patternjavaModerate
DRYing out some Java code and tests
Viewed 0 times
dryingandtestsjavasomecodeout
Problem
I am writing some tests that all follow the same pattern, I feel like repeating myself over and over again, how can I reduce the repetition? The (almost) repeating part is in constructor and the class level variables:
VariablesPagepublic class VariablesPage extends LoadableComponent {
private final TestHelpers helpers;
private WebDriver driver;
@FindBy(xpath = "//a[@title=\"Define new variable\"]")
private WebElement btnAddNewVariable;
public VariablesPage() throws Exception {
helpers = new TestHelpers();
driver = helpers.getWebDriver();
helpers.setHar(VariablesPage.class.getSimpleName());
PageFactory.initElements(driver, this);
isLoaded();
helpers.getHar();
}
@Override
protected void load() {
}
@Override
protected void isLoaded() throws Error {
helpers.waitUntil(btnAddNewVariable);
}
}addStepsPagepublic class AddStepsPage extends LoadableComponent {
private final TestHelpers helpers;
private WebDriver driver;
@FindBy(xpath = "//div[@class=\"body sequential\"]")
private WebElement divStepsBody;
public AddStepsPage() throws Exception {
helpers = new TestHelpers();
driver = helpers.getWebDriver();
helpers.setHar(AddStepsPage.class.getSimpleName());
PageFactory.initElements(driver, this);
isLoaded();
helpers.getHar();
}
@Override
protected void load() {
}
@Override
protected void isLoaded() throws Error {
helpers.waitUntil(divStepsBody);
}
}Solution
First, let us collect the code pieces which are repeated
Fields
Constructor related
Now, let's start refactoring by extending
which reduces the first class to
But wait, we can do better! So, let us also call
which reduces the first class to
Naming
I don't know if the
Fields
private final TestHelpers helpers;
private WebDriver driver;Constructor related
helpers = new TestHelpers();
driver = helpers.getWebDriver();Now, let's start refactoring by extending
LoadableComponent public abstract class ExtendedLoadableComponent extends LoadableComponent {
protected final TestHelpers helpers
protected WebDriver driver;
public ExtendedLoadableComponent() throws Exception {
helpers = new TestHelpers();
driver = helpers.getWebDriver();
}
}which reduces the first class to
public class VariablesPage extends ExtendedLoadableComponent {
@FindBy(xpath = "//a[@title=\"Define new variable\"]")
private WebElement btnAddNewVariable;
public VariablesPage() throws Exception {
super();
helpers.setHar(VariablesPage.class.getSimpleName());
PageFactory.initElements(driver, this);
isLoaded();
helpers.getHar();
}
@Override
protected void load() {}
@Override
protected void isLoaded() throws Error {
helpers.waitUntil(btnAddNewVariable);
}
}But wait, we can do better! So, let us also call
helpers.setHar(String) and thus we need to refactor the constructor of ExtendedLoadableComponent public abstract class ExtendedLoadableComponent extends LoadableComponent {
protected final TestHelpers helpers
protected WebDriver driver;
public ExtendedLoadableComponent(Class pageClassToProxy) throws Exception {
helpers = new TestHelpers();
driver = helpers.getWebDriver();
helpers.setHar(pageClassToProxy.getSimpleName());
PageFactory.initElements(driver, pageClassToProxy);
}
}which reduces the first class to
public class VariablesPage extends ExtendedLoadableComponent {
@FindBy(xpath = "//a[@title=\"Define new variable\"]")
private WebElement btnAddNewVariable;
public VariablesPage() throws Exception {
super(VariablesPage.class);
isLoaded();
helpers.getHar();
}
@Override
protected void load() {}
@Override
protected void isLoaded() throws Error {
helpers.waitUntil(btnAddNewVariable);
}
}Naming
I don't know if the
TestHelpers class is your own. If yes, you should think about changing the names for setHar() and getHar() so Mr. Maintainer can evaluate what they do by looking at the names.Code Snippets
private final TestHelpers helpers;
private WebDriver driver;helpers = new TestHelpers();
driver = helpers.getWebDriver();public abstract class ExtendedLoadableComponent<T> extends LoadableComponent<T> {
protected final TestHelpers helpers
protected WebDriver driver;
public ExtendedLoadableComponent() throws Exception {
helpers = new TestHelpers();
driver = helpers.getWebDriver();
}
}public class VariablesPage extends ExtendedLoadableComponent<VariablesPage> {
@FindBy(xpath = "//a[@title=\"Define new variable\"]")
private WebElement btnAddNewVariable;
public VariablesPage() throws Exception {
super();
helpers.setHar(VariablesPage.class.getSimpleName());
PageFactory.initElements(driver, this);
isLoaded();
helpers.getHar();
}
@Override
protected void load() {}
@Override
protected void isLoaded() throws Error {
helpers.waitUntil(btnAddNewVariable);
}
}public abstract class ExtendedLoadableComponent<T> extends LoadableComponent<T> {
protected final TestHelpers helpers
protected WebDriver driver;
public ExtendedLoadableComponent(Class<T> pageClassToProxy) throws Exception {
helpers = new TestHelpers();
driver = helpers.getWebDriver();
helpers.setHar(pageClassToProxy.getSimpleName());
PageFactory.initElements(driver, pageClassToProxy);
}
}Context
StackExchange Code Review Q#59388, answer score: 10
Revisions (0)
No revisions yet.