Ниже приведено точное (минимальное) представление структуры моего класса, обратите внимание, что в структуре есть только одна точка интеграции с TestNG (аннотация @Test для абстрактного класса).
public abstract class AbstractValidator2{
protected WebDriver driver;
protected String url;
public AbstractValidator2(String url, WebDriver driver) {
this.url = url;
this.driver = driver == null ? new ChromeBrowser() : driver; //Setup Selenium
//more common setups reports, utilities, etc...
}
@Test
public void run() {
setup();
validate();
tearDown();
}
public void setup() {}
public void tearDown() {}
public abstract boolean validate();
}
Теперь приведен пример тестового примера, который прекрасно работает с описанной выше структурой.
public class sampletest extends AbstractValidator2{
public sampletest() {
super("www.google.com", null);
}
@Override
public boolean validate() {
return true;
}
}
В связи с тем, что в приведенном выше нет конструктора args, его очень легко использовать с TestNG. Я могу включить это в любой тестовый XML-файл и настроить его на запуск любым способом. Отлично, жизнь удалась!
Следующий тест ниже - это интеграция с TestNG.
public class sampletest2 extends AbstractValidator2{
Date date;
public sampletest2(String url, Date date) {
super(url, null);
date = date;
}
@Override
public boolean validate() {
driver.get(url);
Utils.wait(5000);
return false;
}
}
В этом примере мне нужно предоставить аргументы моему конструктору. Мне также нужен новый экземпляр для каждого теста, который я хотел бы проверить. Это исключает поставщиков данных в одиночку. Чтобы добавить сложности, мне также нужно работать параллельно. Фабрики действительно работают, но есть проблема. Мне кажется невозможным выбрать отдельные варианты использования при использовании фабрики (я должен запустить их все без изменения кода). Ежедневно мне очень нравится запускать варианты использования индивидуально.
Решение, которое я нашел, заключается в следующем.
public class sampletest2suite {
@Test
public void sampletest2google(){
new sampletest2("https://www.google.com/", null).run();
}
@Test
public void sampletest3bing(){
new sampletest2("https://www.bing.com/", null).run();
}
}
Эта структура, однако, нанесла мне вред и создала структуру, которая не позволяет мне использовать многие замечательные возможности Testng. Моей целью было бы использовать конфигурацию xml testng, чтобы я мог удалить этот дубликат кода и конфигурацию из своей структуры классов Java.
Я также предложил другое решение. Это решение злоупотребляет наследованием и создает подклассы по единственной причине обеспечения конструктора no args для совместимости с testng. Вы можете увидеть следующий вопрос stackexchange о том, почему это плохая схема: https://softwareengineering.stackexchange.com/questions/257562/is-creating-subclasses-for-specific-instances-a-bad-practice
public class sampletest2suitealternativeapproach {
public static class sampletest2Google extends sampletest2{
public sampletest2Google() { super("https://www.google.com/", null); }
}
public static class sampletest2Bing extends sampletest2{
public sampletest2Bing() { super("https://www.bing.com/", null); }
}
}
Учитывая текущие проблемы, есть ли у кого-нибудь совет, чтобы вернуться на более здоровый путь.