Запуск одних и тех же тестов на большом количестве веб-сайтов

Мне нужно запустить одни и те же тесты на более чем 70 веб-сайтах, которые функционально одинаковы, но имеют разные скины. Однако все они доступны через разные URL-адреса.

Используя TestNG и Java, что было бы эффективным способом передачи URL-адресов в тесты, чтобы я мог: а) запускать каждый тест для каждого сайта и сообщать о том же б) выполнять тесты параллельно, чтобы сэкономить время (потребность в будущем)

Я хочу хранить URL-адреса в таком формате, чтобы они были доступны конечным пользователям и настраивались ими. В идеале это должен быть файл .csv или, альтернативно, файл testng.xml. Я думаю либо о @DataProvider, либо о @Factory, но не уверен, как использовать их эффективным и удобным способом для получения параметров из внешнего источника или где в моей текущей модели лучше всего разместить такие методы? Трудность, с которой я сталкиваюсь, заключается в том, что я не хочу обязательно передавать данные в @Test, а скорее передавать одно значение за раз (url-адрес) и запускать все аннотированные методы @Test.

Моя текущая простая установка выглядит следующим образом:

testngxml:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Suite1" verbose="1">
<test name="FindARouteTest">
    <parameter name="number" value="1"/>
    <parameter name="from" value="LONDON"/>
    <parameter name="to" value="GLASGOW"/>
    <parameter name="emailAddress" value="[email protected]"/>
    <classes>
        <class name="acceptancetests.EndToEndTest">
        </class>
    </classes>
</test>

My acceptance test:

public class EndToEndTest extends DriverBase{

private HomePage home;
private String url;

@Factory(dataProvider = "urls", dataProviderClass = URLProvider.class)
public EndToEndTest(String url) {
    this.url = url;
}


@BeforeSuite
public void stuff(){
    newDriver();
}


@BeforeClass
public void setup(){
    home = new HomePage(driver, url);
}

@Test (priority = 1)
@Parameters({"from","to"})
public void searchForARoute(String from, String to) throws InterruptedException {
    home.selectWhereFrom(from);
    home.selectWhereTo(to);
    //some assertions...

Мой объект страницы:

public class HomePage extends SeleniumBase {

public HomePage(WebDriver driver, String url) {
    super(driver, url);
    try {
        visit(url);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    driver.manage().window().maximize();
}

public void someMethodOrOther(){
//some methods...

Базовая страница моих методов Selenium:

public class SeleniumBase implements Config {

public WebDriver driver;
public String url;

public SeleniumBase(WebDriver driver) {
    this.driver = driver;
    this.url = url;
}

public void visit() throws MalformedURLException {
    driver.get(url);
} //more methods...

Страница моей базы драйверов:

public class DriverBase implements Config {

public static WebDriver driver;
public static String url;

    protected void newDriver() {
        if (host.equals("localhost")) {
            if (browser.equals("firefox")) {
                System.setProperty("webdriver.gecko.driver",
                        System.getProperty("user.dir") + "\\drivers\\geckodriver.exe");
                FirefoxProfile fp = new FirefoxProfile();
//more stuff

Класс поставщика URL:

public class URLProvider {

@DataProvider(name = "urls")
public static Object[][] dataProviderMethod()
{
    return new Object[][] {{"http://siteone.com"},
                            {"http://sitetwo.com"},
                            {"http://sitethree.com"}
    };
}
}

Наконец, конфигурация, которая в настоящее время содержит только BaseUrl:

public interface Config {

String baseUrl = System.getProperty("baseUrl", 
String browser = System.getProperty("browser", "chrome");
String host = System.getProperty("host", "localhost");

}

person Steerpike    schedule 09.08.2016    source источник


Ответы (1)


Вы можете использовать аннотацию @Factory в конструкторе тестового класса EndToEndTest и предоставить ему поставщик данных.

private String url;

@Factory(dataProvider = "urls", dataProviderClass = URLProvider.class)
public EndToEndTest(String url) {
  this.url = url;
}

Вам необходимо предоставить реализацию класса поставщика данных URL для доступа к Excel или любому другому файлу, который вы хотите, и вернуть объект [][].

Необходимо изменить конструкторы HomePage и SeleniumBase, чтобы передать URL-адрес, который вы вызываете из своего метода @BeforeClass.

Это должно создать отдельный экземпляр для этого тестового класса для каждой строки URL-адреса и вызвать методы @Test.

Если вам нужно передать больше данных, чем URL-адрес строки, вы можете вместо этого использовать объект. Как я вижу, вы передаете 4 параметра в свой testng.xml для метода.

Параллелизм должен быть довольно простым, предполагая, что вы захотите запустить все методы @Test для данного URL-адреса в одном потоке. Параллельным вариантом будут «классы».

person Grasshopper    schedule 10.08.2016
comment
спасибо за подробный ответ - я попробую ваши предложения и дам вам знать, как я получаю - person Steerpike; 11.08.2016
comment
это работает хорошо, но при отладке с URL-адресами x3 в URLProvider.class я вижу, что аннотированный конструктор «@Factory» вызывается 3 раза (один раз для каждого параметра) перед «@BeforeClass», а это означает 3 потока? Полагаю, и 3 окна браузера с параллельно работающими тестами. Начнем с того, что я хотел бы, чтобы каждый URL-адрес был передан, все «@Tests» запускались с одним URL-адресом, а затем извлекались по следующему. Итак, передайте один URL-адрес конструктору EndtoEnd, запустите тесты, а затем выберите следующий - не знаю, как это возможно. - person Steerpike; 11.08.2016
comment
Насколько я понимаю, вы хотите, чтобы он запускался последовательно, один URL за другим. Не параллельно. Это правильно? Просто удалите параметр parallel из вашего testng.xml или тестов, и они будут запускаться один за другим. - person Grasshopper; 11.08.2016
comment
извините, да, сначала серийно, но в будущем хочу исследовать параллельно. В настоящее время у меня нет параллели ни в testng.xml, ни в тестах. Я обновлю фрагменты кода, чтобы показать текущую реализацию - person Steerpike; 11.08.2016
comment
Итак, вы хотите, чтобы вместо открытия и закрытия трех окон браузера вы хотели, чтобы тест выполнялся последовательно в одном окне браузера. Если это так, то в классе EndToEndTest создайте новый метод и аннотируйте его с помощью «BeforeSuite» и переместите вызов newDriver() из текущего метода «BeforeClass» в этот новый метод. Также убедитесь, что вы закрываете или выходите из браузера в методе AfterSuite. Удалите закрытие любого драйвера из метода AfterClass. Теоретически он должен открывать только одно окно браузера для всего набора тестов. - person Grasshopper; 11.08.2016
comment
Видел обновленный код, должен работать с изменениями, упомянутыми в моем предыдущем комментарии. - person Grasshopper; 11.08.2016
comment
что на самом деле происходит в этом случае, так это то, что он запускает @BeforeClass x3 раза - один раз для каждого URL-адреса - до того, как попадет в тесты. Это означает, что каждый URL-адрес загружается в одно и то же окно браузера перед запуском любых тестов. Поэтому мне все еще нужно средство для чтения только 1 URL-адреса в классе за раз, открытия браузера, запуска тестов, затем загрузки следующего URL-адреса, запуска тестов и т. д. - person Steerpike; 11.08.2016
comment
Можете ли вы попробовать это в Google Chrome. Я пробовал что-то похожее на ваш код на firefox и chrome. Работал правильно на хроме, но бомбил, как вы описали, на фаерфоксе. Надо проверить это. Интересно! - person Grasshopper; 11.08.2016
comment
думая об этом, будет непрактично запускать от начала до конца в одном потоке/браузере, поэтому их параллельная работа, вероятно, идеальна. Мне просто нужно настроить их на a. ограничить количество браузеров разумным числом и б. попросите testng сообщить имя проверенного URL-адреса вместо номера потока. Спасибо за вашу помощь - голосование за оригинальный ответ - person Steerpike; 11.08.2016