并行模式下数据提供者与线程并行“方法”设置之间的关系

问题描述 投票:1回答:2

有两个测试类,每个测试类都有一个测试方法,使用并行模式的数据提供器。

public class FirstNg {

    @Test(dataProvider = "dp11", description="f one")
    public void f11(Integer n, String s) throws InterruptedException {
        System.out.println("DP FIR ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
        Thread.sleep(4000);
    }

    @DataProvider(parallel = true)
    public Object[][] dp11() {
        return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
                new Object[] { 4, "d" }};
    }

}

public class SecondNg {

    @Test(dataProvider = "dp22", description="f two")
    public void f22(Integer n, String s) throws InterruptedException {
        System.out.println("DP SEC ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
        Thread.sleep(4000);
    }

    @DataProvider(parallel = true)
    public Object[][] dp22() {
        return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
                new Object[] { 4, "d" }};
    }       
}

测试运行的持续时间使用在BeforeSuite和AterSuite中确定的时间计算。

案例1 - 没有任何线程并行设置运行。

<suite name="suite" data-provider-thread-count="2"> 
  <test name="test"> 
    <classes> 
      <class name="FirstNg"/> 
      <class name="SecondNg"/> 
    </classes> 
  </test>
</suite>

这给出了以下结果。

DP FIR ----12----1552410839748
DP FIR ----11----1552410839752
DP FIR ----12----1552410843753
DP FIR ----11----1552410843756
DP SEC ----13----1552410847763
DP SEC ----14----1552410847764
DP SEC ----13----1552410851767
DP SEC ----14----1552410851768
DURATION - 16.936 secs

前两行是属于FirstNg类的数据提供者的。这将以两对(等于data-provider-thread-count的值)重复,然后使用SecondNg类的数据提供者。

案例2 - 使用线程并行设置运行方法。

<suite name="Surefire suite" data-provider-thread-count="2" parallel="methods"> 
  <test name="Surefire test"> 
    <classes> 
      <class name="testngparallel.FirstNg"/> 
      <class name="testngparallel.SecondNg"/> 
    </classes> 
  </test>
</suite>

这给出了以下结果。

DP SEC ----14----1552412828961
DP FIR ----13----1552412828962
DP FIR ----16----1552412828964
DP SEC ----15----1552412828966
DP FIR ----13----1552412832972
DP FIR ----16----1552412832977
DP SEC ----15----1552412832979
DP SEC ----14----1552412832980
DURATION - 8.161 secs

前四行一起启动。两行属于FirstNg数据提供者,另外两行属于SecondNg。重复此操作直到所有数据提供程序的所有行都用完为止。

从这个讨论看来,它有2个池,一个用于数据提供者,另一个用于其他测试 - https://groups.google.com/forum/#!topic/testng-users/BKfSgHoAChU

添加parallel =“methods”设置可减少测试执行的时间。此外,测试序列也发生了变化,来自数据提供者的测试也被混淆了。两个设置之间有什么联系?

testng testng-dataprovider
2个回答
2
投票

添加parallel =“methods”设置可减少测试执行的时间。此外,测试序列也发生了变化,来自数据提供者的测试也被混淆了。两个设置之间有什么联系?

基本上这两个设置控制不同的执行方面。所有测试方法都可以分为两类。

  • 定期测试方法
  • 由数据提供程序支持的测试方法。

TestNG有两个特定的设置,以满足上述两个类别的需求

  • thread-count - 在任何给定点控制有多少常规测试方法可以同时运行。
  • data-provider-thread-count - 在任何给定点控制,可以同时运行多少数据驱动的测试方法。

当您启用这两个设置时(以及当您使用常规和数据驱动的测试方法时)会发生什么情况,TestNG会同时运行所有测试方法,如果存在本质上是数据驱动的测试方法,那么这些数据驱动迭代也是并行执行的。

就像你同时分离一堆线程一样,但是其中一个或多个线程在内部分离出额外的线程。

此设置为您提供了执行速度方面的最大吞吐量,但如果您有更大的值(通过添加这两个设置值获得),则可能会影响整体性能,因为现在JVM将开始执行更多上下文切换而不是安排线程并完成工作。

简单术语中线程数的经验法则为2N-1(其中N表示处理器中的核心数。因此,如果您有四核处理器,则最大线程数应为7)。这是一种计算线程数的过于简单的方法,但是知道这一点对我有帮助。


1
投票

简而言之,parallel = true对数据提供者的注释,允许对方法的每次迭代使用单独的线程池和测试数据,而不管并行方法/ class / tests / none。

当您将parallel = true添加到数据提供者注释时,它将考虑使用data-provider-thread-count(默认为10)提供大小的单独池。因此,当使用数据提供程序进行测试时,它将使用单独的线程池并行执行,即使您在套件配置中设置了parallel=none也是如此。

Case parallel=none和数据提供者parallel = false或未设置:包含来自数据提供者的迭代的每个方法都将在同一个线程中运行。

DP FIR ----1----1552433313814
DP FIR ----1----1552433317824
DP FIR ----1----1552433321834
DP FIR ----1----1552433325839
Normal FIR2 ----1----1552433329848
DP SEC ----1----1552433333855
DP SEC ----1----1552433337859
DP SEC ----1----1552433341865
DP SEC ----1----1552433345871
Normal SEC2 ----1----1552433349876

Case parallel=none和数据提供者parallel = true

所有方法都需要在相同的线程中按顺序执行接受数据驱动的方法。如果该方法是数据驱动的,那么当它转向时,当前的线程将使用单独的池来并行运行每个迭代,以防数据提供者parallel = true。在下面的执行中,一个数据提供者设置为parallel = true而另一个不设置。因此,您可以看到当前线程在“DP FIR”的单独池中执行迭代,并在“DP SEC”的当前线程中运行所有迭代。 (未提供data-provider-thread-count,因此默认为10)

DP FIR ----10----1552433554893
DP FIR ----12----1552433554893
DP FIR ----11----1552433554893
DP FIR ----13----1552433554894
Normal FIR2 ----1----1552433558907
DP SEC ----1----1552433562916
DP SEC ----1----1552433566923
DP SEC ----1----1552433570928
DP SEC ----1----1552433574933
Normal SEC2 ----1----1552433578938
<suite name="suite" >
    <test name="test">
        <classes>
            <class name="FirstNg" />
            <class name="SecondNg" />
        </classes>
    </test>
</suite>
public class FirstNg {


    @Test(dataProvider = "dp11", description = "f one")
    public void f11(Integer n, String s) throws InterruptedException {
        System.out.println("DP FIR ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
        Thread.sleep(4000);
    }

    @Test
    public void f12() throws InterruptedException {
        System.out.println("Normal FIR2 ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
        Thread.sleep(4000);
    }

    @DataProvider(parallel = true)
    //@DataProvider
    public Object[][] dp11() {
        return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
                new Object[] { 4, "d" } };
    }

}

public class SecondNg {

    @Test(dataProvider = "dp22", description="f two")
    public void f22(Integer n, String s) throws InterruptedException {
        System.out.println("DP SEC ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
        Thread.sleep(4000);
    }

    @Test
    public void f222() throws InterruptedException {
        System.out.println("Normal SEC2 ----" + Thread.currentThread().getId() + "----" + System.currentTimeMillis());
        Thread.sleep(4000);
    }

    //@DataProvider(parallel = true)
    @DataProvider
    public Object[][] dp22() {
        return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, new Object[] { 3, "c" },
                new Object[] { 4, "d" }};
    }       
}

案例parallel=methods or classes

使用parallel=methods它将开始并行执行,具体取决于thread-count在xml配置中提供的大小池。再次如果方法是数据驱动的,当它转向时,分配的线程将在并行的单独池中运行每次迭代。否则,分配的线程按顺序运行每次迭代。

您可以看到分配给“DP FIR”的线程在“DP FIR”的单独池中执行迭代,但在“DP SEC”的指定线程中运行所有迭代。

DP FIR ----14----1552433989613
Normal FIR2 ----11----1552433989614
DP FIR ----17----1552433989613
DP SEC ----12----1552433989613
DP FIR ----16----1552433989613
DP FIR ----15----1552433989616
Normal SEC2 ----13----1552433989617
DP SEC ----12----1552433993625
DP SEC ----12----1552433997632
DP SEC ----12----1552434001640

案例parallel=methods or classes和数据提供者parallel = false或未设置:

当转向数据驱动方法时,每个迭代将在分配的线程中按顺序执行。

© www.soinside.com 2019 - 2024. All rights reserved.