запускать последовательные тесты из параллельных наборов - PullRequest
0 голосов
/ 19 февраля 2020

Из одного списка ввода я делаю уникальные наборы входов. Все наборы должны работать параллельно, но сам каждый набор должен запускать тест последовательно, с перестановками набора в качестве входных данных для теста.

Как это настроено:
DataProvider принимает список устройств (количество устройств варьируется). Это делает наборы устройств n-размера, скажем, 3 устройства на набор. Каждый набор устройств вводится для одного и того же заводского метода для одного и того же контрольного примера. (Эта часть должна быть параллельной). Затем метод Factory делает перестановки этого набора и выполняет тестовый пример для каждой перестановки. (Эта часть должна быть последовательной)

Например:
Список устройств в качестве входных данных для DP: {A, B, C, D, E, F}
DP создает наборы из 3 устройства: {A, B, C} и {D, E, F}
{A, B, C} вводятся для фабрики. Фабрика производит: {A, B, C}, {B, C, A} и {C, A, B}.
Тестовый набор должен сначала выполняться для: A, B, C
Затем тестовый пример должен выполняться снова для B, C, A
и запускаться в последний раз для C, A, B
Параллельно
{D, E, F} вводится для той же Фабрики, что и выше. Фабрика делает: {D, E, F}, {E, F, D} и {F, D, E}
Как и выше, тестовый случай последовательно перебирает перестановки.

Что я ожидается, что каждая фабрика работает в потоке, и что каждая фабрика делает перестановки и запускает перестановки последовательно. Заводы должны работать параллельно.

Первый вопрос: Возможно ли это? Я все еще довольно новичок в TestNG, так что, возможно, это не так.
Второй вопрос: (зависит от OnQuestion = "Первый вопрос") - Как? Я мог бы не структурировать это наилучшим образом, как есть. Использование потоков возможно, но похоже, что TestNG уже должен это обрабатывать.

В XML я пытался изменить то, что выполняется параллельно. Для сюиты все это 1 поток (не удивительно). Для теста это только 1 отдельный поток. Для классов это создает отдельные потоки для каждого метода @ Test-annotated, но последний поток запускает все остальные методы. Methods запускает каждый метод в одном из 3 потоков, выделенных в XML, но каждая фабрика все еще находится в одном «основном» потоке. Конечно, если я просто удаляю параллельный параметр, все работает в одном потоке. Группировка по экземплярам должна быть истинной, поэтому каждый шаг T C выполняется до запуска следующего экземпляра T C. Я также играю со структурой - если я найду решение, я выложу обновление.

//with parallel "tests"
DP thread: main
Creating a permutation from: A, B, C
Factory thread: main
Set: A, B, C
Set: B, C, A
Set: C, A, B
Creating a permutation from: D, E, F
Factory thread: main
Set: D, E, F
Set: E, F, D
Set: F, D, E
TestNG-tests-1: step 1
TestNG-tests-1: step 2
TestNG-tests-1: step 3
TestNG-tests-1: step 4
TestNG-tests-1: step 1
TestNG-tests-1: step 2
TestNG-tests-1: step 3
TestNG-tests-1: step 4
(repeats 4x)
//with parallel "classes"
DP thread: main
Creating a permutation from: A, B, C
Factory thread: main
Set: A, B, C
Set: B, C, A
Set: C, A, B
Creating a permutation from: D, E, F
Factory thread: main
Set: D, E, F
Set: E, F, D
Set: F, D, E
TestNG-test=Dev test-1: step 1
TestNG-test=Dev test-2: step 2
TestNG-test=Dev test-3: step 3
TestNG-test=Dev test-3: step 4
TestNG-test=Dev test-3: step 1
TestNG-test=Dev test-3: step 2
TestNG-test=Dev test-3: step 3
TestNG-test=Dev test-3: step 4
(repeats 4x with thread 3 running remaining iterations)

Ожидаемый / желаемый вывод:

DP thread: main
Creating a permutation from: A, B, C
Factory thread: 1
Set: A, B, C
Set: B, C, A
Set: C, A, B
Creating a permutation from: D, E, F
Factory thread: 2
Set: D, E, F
Set: E, F, D
Set: F, D, E
TestNG-test=Dev test-1: step 1
TestNG-test=Dev test-1: step 2
TestNG-test=Dev test-1: step 3
TestNG-test=Dev test-1: step 4 //completed TC for A, B, C
TestNG-test=Dev test-1: step 1
TestNG-test=Dev test-1: step 2
TestNG-test=Dev test-1: step 3
TestNG-test=Dev test-1: step 4 //completed TC for B, C, A
TestNG-test=Dev test-1: step 1
TestNG-test=Dev test-1: step 2
TestNG-test=Dev test-1: step 3
TestNG-test=Dev test-1: step 4 //completed TC for C, A, B
TestNG-test=Dev test-2: step 1
TestNG-test=Dev test-2: step 2
TestNG-test=Dev test-2: step 3
TestNG-test=Dev test-2: step 4 //completed TC for D, E, F
TestNG-test=Dev test-2: step 1
TestNG-test=Dev test-2: step 2
TestNG-test=Dev test-2: step 3
TestNG-test=Dev test-2: step 4 //completed TC for E, F, D
TestNG-test=Dev test-2: step 1
TestNG-test=Dev test-2: step 2
TestNG-test=Dev test-2: step 3
TestNG-test=Dev test-2: step 4 //completed TC for F, D, E
(parallel output, so not necessary in order as above)

XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<suite name="Suite" parallel="suites" thread-count="3" data-provider-thread-count="3" verbose="1">
     <test name="Dev test" group-by-instances="true"> 
        <classes> 
            <class name="package.TestCase1Factory" />
<!--            <class name="package.TestCase2Factory" /> -->
<!--            <class name="package.TestCase3Factory" /> -->
<!--  will eventually have other test cases in this suite -->
        </classes> 
    </test> 
</suite>

DP:

public class DP_forFactory {

    @DataProvider (name = "setsAndNum", parallel = true)
    public static Object[][] testInput3() throws IOException {

        System.out.println("DP thread: "  + Thread.currentThread().getName());

        //just some sample data. Each row could also just be {A, B, C}, etc
        Object[][] output = new Object[][] {
            {new String[] {"A", "B", "C"}, "Parallel set 1"},
            {new String[] {"D", "E", "F"}, "Parallel set 2"},   
        };      
        return output;
    }
}

Завод:

public class TestCase1Factory {
    private static final int DEVICES_PER_TEST = 3;

    @Factory (dataProviderClass = DP_forFactory.class, dataProvider = "setsAndNum")
    public Object[] createTCInstances(String[] deviceSet, String setNum) {

        System.out.println("Creating a permutation from: " + deviceSet[0] + ", " + deviceSet[1] + ", " + deviceSet[2]);
        System.out.println("Factory thread: " + Thread.currentThread().getName());

        Object[] sequentialSet = new Object[deviceSet.length];

        //create permutations
        for (int i = 0; i < DEVICES_PER_TEST; i++) {
            sequentialSet[i] = new TestCase1(deviceSet[i], deviceSet[(i+1) % DEVICES_PER_TEST], deviceSet[(i+2) % DEVICES_PER_TEST]);
        }       
        return sequentialSet;
    }   
}

Контрольный пример (класс):

//this is the part that receives the @Factory input
public class TestCase1 {

    //these are specific to the TC, so don't need to have a flexible setup
    private String role1;
    private String role2;
    private String role3;

    public TestCase1(String dev1, String dev2, String dev3) {
        this.role1= dev1;
        this.role2= dev2;
        this.role3= dev3;
        System.out.println("Set: " + role1 + ", " + role2 + ", " + role3);
    }

    @Test
    public void step1() {
        System.out.println(Thread.currentThread().getName() + ": step 1");
    }

    @Test (dependsOnMethods = "step1")
    public void step2() {
        System.out.println(Thread.currentThread().getName() + ": step 2");
    }

    @Test (dependsOnMethods = "step2")
    public void step3() {
        System.out.println(Thread.currentThread().getName() + ": step 3");
    }

    @Test (dependsOnMethods = "step3")
    public void step4() {
        System.out.println(Thread.currentThread().getName() + ": step 4");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...