Where he blogs about his eclipse musings
Reusing Functional Tests – Part 1
While writing some tests for SWTBot, there was quite some code duplication that could be removed by using some simple test patterns. This is part of a series of articles about how test code could be written better. This example uses SWTBot as a driver to drive an Eclipse application used by ACME Corporation.
Here is a snippet of a Test Case that creates an account in ACME Corporation’s customer management system.
public void testCreatesAccount() throws Exception {
bot.menu("Accounts").menu("New").click();
// nice wizard
bot.shell("Create a new account").activate();
bot.textWithLabel("Name:").setText("Will Coyote");
bot.textWithLabel("Email:").setText("will@coyote");
bot.button("Next>").click();
// yet another wizard
bot.shell("Address Details").activate();
bot.textWithLabel("Mailing Address:").setText("Will Coyote, middle of, nowhere");
bot.button("Finish").click();
assertThatAccountIsCreated("Will Cooyte", "will@coyote.com");
}
That’s a great start to begin writing tests. But there’s the problem: What happens if the test fails somewhere and the “Create a new account” or the “Address Details” window remains open ? This means that the rest of the tests fail or do not run at all. Not a problem, tearDown() to the rescue:
protected void tearDown() throws Exception {
closeWindow("Create a new account");
closeWindow("Address Details");
}
private void closeWindow(String windowTitle) throws Exception {
try {
bot.shell(windowTitle).close();
} catch (WidgetNotFoundException e) {
// do nothing if the window is not found
}
}
Now we write a test that tests if you’re able to create two users with the same name.
public void testShouldNotCreateTwoAccountsWithTheSameName() throws Exception {
bot.menu("Accounts").menu("New").click();
// nice wizard
bot.shell("Create a new account").activate();
bot.textWithLabel("Name:").setText("Will Coyote");
bot.textWithLabel("Email:").setText("will@coyote");
bot.button("Next>").click();
// yet another wizard
bot.shell("Address Details").activate();
bot.textWithLabel("Mailing Address:").setText("Will Coyote, middle of, nowhere");
bot.button("Finish").click();
assertThatAccountIsCreated("Will Cooyte", "will@coyote.com");
bot.menu("Accounts").menu("New").click();
// nice wizard
bot.shell("Create a new account").activate();
bot.textWithLabel("Name:").setText("Will Coyote");
bot.textWithLabel("Email:").setText("will@coyote");
bot.button("Next>").click();
// yet another wizard
bot.shell("Address Details").activate();
bot.textWithLabel("Mailing Address:").setText("Will Coyote, middle of, nowhere");
bot.button("Finish").click();
assertThatAccountIsNotCreated("Will Cooyte", "will@coyote.com");
}
Duplication, not a big deal, some bit of refactoring and you get to this. This also reduces the number of places where you’ll need to fix the test, if the label on one of the screens change.
public void testCreatesAccount() throws Exception {
createAccount("Will Coyote", "will@coyote", "Will Coyote, middle of, nowhere");
assertThatAccountIsCreated("Will Cooyte", "will@coyote.com");
}
public void testShouldNotCreateTwoAccountsWithTheSameName() throws Exception {
createAccount("Will Coyote", "will@coyote", "Will Coyote, middle of, nowhere");
assertThatAccountIsCreated("Will Cooyte", "will@coyote.com");
createAccount("Will Coyote", "will@coyote", "Will Coyote, middle of, nowhere");
assertThatAccountIsNotCreated("Will Cooyte", "will@coyote.com");
}
private void createAccount(String name, String email, String snailMail) throws WidgetNotFoundException, TimeoutException {
bot.menu("Accounts").menu("New").click();
// nice wizard
bot.shell("Create a new account").activate();
bot.textWithLabel("Name:").setText(name);
bot.textWithLabel("Email:").setText(email);
bot.button("Next>").click();
// yet another wizard
bot.shell("Address Details").activate();
bot.textWithLabel("Mailing Address:").setText(snailMail);
bot.button("Finish").click();
}
In the next article, you’ll get to see how you can reuse code better by using Screen Objects
September 4, 2008 - 5:34 am
Hi! I want to know about your idea of using screen objects. When are you going to write part 2?
September 6, 2008 - 8:50 am
@Leo, hold on for a couple of days. I’m already writing this one and it’s still a draft.
September 12, 2008 - 9:06 pm
cool, I’ll be waiting.
October 15, 2008 - 2:58 pm
Is Screen Object the same concept as a Page Object?
http://code.google.com/p/webdriver/wiki/PageObjects
October 15, 2008 - 5:47 pm
@Jason,
Yes, that is the same concept — Providing classes that expose operations/services that users can perform on a page rather than the raw UI controls.
August 17, 2009 - 2:45 pm
Great Article.
When comes Part 2 about the using of screen objects?