Многократный запуск одного теста в параллельном режиме с разными данными.

Всем доброго времени суток.

Есть набор кейсов для тестирования формы авторизации. По сути, действия выполняются одни и те же, но данные используются разные. Возникла потребность все это дело автоматизировать и распараллелить. С точки зрения кода, тест нам нужен всего один. А вот данные в него будут передаваться разные. Если отбросить затею с параллельностью, то подойдет и DataProvider, который последовательно будет передавать в наш тест набор Object[][]. Но вот попытка использования параметра parallel=true, ничем хорошим не увенчалась. Сам драйвер изначально стартовал в BeforeTest. Пробовал засовывать его в BeforeMethod - не помогло.

Собственно, если банально разнести один и тот же код теста по разным классам и подхватить их Jenkins'ом, то эта проблема решается: стартуют заданное число инстансов браузера, и в параллельном режиме запускают один и тот же тест из разных классов, с разными данными. Но этот вариант не очень красив. Может у кого есть идеи, как можно было бы запустить один тест заданное число раз в параллельном режиме на разных инстансах браузера? 

Заранее спасибо.

кроме того, что вы установили parallel=true, вы установили также что нужно запускать параллельно методы?

Я сталкивался с подобной задачей.

Решил следующим образом, создал два класса: один с тестовым методом, в который передавал тестовые данные, второй - это фабрика которая инициализировала тесты в зависимости от набора входящих данных. 

 

Для этого использовал TestNG. Про фабрики TestNG можно почитать тут  http://testng.org/doc/documentation-main.html#factories .

И еще один нюанс,  для иницилизации драйвера использовал аннотацию @BeforeClass,ну и соответственно @AfterClass - для закрытия браузера и сбора результатов тестов.  

Расспаралеливать я не пробовал, но по идее должно работать.

В xml файле указаны все необходимые опции: parallel="methods" thread-count="3" data-provider-thread-count="3". Самому тесту тоже пробовал задавать threadPoolSize и т.п., но безрезультатно. В такой ситуации вызывается заданное число инстансов браузера, ввиду переноса инициализации драйвера в BeforeMethod, но тесты пытаются распараллелиться только в одном из инстансов, что естественно приводит к эксепшенам.

Так весь вопрос как раз таки в параллельности. Из примеров TestNG видно, что фабрики хоть и создают динамически тесты, но вот обращение производится циклическое. Цикл конечно можно распараллелить на уровне ядер процессора, но как заставить динамически сформированные тесты запускаться не в одном инстансе браузера - пока загадка. TestNG ведь подтягивает xml, в котором прописаны наши тесты и способ их распараллеливания. А если он всего один статический, или множество динамических, ему по сути нечего параллелить. У нас есть готовый скрипт, который формирует xml, исходя из имеющегося набора тестов. У меня появилась одна идея. Попробую его немного поправить, может что-то получится.

Решился таки вопрос. В общем, последний testng (6.5.2) содержит фикс по распарраллеливанию классов с использованием Factory.  Достаточно подключить либу, задать в xml параметры: parallel="classes" thread-count="N", и вынести инициализацию драйвера в BeforeClass. Естественно, класс, копии которого будут динамически создаваться в зависимости от объема выборки DataProvider, не должен фигурировать в xml. Указывать нужно лишь класс, содержащий Factory.

2 лайка

Для тех кто наткнётся на проблему параллелизации тестов с DataProvider-ами в 2018 году.
В TestNG 6.11 это делается добавлением параметра runInParallel=true к DataProvider и теми же

Никаких Фабрик делать не нужно.

1 лайк

покажите пожалуйста проект и пример кода.

Шел 2012 год, testng 6.5.2…
Вы сейчас серьезно просите проект и пример кода? :slight_smile:

сори - но вообще то пример для 6.8.x / 6.13.x тоже пригодится.

Пример класса

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class ParallelClass {
    @Test(dataProviderClass = ParallelClass.class, dataProvider = "dp")
    public void parallelTest(final String example) throws InterruptedException {
        Thread.sleep(10000);
        System.out.println(example);
    }

    @DataProvider(name = "dp", parallel = true )
    public Object[] dpParallel() {
        Object[] strings = new Object[10];
        for (int i = 0; i < 10; i++) {
            strings[i] = "test" + i;
        }
        return strings;
    }
}

Пример тест сьюта

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel Suite" configfailurepolicy="continue" verbose="2" thread-count="5" data-provider-thread-count="5" parallel="methods">
    <test name="Parallel Test">
        <classes>
            <class name="ParallelClass"/>
        </classes>
    </test>
</suite>

Если запустить тесты через IDEA TestNG plugin не через сьют, то запустить количество потоков равное количеству данных в дата провайдере.
Если запустить через сьют, то количество потоков возьмётся из сьют xml. Если такой настройки в сьюте не указано, то количество потоков будет браться по количеству данных в дата провайдере.

PS: Не используйте архаичные DataProvider. Пользуйтесь DataSupplier GitHub - sskorol/test-data-supplier: TestNG DataProvider on steroids, за который отдельное спасибо @ArtOfLife

1 лайк

Небольшая поправка.
“runInParallel” - это название параметра для DataSupplier. Для DataProvider он называется просто “parallel”

спасибо
понимаете мне надо прикрутить интеграционные тесты с многопоточностью к
GitHub - sergueik/testng-dataproviders: This project exercises TestNG data providers: Excel 2003, 2007, Open Office, JSON, csv, Fillo которая скорее всего не пойдет из за race condition по чтению тестовых данных из excel / openoffice и т.п. - да, и хотелось бы чтобы travis это все делал…
этот вообще хобби-проект поэтому я ему периодически уделяю внимание чтобы его улучшить и т.д.
еще раз спасибо