Friday, 23 November 2007

WatiN Tips and Tricks

I've realised that in my last WatiN post I didn't actually explain what it is for those who haven't used it before.

So just briefly, WatiN was inspired by WatiR and is used to perform front end web application testing. WatiN is coded in .net languages and it provides a mechanism to automatically load Internet Explorer, find controls and perform actions and then assert conditions. You can find out more info here: http://watin.sourceforge.net/

Ok now thats done, here is my tips for the week:

Problem:

Each time I load a test I want to run it in a new process so my session information is cleared
Solution:

With version 1.2 of WatiN there is a new argument to allow you to start IE in a new process:

IE ie = new IE(someUrlToGoTo, true))

Problem:

I want to obtain a collection of fields. For example, I have a repeater which contains a text field and I don't know how many repeater items may be returned but I want to grab all text fields.
Solution:

Use a filter to get a collection

TextFieldCollection valueTextFields = browser.TextFields.Filter(Find.ById(new Regex("ValueTextBox")));

Problem:

I want to find a field but its type isn't available in WatiN

Solution:

Use the Element object

Element item1 = ie.Element("li", Find.ById("item1"));

Problem:

I don't want the Internet Explorer windows used during testing to be visible to the user

Solution:

Change the IE setting

IE.Settings.MakeNewIeInstanceVisible = false; // default is true

Tuesday, 20 November 2007

Help EPiServer prioritse their development

EPiServer has kindly provided us with a way to voice our opinion on what future features we see are most important.

Fill out the survey http://www.episerver.com/en/Surveys/Help-us-prioritize-functionality/
and select the top 5 out of 20 features.

Here's my pics:
2. Change page type for a page
(allow you to switch a page to a different page type and match up properties)
4. Drag and drop sorting in tree structure
(so you don't have to go through every edit tab to change the sort index!)
7. Shortcut indication in tree
A simple request but beneficial for editors and during training
14. Search behavior report
(list of the most frequently used search words, and words with no results)
I have had this asked from almost every client
18. Check broken links
(list of broken links - both internal and external)
I get this one requested on every RFP we get through the door

Monday, 12 November 2007

WatiN Testing Pattern

In my latest project I am utilising WatiN to perform my website testing. This is not the first time I have used it in a project but it is the largest test project I've had to create and I've come across a couple of challenges.

Early on I realised my code was becoming increasingly difficult to manage and well rather messy due to all the control find declarations that existed within my tests. So I decided to see if anyone had implemented a nice pattern for WatiN tests that they could recommend. And low and behold I came across a couple and I have included them as references as the bottom of this blog. There are slight variations for both and undoubtedly you will vary your own to suit the situation you are working with but the underlying principals are the same.

First of all we create a page class for every page of our website. This page class is going to contain all the controls that we need to access on our page. The page class is going to inherit from the IE object and instantiates itself using the correct url. Let's look at an example





public class BaseModelPage : IE
{
public const string PreConfiguredModelURL = "/BaseModel.aspx";

public BaseModelPage() : base (SharePointSiteFixture.Site.Url + PreConfiguredModelURL){}

public Button AddToQuoteButton
{
get{ return Button(Find.ById(new Regex("AddToRequestButton"))); }
}

public Button EditSpecButton
{
get{ return Button(Find.ById(new Regex("EditSpecButton"))); }
}
}

From here its a matter of removing all the control find code you had in your tests, reference the new page class and now our tests are clean, easy to read and is a true representation of what we're testing.

So here is what it looks like after the cleanup




[SetUp]]
public void SetUp()
{
page = new BaseModelPage();
}

[Test]
public void AddQuoteAndEditSpecButtonsAreHidden()
{
Assert.That(!page.AddToQuoteButton.Exists);
Assert.That(!page.EditSpecButton.Exists);
}

We can also abstract out common scenarios or workflows out to the classes also. For example if there are some textfields we need to fill out multiple times to cover off a couple of test scenarios then we'll pull this code into a method in our page class and simply reference it from our test. Again, our tests are becoming more clean and simple. Lets look at another test that calls one of these methods.







[Test]
public void SubmittingValuesHidesConfigureFormShowsButtons()
{
page.SubmitValues();

Assert.That(!page.ConfigureForm.Exists);
Assert.That(page.AddToQuoteButton.Exists);
Assert.That(page.EditSpecButton.Exists);
}


Another thing we can do is extend our page classes further to handle moving between pages. This is useful when you have a transactional website and you need to test page sequence. In this scenario we add another constructor which accepts an IE instance. Then we can call this constructor from another page class in order to return the new page.





public QuoteRequestPage(IE instance): base(instance.Uri){}


internal QuoteRequestPage GoToQuoteRequestPage()
{
RequestQuoteButton.Click();
return new QuoteRequestPage(this);
}



So that pretty much sums it up. I certainly recommend following a pattern like this as the maintainability of your code is greatly increased and your tests become clean and readable.

Ref1 - James Avery
Ref2 - Richard Griffin