从并行集中运行顺序测试

时间:2020-02-18 21:55:03

标签: java multithreading testng

从一个输入列表中,我进行了唯一的一组输入。所有集合都应并行运行,但是每个集合本身都需要按顺序运行测试,并且需要将集合的排列作为测试的输入。

设置方式:
DataProvider接收设备列表(设备数量各不相同)。它制作了n个大小的设备集,例如每组3个设备。 对于相同的测试用例,每组设备均以相同的Factory方法输入。 (这部分应该是平行的) 然后,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还是很陌生,所以也许不是。
第二个问题 :( dependsOnQuestion =“第一个问题”)-怎么样?我可能没有以最佳方式按原样构建此结构。使用线程是可能的,似乎TestNG应该已经在处理这种事情。

在XML中,我尝试更改并行运行的内容。对于套件,它全是1个线程(在此并不奇怪)。对于Test,它仅创建1个单独的线程。对于类,它似乎为每个@Test批注的方法创建了单独的线程,但是最终线程运行所有剩余的方法。方法在XML中分配的3个线程之一中运行每个方法,但是每个Factory仍在单个“主”线程中。当然,如果我只是删除并行参数,则所有内容都在单个线程中运行。 按实例分组必须为真,以便每个TC的步骤在TC的下一个实例运行之前执行。 我也在研究结构-如果找到解决方案,我将发布更新。

//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");
    }
}

0 个答案:

没有答案