2009-03-24 12 views
8

Khi cố gắng chạy thử nghiệm WatiN 2.0 (CTP3) rất đơn giản trong Visual Studio 2008, tôi thấy rằng đầu tiên luôn thực hiện tốt. Phương pháp thử nghiệm thứ hai dường như phá vỡ một cái gì đó trong đối tượng IE sản xuất các ngoại lệ sau đây:WatiN trong Visual Studio 2008 - phương pháp thử thứ hai không thành công

Phương pháp thử testProject.WatinTest.testTwo ném ngoại lệ: System.Runtime.InteropServices.InvalidComObjectException: COM đối tượng đó đã được được tách riêng từ RCW cơ bản không thể là được sử dụng ..

Mã mẫu bên dưới. Do cách thức khởi tạo là workin trong VS2008 biến trình duyệt phải được định nghĩa là static mà tôi tin rằng có thể là chìa khóa cho vấn đề. Thật không may, trừ khi trình duyệt được mở trong phương thức chung, nó có nghĩa là một cửa sổ riêng biệt cho mọi thử nghiệm không phải là lý tưởng

Tôi rất biết ơn mọi ý tưởng về cách khắc phục điều đó. Tìm kiếm của Google và tìm kiếm SO không tạo ra bất kỳ kết quả hữu ích nào vì vậy tôi hy vọng rằng câu trả lời hay cho câu hỏi này sẽ giúp cộng đồng. Rất cám ơn,


private static IE ie 

    [ClassInitialize] 
    public static void testInit(TestContext testContext) 
    { 
     ie = new IE("http://news.bbc.co.uk"); 
    } 

    [TestMethod] 
    public void testOne() 
    { 
     Assert.IsTrue(ie.ContainsText("Low graphics")); 
    } 

    [TestMethod] 
    public void testTwo() 
    { 
     Assert.IsTrue(ie.ContainsText("Low graphics")); 
    } 

Trả lời

10

Tôi đã nghe vấn đề này trước đây và có nghĩa là để điều tra điều này trong một thời gian. Bây giờ WatiN 2.0 beta 1 đã có sẵn, tôi đã ngồi xuống và tạo ra một lớp trợ giúp để giải quyết vấn đề này với nhân viên thử nghiệm của Visual Studios. Theo sau lớp trợ giúp và lớp thử nghiệm được cải tiến. Tôi cũng blogged về giải pháp này để cho nó tiếp xúc nhiều hơn.

public class IEStaticInstanceHelper 
{ 
    private IE _ie; 
    private int _ieThread; 
    private string _ieHwnd; 

    public IE IE 
    { 
     get 
     { 
      var currentThreadId = GetCurrentThreadId(); 
      if (currentThreadId != _ieThread) 
      { 
       _ie = IE.AttachToIE(Find.By("hwnd", _ieHwnd)); 
       _ieThread = currentThreadId; 
      } 
      return _ie; 
     } 
     set 
     { 
      _ie = value; 
      _ieHwnd = _ie.hWnd.ToString(); 
      _ieThread = GetCurrentThreadId(); 
     } 
    } 

    private int GetCurrentThreadId() 
    { 
     return Thread.CurrentThread.GetHashCode(); 
    } 
} 

Và lớp thử nghiệm sử dụng helper này:

[TestClass] 
public class UnitTest 
{ 
    private static IEStaticInstanceHelper ieStaticInstanceHelper; 

    [ClassInitialize] 
    public static void testInit(TestContext testContext) 
    { 
     ieStaticInstanceHelper = new IEStaticInstanceHelper(); 
     ieStaticInstanceHelper.IE = new IE("http://news.bbc.co.uk"); 
    } 

    public IE IE 
    { 
     get { return ieStaticInstanceHelper.IE; } 
     set { ieStaticInstanceHelper.IE = value; } 
    } 

    [ClassCleanup] 
    public static void MyClassCleanup() 
    { 
     ieStaticInstanceHelper.IE.Close(); 
     ieStaticInstanceHelper = null; 
    } 

    [TestMethod] 
    public void testOne() 
    { 
     Assert.IsTrue(IE.ContainsText("Low graphics")); 
    } 

    [TestMethod] 
    public void testTwo() 
    { 
     Assert.IsTrue(IE.ContainsText("Low graphics")); 
    } 
} 

HTH, Jeroen

+0

Brilliant, Jeroen. Đó là một câu trả lời tuyệt vời và tôi thực sự hy vọng nó sẽ giúp rất nhiều người có cùng một vấn đề. Ngoài ra tôi hy vọng rằng bây giờ giữa blog của bạn và SO Google sẽ có thể đưa ra gợi ý có ý nghĩa khi mọi người sẽ tìm kiếm giải pháp –

+0

Tôi đã phải sử dụng mã của Nailuj (dựa trên mã của bạn) cho phiên bản mới nhất của WatiN. Tuy nhiên, tôi đã nhận được ngoại lệ trên ClassCleanup và không thể có được trình duyệt để xử lý mà không giết chết quá trình với Process.Kill() ... đó là một giải pháp xấu xí: ( –

0

Tôi nghĩ rằng nó có liên quan đến cách bạn đang giữ một tổ chức vào biến trình duyệt IE. Tôi đã sử dụng nó mà không gặp rắc rối như trong mẫu: http://watin.sourceforge.net/. Tôi thấy các bài kiểm tra watin như nhiều bài kiểm tra chức năng/tích hợp hơn các bài kiểm tra đơn vị, vì vậy mỗi bài kiểm tra giống như một câu chuyện với các tương tác khác nhau. Tôi sử dụng mẫu Đối tượng trang để giúp cấu trúc mã - xem http://code.google.com/p/webdriver/wiki/PageObjects.

Ps. Tôi đã xem xét việc tái sử dụng thể hiện nhưng chưa thực sự thử nó. Mở/đóng các phiên bản của trình duyệt sẽ thêm thời gian vào các bài kiểm tra.

+0

Cảm ơn bạn. Các ví dụ trên trang WatiN đang làm việc tốt cho tôi nhưng đối với các kịch bản thực tế, tôi muốn một cái gì đó hơn. Chúng tôi có thể sử dụng mẫu Đối tượng trang nhưng đặt nó ở đây sẽ làm cho mã mẫu không thể đọc được. Cảm ơn một lần nữa –

+0

Tất nhiên WatiN không thực sự là về thử nghiệm đơn vị nhưng tích hợp/chức năng, nhưng chỉ vì bạn chạy thử nghiệm đơn vị Á hậu, nó không có nghĩa là nó phải được kiểm tra đơn vị. Nếu bạn viết các bài kiểm tra chức năng/tích hợp dựa trên cơ sở hạ tầng kiểm tra đơn vị, bạn sẽ nhận được phần mềm Á hậu, báo cáo, VS tích hợp như kiểm tra đơn vị, đặc biệt là nếu bạn muốn chạy nó trên máy chủ CI, nơi kiểm tra của bạn được thực hiện mỗi lần mới xây dựng ứng dụng được triển khai. – yoosiba

8

tôi đang tìm kiếm điều này giống nhau, và câu trả lời của jvmenen giúp tôi ra ngoài. Tuy nhiên, đã có một số cập nhật cho WatiN kể từ khi câu trả lời được đưa ra, vì vậy tôi đã phải viết lại lớp trợ giúp một chút để phù hợp với phiên bản WatiN mới nhất (hiện tại là 2.0.20).

WatiN không còn chứa chức năng IE.AttachToIE, vì vậy tôi phải sửa đổi một chút. Ngoài ra, tôi cũng đã tạo lớp helper bằng cách sử dụng Generics, để bất kỳ loại trình duyệt nào cũng có thể được sử dụng và không chỉ IE (tôi tin rằng IE và Firefox được hỗ trợ bởi WatiN bây giờ, và Chrome sẽ đến).

Vì vậy, trong trường hợp bất cứ ai đang tìm kiếm này là tốt, đây là phiên bản của tôi về IEStaticInstanceHelper (bây giờ gọi là StaticBrowserInstanceHelper):

class StaticBrowserInstanceHelper<T> where T : Browser 
{ 
    private Browser _browser; 
    private int _browserThread; 
    private string _browserHwnd; 

    public Browser Browser 
    { 
     get 
     { 
      int currentThreadId = GetCurrentThreadId(); 
      if (currentThreadId != _browserThread) 
      { 
       _browser = Browser.AttachTo<T>(Find.By("hwnd", _browserHwnd)); 
       _browserThread = currentThreadId; 
      } 
      return _browser; 
     } 
     set 
     { 
      _browser = value; 
      _browserHwnd = _browser.hWnd.ToString(); 
      _browserThread = GetCurrentThreadId(); 
     } 
    } 

    private int GetCurrentThreadId() 
    { 
     return Thread.CurrentThread.GetHashCode(); 
    } 
} 

Hope this helps ai đó :)