There is quite a bit of code duplication in the following test script.
Can you find it by yourself?
@Test
public void searchTest() {
driver.get(HOME_PAGE_URL);
String homePageUrl = driver.getCurrentUrl();
Verify.verify(homePageUrl.equalsIgnoreCase(HOME_PAGE_URL));
WebElement searchBox = driver.findElement(SEARCH_BOX_ID);
searchBox.sendKeys(KEYWORD);
WebElement searchButton = driver.findElement(SEARCH_BUTTON_ID);
searchButton.click();
String resultsPageUrl = driver.getCurrentUrl();
Verify.verify(resultsPageUrl.startsWith(RESULTS_PAGE_URL),
"results page url does not start with " + RESULTS_PAGE_URL);
Verify.verify(resultsPageUrl.contains("query=" + KEYWORD),
"results page url does not contain query=" + KEYWORD);
Verify.verify(resultsPageUrl.contains("searchType=smart"),
"results page url does not contain searchType=smart");
WebElement resultsFoundLabel = driver.findElement(RESULTS_FOUND_XPATH);
String foundText = resultsFoundLabel.getText();
Verify.verify(foundText.contains("1 to 10"),
"results page does not include 1 to 10");
String countText = StringUtils.substringBetween(foundText,"of"," results");
int totalCount = Integer.parseInt(countText);
Verify.verify(totalCount > 0, totalCount + " is not > 0");
WebElement searchBroaden = driver.findElement(BROADEN_SEARCH_XPATH);
searchBroaden.click();
resultsPageUrl = driver.getCurrentUrl();
Verify.verify(resultsPageUrl.contains("searchType=bkw"),
"results page url doesnt include searchType=bkw");
resultsFoundLabel = driver.findElement(RESULTS_FOUND_XPATH);
foundText = resultsFoundLabel.getText();
countText = StringUtils.substringBetween(foundText, "of", " results");
int newTotalCount = Integer.parseInt(countText);
Assert.assertTrue(newTotalCount > 0, newTotalCount + " is not > 0");
Assert.assertTrue(newTotalCount > totalCount,
newTotalCount + " is not > than " + totalCount);
}
Where is the code duplication?
Let’s compare all verifications:
Verify.verify(homePageUrl.equalsIgnoreCase(HOME_PAGE_URL));
Verify.verify(resultsPageUrl.startsWith(RESULTS_PAGE_URL),
"results page url does not start with " + RESULTS_PAGE_URL);
Verify.verify(resultsPageUrl.contains("query=" + KEYWORD),
"results page url does not contain query=" + KEYWORD);
Verify.verify(resultsPageUrl.contains("searchType=smart"),
"results page url does not contain searchType=smart");
Verify.verify(foundText.contains("1 to 10"),
"results page does not include 1 to 10");
Verify.verify(totalCount > 0, totalCount + " is not > 0");
Verify.verify(resultsPageUrl.contains("searchType=bkw"),
"results page url doesnt include searchType=bkw");
All verify() methods are prefixed by the Verify class.
The same thing happens for the assertion methods:
Assert.assertTrue(newTotalCount > 0, newTotalCount + " is not > 0");
Assert.assertTrue(newTotalCount > totalCount,
newTotalCount + " is not > than " + totalCount);
Also, for the substringBetween() method:
String countText = StringUtils.substringBetween(foundText,"of"," results");
countText = StringUtils.substringBetween(foundText, "of", " results");
It would be nice not to have to prefix all verify() methods with the Verify class, all assert methods with the Assert class and all substringBetween() methods with the StringUtils class.
Using static imports does the trick.
Add the following imports to the top of the class:
import static org.apache.commons.lang3.StringUtils.*;
import static org.testng.Assert.*;
import static com.google.common.base.Verify.*;
You can remove now the Verify, Assert and StringUtils class names from the script:
@Test
public void searchTestUsingStaticImports() {
driver.get(HOME_PAGE_URL);
String homePageUrl = driver.getCurrentUrl();
verify(homePageUrl.equalsIgnoreCase(HOME_PAGE_URL));
WebElement searchBox = driver.findElement(SEARCH_BOX_ID);
searchBox.sendKeys(KEYWORD);
WebElement searchButton = driver.findElement(SEARCH_BUTTON_ID);
searchButton.click();
String resultsPageUrl = driver.getCurrentUrl();
verify(resultsPageUrl.startsWith(RESULTS_PAGE_URL),
"results page url does not start with " + RESULTS_PAGE_URL);
verify(resultsPageUrl.contains("query=" + KEYWORD),
"results page url does not contain query=" + KEYWORD);
verify(resultsPageUrl.contains("searchType=smart"),
"results page url does not contain searchType=smart");
WebElement resultsFoundLabel = driver.findElement(RESULTS_FOUND_XPATH);
String foundText = resultsFoundLabel.getText();
verify(foundText.contains("1 to 10"),
"results page does not include 1 to 10");
String countText = substringBetween(resultsFoundText, "of", " results");
int totalCount = Integer.parseInt(countText);
verify(totalCount > 0, totalCount + " is not > 0");
WebElement searchBroaden = driver.findElement(BROADEN_SEARCH_XPATH);
searchBroaden.click();
resultsPageUrl = driver.getCurrentUrl();
verify(resultsPageUrl.contains("searchType=bkw"),
"results page url doesnt include searchType=bkw");
resultsFoundLabel = driver.findElement(RESULTS_FOUND_XPATH);
foundText = resultsFoundLabel.getText();
countText = substringBetween(foundText, "of", " results");
int newTotalCount = Integer.parseInt(countText);
assertTrue(newTotalCount > 0, newTotalCount + " is not > 0");
assertTrue(newTotalCount > totalCount,
newTotalCount + " is not > than " + totalCount);
}