Sunday, 11 September 2011

Testing out the WatiN unit testing

WatiN, or "Web application testing in .Net", is based on a similar package for Ruby on Rails called WatiR. This is a browser automation package that gives the ability to run say a MsTest where you open up an url in Internet Explorer 6,7,8 or 9 or Firefox 2 or 3, then locate a gui element in a web page by its id and write in some text, if it is textbox and click a button. This is making it possible easily write GUI tests for web applications running in an IE or FireFox environment, covering most users. WatiN also gives logging options and makes it possible to create screenshots and so on.

Lets start with a equivalent "Hello world" unit test using WatiN.

First off, create a new Mvc 3 Web Application, select Internet Application as the template, choose to add a unit test. Check that you got Nuget insstalled.

Then write in the Nuget console:


Install-Package WatiN


This will download the necessary DLL files to the unit test project and add to its references. These DLL files are:



  • Interop.SHDocVw - Mark in the references this DLL and choose Embed Interop Types to false.


  • WatiN.Core


  • WatinUnitTest



Now add a unit test or basic unit test and then write the following test method
inside your test class:



[TestMethod]
public void TestLogInToMrs()
{
string targetServer = "http://mrx.hex.no";
using (var browser = new IE(targetServer))
{

LogintoCerebralParese(targetServer, browser);
}
}

private static void LogintoCerebralParese(string targetServer, IE browser)
{
browser.ShowWindow(WatiN.Core.Native.Windows.NativeMethods.WindowShowStyle.ShowMaximized);
browser.Link(l => l.Url == targetServer + "/CerebralPareseRegister").Click();
browser.TextField(t => t.Name == "ctl00$ContentPlaceHolderMain$RoleComboBox").SetAttributeValue("readonly", "");
browser.TextField(t => t.Name == "ctl00$ContentPlaceHolderMain$RoleComboBox").TypeText("Registeransvarlig");
browser.Button("ContentPlaceHolderMain_LoginButton").Click();
}



In this example, an instance of an IE object is instantiated inside the using block. The url specified in the constructor argument is requested. Then the unit test
maximizes the window, then it will search on the login page for a Link object (basically searching for the A tags) by url matching CerebralPareseRegister.
It will then look for a TextField, again using a lambda overload (Linq is supported in WatIN, which is written in C#), overriding its readonly html property using the SetAttributeValue method and setting readonly to empty string, unlocking the readonly textbox. Then it writes in "Registeransvarlig" (a role in my test scenario) in the textfield, using the TypeText method with the argument passed into the text box. The last line looks for a button, i.e. an input tag element with id equal to the passed in argument and invokes the click method which will click the button.

The test then will check that it is possible to login to this registry. Without giving out to much details to our global audience, we got web registries which there will be about 50 registries later and this single test will test logging into a single registry (CerebralPareseRegistry). We would then probably test all 50 registries and verify that we can log in to the different registries. The Internet Explorer browser is not thread safe and therefore there is a risk that unit tests running in parallel will crash the IE browser. The good thing then, is that when using the IE browser in these parallel tests, they will run in STA (Single thread apartment) and therefore it will avoid the possible crash. An optimization is in the TestInitialize method use the same IE object and then dispose it in the TestComplete method. Instead, use a single IE object per test to keep thread safety. This will increase the test time. The good thing is that these automated web gui tests can be run in automatic mode and for example runned every night in the nightly build. The WatiN framework makes it therefore possible to do full integration unit tests using browser automation so that you can verify that the web application is working for the end user for its core functionality, such as log in to a web application, perform a search and so on.

The WatiN tests should be testing the core end-user functionality. The different parts of your web application, for example a MVC 3 application, should also have unit tests of their own.

As I have suggested in previous posts, the MvcContrib TestHelper should be used when testing Controllers and their actions in MVC 3. Unit tests in javascript can use the helper class of Stephen Walther. The views can also use the Razor Single File Generator to tests their views. Finally testing the DAL layer Entity Framework supports testing POCO objects using the Seed function if you use Entity Framework Objects.

WatiN supports a multitude of functionality and this blogpost just wanted to mention it.

Check out the http://watin.org website to see the documentation of WatiN and download the package, if you do not want to use Nuget. WatiN is open source and therefore fully customizable.

2 comments:

  1. WatiN looks and works just awesome! if you have tips using WatiN such as grabbing screenshots, please let me know. Any good experiences WatiN and unit testing MVC 3 applications with this?

    ReplyDelete
  2. If you are interested in generating money from your websites or blogs with popunder ads - you can embed one of the biggest networks - Ero-Advertising.

    ReplyDelete