问题
When trying to run a very simple WatiN 2.0 (CTP3) test in Visual Studio 2008 I found that the first one always executes fine. The second test method seem to break something in the IE object producing the following exception:
Test method testProject.WatinTest.testTwo threw exception: System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used..
A sample code is below. Due to the way the initialization method is workin in VS2008 the browser variable has to be defined as static
which I believe could be a key to the problem. Unfortunately unless the browser is opened in the common method it means a separate window for every test which is not ideal
I would be very grateful for any ideas on how to fix that. Google search and SO search did not produce any useful results so I hope that a good answer to this question will help the community. Many thanks,
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"));
}
回答1:
I have heard this problem before and meant to investigate this for a while. Now that WatiN 2.0 beta 1 is available I sat down and created a helper class to solve this problem with Visual Studios test runner. Following the helper class and the revamped test class. I also blogged about this solution to give it even more exposure.
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();
}
}
And the test class using this helper:
[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
回答2:
I was looking for this same thing, and the answer of jvmenen helped me out. However, there has been some updates to WatiN since that answer was given, so I had to rewrite the helper class a bit to be consistent with the latest WatiN version (currently 2.0.20).
WatiN no longer contains the IE.AttachToIE
function, so I had to modify that a bit. In addition I also made the helper class using generics, so that any browser type can be used and not only IE (I believe IE and Firefox is supported by WatiN now, and Chrome is to come).
So in case anybody else is looking for this as well, here is my version of the IEStaticInstanceHelper
(now called 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 somebody :)
回答3:
I think it is related to the way you are keeping a hold to the IE variable. I have been using it with no trouble as in the sample: http://watin.sourceforge.net/. I see watin tests as more functional/integration tests than unit tests, so each test is more like a story with different interactions. I use the Page Object pattern to help structure the code - see http://code.google.com/p/webdriver/wiki/PageObjects.
Ps. I have considered reusing the instance but haven't really tried it. Opening/closing instances of the browser do add time to the tests.
来源:https://stackoverflow.com/questions/679347/watin-in-visual-studio-2008-second-test-method-fails