Sometimes, we need test data as follows in our Selenium tests:
public static final String ADDRESS = "3000 Main Street, Burnaby, V2N-1M9, British Columbia, Canada";
The address value is saved in a String variable.
The test method will need different parts of the address so methods for getting the street number, street name, city, postal code, province and country are necessary:
private String getStreetNumber(String address) {
}
private String getStreetName(String address) {
}
private String getCity(String address) {
}
private String getPostalCode(String address) {
}
private String getProvince(String address) {
}
private String getCountry(String address) {
}
This approach works well if the address always includes the same parts and in the same order (street number, street name, city, postal code, province, country).
But, if the address includes also an apartment number sometimes, the code will become more complex than it should be. Since it has to take into consideration 2 types of addresses:
one without apartment number
public static final String ADDRESS = "3000 Main Street, Burnaby, V2N-1M9, British Columbia, Canada";
the other with apartment number
public static final String ADDRESS = "3000 Main Street, apartment 14, Burnaby, V2N-1M9, British Columbia, Canada";
Things become even more complex if the address parts are displayed in different order such as:
public static final String ADDRESS = "3000 Main Street, V2N-1M9, Burnaby, British Columbia, Canada";
or
public static final String ADDRESS = "3000 Main Street, Burnaby, British Columbia, V2N-1M9, Canada";
What should we do in this case?
The solution is simple.
Instead of saving a complex value in a String variable, create an Address class and use an object of it:
private Address address = new Address(3000, "Main Street", City.Burnaby, "V2N-1M9", Province.BC, Country.Canada);
Each part of the address is provided as a parameter of the constructor. Not all parameters use String as type. Some parameters may be numeric, others may be an enumeration. This solves the issue with address parts being available in different orders.
The Address class may have multiple constructors in case that apartment is needed:
private Address address = new Address(3000, "Main Street", 15, City.Burnaby, "V2N-1M9", Province.BC, Country.Canada);
The Address class does not need to implement methods for extracting the different parts of the address. To get any part of an address, a get method is all you need.
The full Address class is below:
public class Address {
private int streetNumber;
private String streetName;
private int apartmentNumber = 0;
private String city;
private String province;
private String postalCode;
private String country;
public Address(int streetNumber,
String streetName,
int apartmentNumber,
String city,
String postalCode,
String province,
String country) {
this(streetNumber, streetName, city, postalCode, province, country);
this.apartmentNumber = apartmentNumber;
}
public Address(int streetNumber,
String streetName,
String city,
String postalCode,
String province,
String country) {
this.streetNumber = streetNumber;
this.streetName = streetName;
this.city = city;
this.province = province;
this.postalCode = postalCode;
this.country = country;
}
public int getStreetNumber() {
return streetNumber;
}
public String getStreetName() {
return streetName;
}
public int getApartmentNumber() {
return apartmentNumber;
}
public String getCity() {
return city;
}
public String getProvince() {
return province;
}
public String getPostalCode() {
return postalCode;
}
public String getCountry() {
return country;
}
}
In summary, do not save complex values in String variables.
Create a class instead and use its objects.
Thanks for reading.
PS:
In case that you are interested in seeing how a full Selenium project is created, have a look here.