dinsdag 31 maart 2009

Reusing an IE instance in VS test

I was going over the WatiN questions on stackoverflow. One of the questions involved reusing an IE instance over multiple tests. Since Visual Studio’s test runner creates a new Thread for each TestMethod in a TestClass you get a nasty InvalidComObjectException with the additional information "COM object that has been separated from its underlying RCW can not be used.".

Following the problem example as posted on stackoverflow. When running these tests, the first test “testOne” passes but the second test “testTwo” will throw the InvalidComObjectException.

image

Does this mean we can’t reuse an IE instance across multiple tests? Nope.

We can still instantiate IE in the method decorated with the ClassInitialize attribute but in each test case we need to attach to the running instance using IE.AttachToIE(constraint). To find the Internet Explorer instance we created, we can use the window handle to find the instance. Somewhat like a “good-old-pointer”. Add a little bit logic to cache the found IE instance and return this as long as the CurrentThread hasn’t changed and the helper class could look something like this:

image

To make use of this helper class, we create an instance of IEStaticInstanceHelper and assign it to a static field (as we did before with the IE instance). Next we assign an IE instance to the IE property. Now we can use this Internet Explorer instance in our test cases without bothering about different Threads.

For clarity sake I wrapped the call to the  ieStaticInstanceHelper.IE property in an instance property of the test class, called IE. And to make sure the IE instance gets closed after all tests have run I added a method decorated with the ClassCleanup attribute.

 

image

Off course you could create a base class which is used by all your test classes, but that's up to you.

You can download the code here.

Happy testing with WatiN and Visual Studio test runner!

Technorati Tags:

2 reacties:

commentor zei

The ClassCleanup static method doesn't get called if defined on a base class.

Paul zei

I have error on ClassCleanup:

Class Cleanup method UnitTest.MyClassCleanup failed. Error Message: WatiN.Core.Exceptions.IENotFoundException: Could not find an IE window matching constraint: Attribute 'hwnd' equals '1316968'. Search expired after '1' seconds.. Stack Trace: at WatiN.Core.IE.FindIE(Constraint findBy, Int32 timeout, Boolean waitForComplete)
at WatiN.Core.IE.AttachToIE(Constraint findBy, Int32 timeout)
at TestProject.IEStaticInstanceHelper.get_IE() in C:\Documents and Settings\pane\Desktop\Using watin with visual studio test\TestProject\IEStaticInstanceHelper.cs:line 19
at TestProject.UnitTest.MyClassCleanup() in C:\Documents and Settings\pane\Desktop\Using watin with visual studio test\TestProject\PassingTests.cs:line 27