Download code sample (zipped 190k)
WatiN is a .Net library that can be used to automate Internet Explorer. It allows developers to create unit tests for web application front-ends. Due to the fact that it's basically just a DLL it easily integrates with nunit and mstest
Why use WatiN?
WatiN allows you to emulate real users interacting with your web site by automating IE, and more importantly allows you to assert conditions about the web site.
A typical example of this might be to test user registration, asserting appropriate error messages are displayed when required fields are not filled out.
In most cases this type of validation is performed using JavaScript; which is why you need to use a framework such as WatiN that executes the JavaScript contained within your web page. This is where nunitasp or Visual Studio web tests fall down as they both simulate a browser and do not run client side code during test execution.
In past projects I've used WatiN to test all of the expected user interactions and integrated the tests into our build process. It's quite helpful at giving you an early indication that you might have broken something.
Hello world test
[TestMethod]
public void Search()
{
// Perform search
IE browser = new IE();
browser.GoTo("http://search.live.com/");
browser.TextField("q").TypeText("Hello world");
browser.Button("go").Click();
// Navigate to next page
browser.Link(Find.ByText("Next")).Click();
// Now assert that we really are on page 2
Assert.IsTrue(browser.Div("search_header").Text.Contains("Page 2 of "));
}
Locating elements
Creating test scripts in most cases involves finding an html element and either causing it to fire an event, set it's value or assert it's expected value.
In order to perform an action against an element you must first obtain a reference to it. This can be done in 3 different ways:
- By the elements id (if it has one)
- Regular expression that matches the elements id
- Attribute class
The attribute class is extremely flexible and makes finding elements that do not have an id a breeze. The Find class provides factory methods (returning instances of Attribute) for the most commonly used ways to find an element:
[TestMethod]
public void FindElements()
{
IE browser = new IE();
browser.GoTo(Path.Combine(Environment.CurrentDirectory, "testpage1.htm"));
// Find using the name: <input type="button" name="btnGo"....
browser.Button(Find.ByName("btnGo")).Flash();
// Find a label element by the id of the control it's linked to
browser.Label(Find.ByFor("firstName")).Flash();
// Find an image by it's source attribute
browser.Image(Find.BySrc("princejazzbo.jpg"));
// Find an element by it's index in the collection return by the first findby
browser.RadioButton(Find.ByName("cardType") && new Index(1)).Flash();
// Alternatively we could locate a radio button by name and value
browser.RadioButton(Find.ByName("cardType") && Find.ByValue("MasterCard")).Flash();
}
In order to determine the best way to find an element it's often necessary to have a peek at the DOM for the page you're testing. Two great tools for this are:
Interacting with JavaScript dialogs
One of the great things about WatiN is how easy it is to automate interaction the pop-up windows and JavaScript dialogs.
[TestMethod]
public void JSDialog()
{
using (IE browser = new IE())
{
browser.GoTo(Path.Combine(Environment.CurrentDirectory, "testpage1.htm"));
// First create an object to handle the js alert
AlertDialogHandler dialogHandler = new AlertDialogHandler();
browser.DialogWatcher.Add(dialogHandler);
// Need to use ClickNoWait to allow the code to continue execution
// and handle the modal dialog that's created as a result of the click
browser.Link("linkJSDialog").ClickNoWait();
// Now interact with the dialog
dialogHandler.OKButton.Click();
// Remove the handler so that it does not intercept any more dialogs
browser.DialogWatcher.Remove(dialogHandler);
}
}
If the only thing you're interested in is making sure that a dialog did or did not appear use the SimpleJavaDialogHandler class. This is particularly useful for testing registration forms that use alert dialogs.
[TestMethod]
public void SimpleJavaDialogHandler()
{
using (IE browser = new IE())
{
browser.GoTo(Path.Combine(Environment.CurrentDirectory, "testpage1.htm"));
// First create an object to handle the js alert
SimpleJavaDialogHandler dialogHandler = new SimpleJavaDialogHandler();
browser.DialogWatcher.Add(dialogHandler);
browser.Link("linkJSDialog").Click();
// Now assert that a dialog was shown.
Assert.IsTrue(dialogHandler.HasHandledDialog);
// Remove the handler so that it does not intercept any more dialogs
browser.DialogWatcher.Remove(dialogHandler);
}
}
Code sample:
If you've never tried using WatiN I encourage you to give it a go: WatiN introduction sample code (zipped 190k)
Useful WatiN links:
http://watin.sourceforge.net/ - WatiN Home page
http://watin.sourceforge.net/htmlelementmapping.html - HTML to WatiN object mapping table
http://watintestrecord.sourceforge.net/ - Test recorder for WatiN