Adventures of a wannabe geek!

Ranting within

What Happens to WatiN Tests When Containers Change?

My venturing into Automated Acceptance Testing has improved again thanks to a fantastic article on Simplifying WatiN tests by not over specifying - thanks to Richard Lawrence for this blog post.

if we have code as follows:

[Test]
public void ShouldAuthenticateUsersSuccessfully()
{
	using (IE ie = new IE())
	{
		ie.GoTo("http://testsite.com/");
		ie.TextField("ctl1001_Content_Content_txtUsername").TypeText("Owain");
		ie.TextField("ctl1001_Content_Content_txtPassword").TypeText("Hughes");
		ie.Button("ctl1001_Content_Content_btnLogin").Click();
		Assert.IsTrue(ie.ContainsText("Welcome, Owain!"));
	}
}

if the container divs change from ‘content’ to ‘login’ then this test will break as its very brittle as its looking for ‘content’. It will not be able to dine the textfields or the button. We would then have to change our test to code as follows:

[Test]
public void ShouldAuthenticateUsersSuccessfully()
{
	using (IE ie = new IE())
	{
		ie.GoTo("http://testsite.com/");
		ie.TextField("ctl1001_Content_Login_txtUsername").TypeText("Owain");
		ie.TextField("ctl1001_Content_Login_txtPassword").TypeText("Hughes");
		ie.Button("ctl1001_Content_Login_btnLogin").Click();
		Assert.IsTrue(ie.ContainsText("Welcome, Owain!"));
	}
}

We can stop this from happening by the use of Regular Expressions in our WatiN tests. This Regex will find the correct id of the control and then it will not depend on the parent divs. Of course the tests will still fail if we change the control names themselves - but we know that by changing the control names that we have to change the test. The new code will be as follows:

[Test]
public void ShouldAuthenticateUsersSuccessfully()
{
	using (IE ie = new IE())
	{
		ie.GoTo("http://testsite.com/");
		ie.TextField(new Regex("txtUsername$")).TypeText("Owain");
		ie.TextField(new Regex("txtPassword$")).TypeText("Hughes");
		ie.Button(new Regex("btnLogin$")).Click();
		Assert.IsTrue(ie.ContainsText("Welcome, Owain!"));
	}
}

This will tell the Watin dll to look for the control that ends in the text expressed within the regex. This is very useful for me as i have previously hard coded the control ids into a constants file as follows:

[Test]
public void ShouldAuthenticateUsersSuccessfully()
{
	using (IE ie = new IE())
	{
		ie.GoTo("http://testsite.com/");
		ie.TextField(Find.ById(Constants.Login_Firstname)).TypeText("Owain");
		ie.TextField(Find.ById(Constants.Login_Surname)).TypeText("Hughes");
		ie.Button(Find.ById(Constants.LoginButton)).Click();
		Assert.IsTrue(ie.ContainsText("Welcome, Owain!"));
	}
}

My testing foraging now continues! :)