Focus on WHAT instead of HOW when writing a Selenium test
A typical login page is made of
username fields (username label, username textbox)
password fields (password label, password textbox)
login button
reset password link
It provides the user a few services:
logging in
resetting password
The most important service offered by this page is logging in.
Logging in is usually implemented by interacting with the page elements as follows:
type username
type password
click login button
So, we have a page (log in page) that offers services (logging in, reset password) which are implemented by interacting the page elements.
How does a user login test case look like?
go to login page
log in with username and password.
or
click login link to go to login page
type username in username textbox.
type password in password textbox
click login button
The 1st test case is high level and relies on the services offered by the page to the user.
The test case is focused on WHAT the user does. In our case, logging in.
How the logging in is done is not relevant here.
The 2nd test case is low level and relies on interacting with the elements of the page.
The test case is focused on HOW the logging in is implemented.
Which of these is better?
The 1st is shorter and will not be impacted if there are changes in the logging in implementation.
The 2nd is longer and prone to changes every time the page changes.
The first one is better.
When it comes to Selenium tests,
should we have the logging in test look like this
@Test
public void userCanLogInTest() {
HomePage homePage = new HomePage(driver);
homePage.open();
Assert.assertTrue(homePage.isDisplayed());
LoginPage logingPage = homePage.navigateToLoginPage();
Assert.assertTrue(loginPage.isDisplayed());
loginPage.typeUserName(userName);
loginPage.typePassword(password);
loginPage.clickLoginButton();
.........
}
or
@Test
public void userCanLogInTest() {
HomePage homePage = new HomePage(driver);
homePage.open();
Assert.assertTrue(homePage.isDisplayed());
LoginPage logingPage = homePage.goToLoginPage();
Assert.assertTrue(loginPage.isDisplayed());
loginPage.loginWith(userName, password);
.........
}
The 2nd one is better.
The Selenium team recommends that
PageObjects can be thought of as facing in two directions simultaneously.
Facing toward the developer of a test, they represent the services offered by a particular page.
Facing away from the developer, they should be the only thing that has a deep knowledge of the structure of the HTML of a page.
It’s simplest to think of the methods on a Page Object as offering the “services” that a page offers rather than exposing the details and mechanics of the page.
PS:
If you are interested in a full Selenium project built from A to Z, please go here.
The 1st part (writing the automation code) is done.
The 2nd part (refactoring the automation code) will start shortly.