On my current project we have zero unit tests. I inherited the application and the existing unit tests where such a mess it was better to just kill em and start over. I would normally start from the data layer and work up, but since we are working toward a release in a couple weeks I need the best bang for my buck. So I decided to start with some UI functional tests, these will also be a major asset once we start really refactoring the application.
I have used Watir in the past, but since this is a .NET project I think it makes more sense to go with Watin. Before getting started with Watin I did some research to see what the "best practices" were. The watin site has some good samples, but not much in the way of patterns or best practices. The site does link to this blog post from Richard Griffin which outlines a design pattern, but the pattern is a little too procedural for my liking. Perhaps it is all the ruby lately, but more and more I want clean object oriented solutions whenever possible.
So I came up with my own pattern. I wanted to completely hide the IE object and make writing tests as intuitive and easy as possible, while following DRY and KISS. So I decided to start with an object for each page, here is what I started with.
public class HomePage : IE { public const string HomePageURL = "default.aspx"; public HomePage() : base (ConfigurationManager.Host
+ HomePageURL) { }
}
Instead of playing around with passing the IE object around, I decided to just inherit from it. In your test if you want to test the homepage you just have to say
HomPage home = new HomePage();
and use the home object in the exact way you would the IE object. Then I include properties for the various textboxes and such on the page:
public TextField UserIDField {
get{ return TextField(Find.ByName("txtUsername")); } }
public TextField PasswordField {
get { return TextField(Find.ByName("txtPassword")); } }
public Button ContinueButton {
get { return Button(Find.ByName("btnContinue")); } }
and also methods for the main actions on the page:
internal void Login(string username, string password) { UserIDField.TypeText(username); PasswordField.TypeText(password); ContinueButton.Click(); }
Now if I want to write a test to test logging in my test looks like this:
[Test] public void Login() { HomePage home = new HomePage(); home.Login("james", "password"); Assert.IsTrue(home.ContainsText("My Stuff")); //more assertions here home.Close(); }
The only other thing I found I needed was a way to change what page object I am working with, so I added another constructor that lets you "switch" the page you are on:
public HomePage(IE instance) :
base(instance.InternetExplorer) {}
This way I can add methods that return a different page like this one:
internal UserRegistrationPage GoToUserRegistration() { UserRegistrationLink.Click(); return new UserRegistrationPage(this); }
You would only need this for tests that move from page to page, otherwise you could just create a new page object. So far it has been working great, I will post an update if I encounter any issues or make any major changes. If I find the time I am going to try and add a feature to the Watin recorder to generate these page objects, it wouldn’t be too hard and it would make it really easy to write Watin tests.
While twittering about it I talked to Phil Haack and he is using a similar pattern on subText, though there are a couple differences like he keeps the IE object separate. (you can grab the source and check it out if you want to see another option.
Download the sample files:
-James

{ 15 comments }
Really great approach! Integration tests containing the names of the different HTML elements can become tedious and hard to read. Your approach makes the code of the tests very easy to read and comprehend. Thanks for sharing.
Thanks Jan! I am going to work up a screencast once I make some changes to WatinRecorder.
I like the approach too. My only question is how to automatically name it in a transparent way. We could have a fairly simple grid interface to change the more cryptic IDs into readable names for the whole page.
Would XPath (like “home/Textbox/txtFirstName”) be any easier to understand?
Hi everybody, i have used this stuff in my project,its a good one..for testing..but has some drawbacks too like when executing a page, it some times fire timeout error.
Nishant, if you get a timeout error, consider why it is timing out and either fix that or extend the timeout value…
I believe this is called the Facade Pattern.
Paolo
Yep. That’s similar to the pattern I use but I don’t inherit from IE and I don’t really pass them around either. I also don’t require even so much as a default constructor.
One of the custom WatiN extensions I create is a generic method called Page<T>(), a bit like this:
public class Browser : IE
{
public T Page<T>() where T : Page, new()
{
T page = new T();
page.Initialize(this);
return page;
}
}
And…
public class Page
{
private Browser browser;
public Browser Browser
{
get { return browser; }
}
public void Initialize(Browser browser)
{
this.browser = browser;
}
}
So then your HomePage class becomes:
public class HomePage : Page
{
public Link SignInLink { get { return Browser.Link(”signIn”); } }
// etc…
}
And you use it like this in your test:
Browser.Page<HomePage>().SignInLink.Click();
However, in the real framework, I don’t actually pass in the Browser itself. I pass in a service provider interface which provides access to the Browser and several other services used by the tests, site map (pages & controls), and helpers. The base test fixture class implements IQEServiceProvider as does the base Page class (indirectly).
What that means is that I can count on the same services being available to me anywhere and in the same manner. I’ve left out that detail above.
It’s simple stuff but quite useful. I am planning to blog more about it soonish.
I have been using Watin for month or so. I have tried a number of UI testing frameworks but they all have had issues with client side validation, dialog windows, alerts etc. Watin however seems to be working very well. Are there any others that you have been successful with? It would seem that Microsoft should license/purchase Watin for incorporation into their Vs.Net product line. Thoughts?
Watin is the only one I have had success with as well. I am sure Microsoft would never license it, but I wouldn’t be surprised to see them copy it in the next version of Visual Studio.
Things have been working great. Today however I have no clue as to why i am getting the following error when i try to run my unit test
Test method TestHarness.PageTests.GoToPageTest
threw exception: System.TypeLoadException: Could not load type ‘SHDocVw.InternetExplorerClass’
from assembly ‘Interop.ShDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91′..
Seen this before?
thx
If you have references within your test project that have changed you may get the obscure error “threw exception: System.TypeLoadException: Could not load type ‘SHDocVw.InternetExplorerClass’
“
Remove any references and add new again.
When I run the WatiN through the Nunits GUI, I get Timeout exception ‘ Internet Explorer Busy’. This error occurs is very rare. How to resolve this.
I have been using Selenium RC for automation testing and have had success with it. However, it does require you to install JAVA jdk…and it requires you to run Selenium RC in the background. Besides that, it’s handled all of my testing needs, including the following: log/in out (https), iframes, parsing XPath values, waiting for conditions to occur, etc. However, as WatiN seems tuned to IE, Selenium seems to work best with Firefox…which has some advantages for testing purposes given the vast amount of Firefox ad-ons out there.
I’ve been evaluating Watin for about a day. I like the simplicity and so far it seems as easy to code with as Selenium. The only issue I have so far is that obtaining data from DIV elements is very slow. Depening on your needs, this may not be an issue…and maybe there’s a solution for it.
RE: Watin Testing Pattern
This article references some important links found while attempting to leverage WatiN for unit testing an ASP.NET application. …
you will found a good control implementation document in the following site. tanvirdotnet.blogspot.com/…/ui-test-with-wa
Comments on this entry are closed.