Sometimes, you automate test cases that create a new item, like a new account:
@Test
public void createAccountTest() {
HomePage homePage = new HomePage(driver);
homePage.open();
CreateAccountPage createAccountPage = homePage.goToCreateAccountPage();
createAccountPage.populateFields(
USERNAME, PASSWORD,
FIRST_NAME, LAST_NAME,
BIRTH_DAY, BIRTH_MONTH, BIRTH_YEAR,
STREET_NAME, CITY, POSTAL_CODE, PROVINCE, COUNTRY);
createAccountPage.createAccount();
assertTrue(createAccountPage.isAccountCreated());
}
The obvious issue with this test is that the populateFields() method of the CreateAccountPage class has so many parameters.
The method may look as follows:
public class CreateAccountPage {
..................................
public void populateFields(String userName,
String password,
String firstName,
String lastName,
int birthDay,
int birthMonth,
int birthYear,
String streetName,
String city,
String postalCode,
String province,
String country) {
typeValue(userNameId, userName);
typeValue(passwordId, password);
typeValue(firstNameId, firstName);
typeValue(lastNameId, lastName);
typeValue(birthDayId, String.valueOf(birthDay));
typeValue(birthMonthId, String.valueOf(birthMonth));
typeValue(birthYearId, String.valueOf(birthYear));
typeValue(streetNameId, streetName);
typeValue(cityId, city);
typeValue(postalCodeId, postalCode);
typeValue(provinceId, province);
typeValue(countryId, country);
}
private void typeValue(By by, String value) {
WebElement element = driver.findElement(by);
element.sendKeys(value);
}
}
The method types a value in each of the account fields displayed in the page.
How do we fix the issue of having so many parameters for this method?
One way is by grouping all values into a map and passing only the map to the populateFields() method:
@Test
public void createAccountTest() {
HashMap<String, String> userInfo = new HashMap<> ();
userInfo.put("username", USERNAME);
userInfo.put("password", PASSWORD);
userInfo.put("firstName", FIRST_NAME);
userInfo.put("lastName", LAST_NAME);
userInfo.put("birthDay", BIRTH_DAY);
userInfo.put("birthMonth", BIRTH_MONTH);
userInfo.put("birthYear", BIRTH_YEAR);
userInfo.put("streetName", STREET_NAME);
userInfo.put("city", CITY);
userInfo.put("postalCode", POSTAL_CODE);
userInfo.put("province", PROVINCE);
userInfo.put("country", COUNTRY);
HomePage homePage = new HomePage(driver);
homePage.open();
CreateAccountPage createAccountPage = homePage.goToCreateAccountPage();
createAccountPage.populateFields(userInfo);
createAccountPage.createAccount();
assertTrue(createAccountPage.isAccountCreated());
}
The populateFields() method changes a bit as well:
public class CreateAccountPage {
..................................
public void populateFields(HashMap<String, String> userInfo) {
typeValue(userNameId, userInfo.get("userName"));
typeValue(passwordId, userInfo.get("password"));
typeValue(firstNameId, userInfo.get("firstName"));
typeValue(lastNameId, userInfo.get("lastName"));
typeValue(birthDayId, userInfo.get("birthDay"));
typeValue(birthMonthId, userInfo.get("birthMonth"));
typeValue(birthYearId, userInfo.get("birthYear"));
typeValue(streetNameId, userInfo.get("streetName"));
typeValue(cityId, userInfo.get("city"));
typeValue(postalCodeId, userInfo.get("postalCode"));
typeValue(provinceId, userInfo.get("province"));
typeValue(countryId, userInfo.get("country"));
}
private void typeValue(By by, String value) {
WebElement element = driver.findElement(by);
element.sendKeys(value);
}
}
The method has only 1 parameter, the map object.
Each time a value from the map is needed, it is retrieved using the key value.
There are multiple issues with using a map in a scenario like this:
initially, the birth day, month and year have the int type; since the map uses String as type for the keys and also for the values, we need to use the String type for these 3 fields; this is not good as an integer value should be saved in an integer variable and not in a String one
the map contains values that have nothing in common; the username and password do not have anything in common with the user personal info (first name, last name, birth date) or with the address info
if we need methods for comparing different user info objects (or other purposes), there is no way to add them to the map object; these methods could be created in the CreateAccountPage but this is the wrong place to have them (as the CreateAccountPage should only be about handling this page and not about comparing or handling maps)
there is no way to validate the values that are added to the map
Maps should not be used for grouping together values that are unrelated.
What should we do then?
The next post will explain a possible solution.