Sometimes, test scripts do not use any assertions because all assertions are done in the page classes:
@Test
public void canNavigateToOtherPagesTest() {
HomePage homePage = new HomePage(driver);
homePage.open();
homePage.verifyPageIsDisplayed();
ResultsPage resultsPage = homePage.searchBy(KEYWORD);
resultsPage.verifyPageIsDisplayed();
resultsPage.verifyResultsFoundIncluded1To10();
resultsPage.goToPage(2);
resultsPage.goToPage(3);
resultsPage.goToPage(4);
}
There are no assertions in the test script because each page class uses them.
HomePage class has an assertion in the verifyPageIsDisplayed() method to verify if home page is displayed:
public class HomePage {
private WebDriver driver;
private static final String HOME_PAGE_URL = "https://www.vpl.ca/";
private static final By SEARCH_BOX_ID = By.id("edit-search");
private static final By SEARCH_BUTTON_ID = By.id("edit-submit");
public HomePage(WebDriver driver) {
this.driver = driver;
}
public void open() {
driver.get(HOME_PAGE_URL);
}
public void verifyPageIsDisplayed() {
Assert.assertTrue(getUrl().equalsIgnoreCase(HOME_PAGE_URL));
}
public String getUrl() {
return driver.getCurrentUrl();
}
public ResultsPage searchBy(String keyword) {
typeKeyword(keyword);
clickSearchButton();
return new ResultsPage(driver);
}
public void typeKeyword(String keyword) {
WebElement searchBox = driver.findElement(SEARCH_BOX_ID);
searchBox.sendKeys(keyword);
}
public void clickSearchButton() {
WebElement searchButton = driver.findElement(SEARCH_BUTTON_ID);
searchButton.click();
}
}
ResultsPage class uses a few assertions as well:
public class ResultsPage {
private WebDriver driver;
private static final String RESULTS_PAGE_URL =
"https://vpl.bibliocommons.com";
private static final By RESULTS_FOUND_XPATH =
By.xpath("(//span[@data-key = 'pagination-text'])[1]");
private static final By PAGE_2_XPATH =
By.xpath("//li[contains(@class, 'page-number')]/a[@data-page = '2']");
private static final By PAGE_3_XPATH =
By.xpath("//li[contains(@class, 'page-number')]/a[@data-page = '3']");
private static final By PAGE_4_XPATH =
By.xpath("//li[contains(@class, 'page-number')]/a[@data-page = '4']");
public ResultsPage(WebDriver driver) {
this.driver = driver;
}
public String getUrl() {
return driver.getCurrentUrl();
}
public void verifyPageIsDisplayed() {
Assert.assertTrue(getUrl().startsWith(RESULTS_PAGE_URL));
}
public void verifyResultsFoundIncluded1To10() {
WebElement label = driver.findElement(RESULTS_FOUND_XPATH);
String labelText = label.getText();
Assert.assertTrue(labelText.contains("1 to 10"));
}
public void goToPage2() {
WebElement page = driver.findElement(PAGE_2_XPATH);
page.click();
Assert.assertTrue(getUrl().contains("page=2"));
}
public void goToPage3() {
WebElement page = driver.findElement(PAGE_3_XPATH);
page.click();
Assert.assertTrue(getUrl().contains("page=3"));
}
public void goToPage4() {
WebElement page = driver.findElement(PAGE_4_XPATH);
page.click();
Assert.assertTrue(getUrl().contains("page=4"));
}
}
There are assertions in many methods in this class:
the assertion from verifyPageIsDisplayed() verifies that results page is displayed
the assertion from verifyResultsFoundIncludes1To10() verifies that the resultsFound label included the “1 to 10” text
each of the goToPage2(), goToPage3() and goToPage4() methods verify that the next page is displayed
Using assertions in the page methods is incorrect for multiple reasons.
Let’s review them one by one.
A page object should wrap an HTML page with an application-specific API, allowing test scripts to manipulate page elements without knowing much about the HTML code. A page object should work like an API and provide the test scripts ways of interacting with the page and getting information from the page. A typical API has get and post methods (and no assertions) so a page object should do the same
using assertions in a page class increases the page class responsibilities as the class will be responsible not only for the interaction with the page but also for making verification; a page class, like any other class, should have one purpose only
if assertions are used in the page classes instead of the test script, it will be hard to understand what the test script does just by looking at it
not using assertions in the test script leads to an unusual test script template; in general, a test script written as a unit test starts with navigating to the site page that should be tested; once that site page is displayed, the test script will make the verifications required by the test case; if this last part is missing, the test script is not following common unit test structure
So, do not use assertions in the page classes.
A page class should provide access to the state of the underlying page.
It should be up to test scripts to execute the assertions.
How do we change the page classes?
For HomePage, we remove the verifyPageIsDisplayed() method and replace it with the isDisplayed() method. isDisplayed() returns true if home page is displayed and false otherwise:
public boolean isDisplayed() {
return getUrl().equalsIgnoreCase(HOME_PAGE_URL);
}
For ResultsPage, first, we remove verifyPageIsDisplayed() and replace it with the isDisplayed() method. isDisplayed() returns true if results page is displayed and false if not:
public boolean isDisplayed() {
return getUrl().startsWith(RESULTS_PAGE_URL);
}
Then, we remove the verifyResultsFoundIncluded1To10() method and replace it with getResultsFound(). getResultsFound() returns the value of the resultsFound label. It will be up to the test script to assert that this value is correct:
public String getResultsFound() {
WebElement label = driver.findElement(RESULTS_FOUND_XPATH);
return label.getText();
}
We remove the assertions from the goToPage methods as follows:
public void goToPage2() {
WebElement page = driver.findElement(PAGE_2_XPATH);
page.click();
}
public void goToPage3() {
WebElement page = driver.findElement(PAGE_3_XPATH);
page.click();
}
public void goToPage4() {
WebElement page = driver.findElement(PAGE_4_XPATH);
page.click();
}
It will be the test script’s responsibility to verify that the correct page is displayed.
The test script changes as follows:
@Test
public void canNavigateToOtherPagesTest2() {
HomePage homePage = new HomePage(driver);
homePage.open();
Verify.verify(homePage.isDisplayed(), "home page is not displayed!");
ResultsPage resultsPage = homePage.searchBy(KEYWORD);
Verify.verify(resultsPage.isDisplayed(), "results page is not displayed!");
Verify.verify(resultsPage.getResultsFound().contains("1 to 10"),
"results found label does not include 1 to 10!");
resultsPage.goToPage2();
Assert.assertTrue(resultsPage.getUrl().contains("page=2"));
resultsPage.goToPage3();
Assert.assertTrue(resultsPage.getUrl().contains("page=3"));
resultsPage.goToPage4();
Assert.assertTrue(resultsPage.getUrl().contains("page=4"));
}
Notice that now we have both verifications and assertions in the test script.
Verifications are used to verify that the site navigation goes as expected.
Assertions are needed for checking that the pages are displayed correctly.