Whether you end up
WatiN or Selenium for automating the browser actually doesn't matter that
much. Whichever mechanism you use should
be hidden behind a Page Object Model.
This actually took me a while to discover because it wasn't really in
your face on the WatiN and Selenium forums.
In fact even once I knew about the pattern I didn't feel the need for it
at first. It was similar to having a
domain controller for a couple of computers.
However, as the sites I was writing and testing got more complicated, I
needed a way of organizing the methods to manipulate the pages into a logical
grouping. It makes sense to make an
object model that encapsulates the ID, classes, tags, etc. inside a page so
that they can be reused easily. Let's
look at a simple example in WatiN, prior to putting in the Page Object Model.
[Given(@"I am on an item
details page")]
public void
GivenIAmOnAnItemDetailsPage()
{
browser = new IE("http://localhost:12345/items/details/1?test=true");
}
[When(@"I update the
item information")]
public void
WhenIUpdateTheItemInformation()
{
browser.TextField(Find.ByName("Name")).TypeTextQuickly("New item name");
browser.TextField(Find.ByName("Description")).TypeTextQuickly("This is the new item description");
var fileUpload = browser.FileUpload(Find.ByName("pictureFile"));
string codebase = new
Uri(GetType().Assembly.CodeBase).AbsolutePath;
string baseDir = Path.GetDirectoryName(codebase);
string path = Path.Combine(baseDir,
@"..\..\DM.png");
fileUpload.Set(Path.GetFullPath(path));
The ?test=true in
the first method is interesting, but the subject of another blog post. Instead Notice the
Find.ByName("Name") in the second method. Now what if there is another method where I
need to check the name to see what is there.
And yet another where I need to both check it *and* update it. So I would have three places and four lines
where that Find.ByName("Name") would be used.
What happens when I
change the element to have a different name?
Every test where I have used Find.ByName("Name") breaks. I have to go through and find them all and update
them.
Let's look at the
same two methods, but this time with a PageObject model.
[Given(@"I am on an item
details page")]
public void
GivenIAmOnAnItemDetailsPage()
{
browser = new IE(Pages.ItemDetails.Url);
}
[When(@"I update the
item information")]
public void
WhenIUpdateTheItemInformation()
{
Pages.ItemDetails.SetName("New item name");
Pages.ItemDetails.SetDetails("This is the new item description");
Pages.ItemDetails.SetPictureFile("DM.png");
A couple of
interesting things happened. The first
is that the test is a lot more readable.
The second is that I now have a central place to change when something
from the page changes. I fix one line,
and now all of the tests are running again.
So to recap, Page
Object Models are great when either the pages are volatile or the same pages
are being used for lots of different tests.
No comments:
Post a Comment