当前位置: 首页 > 知识库问答 >
问题:

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

傅胡媚
2023-03-14

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

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类的dataprovider开始。这将成对重复(等于数据提供程序线程计数的值),然后使用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

前四行一起开始。两行属于第一个NG数据提供程序,另外两行属于第二个NG数据提供程序。重复此操作,直到耗尽所有数据提供程序的所有行。

从这个讨论中,似乎有2个池,一个用于dataprovider,另一个用于其他测试-https://groups.google.com/forum/#哦!主题/测试用户/BKfSgHoAChU

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

共有2个答案

公冶翰池
2023-03-14

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

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

Caseparallel=none和data providerparallel=false或未设置:包括来自data provider的迭代的每个方法都将在同一线程中运行。

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

大小写并行=无和数据提供程序并行=真:

所有方法都需要在同一个线程中顺序执行,接受数据驱动的方法。如果该方法是数据驱动的,当轮到它时,当前线程将使用单独的池来并行运行每个迭代,以防数据提供者parallel=true。在下面的执行中,一个数据提供程序设置为“parallel=true”,另一个数据提供程序设置为“not”。因此,您可以看到当前线程在单独的池中为“DP FIR”执行迭代,并在当前线程中为“DP SEC”运行所有迭代。(未提供数据提供程序线程计数,因此默认为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" }};
    }       
}

Caseparallel=方法或类

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

您可以看到分配给“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

案例并行=方法或类和数据提供者并行=false或未设置:

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

周弘毅
2023-03-14

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

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

  • 常规试验方法
  • 数据提供程序支持的测试方法

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

  • 线程计数-它控制在任何给定点有多少个常规测试方法可以同时运行

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

这就像您同时旋转一堆线程,但其中一个或多个线程在内部旋转额外的线程。

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

简单来说,线程数的经验法则是2N-1(其中N代表处理器中的内核数。因此,如果您有四核处理器,最大线程数应该是7)。这是一种过于简单的线程数计算方法,但意识到这一点对我有帮助。

 类似资料:
  • 我想在类中与数据提供者并行运行测试方法。我需要一个数据提供者,它每次在新测试方法开始为给定的测试运行生成部分动态数据之前都会被调用。让我用伪代码解释一下: 我怎样才能做到这一点?

  • 我已经使用testng并行测试用例执行设置,但我只需要执行一次设置方法。 BeforeClass和BeforeMethod也会针对单个线程执行。但我需要在所有线程之前执行一次方法。 如何通过TestNG设置实现这一点? 测试NG。xml

  • 我想用Selenium和TestNG来模拟谷歌搜索,同时使用各种搜索参数。下面是我的测试类和testng。xml。我已经使用下面的注释

  • 本文向大家介绍数据并行与任务并行,包括了数据并行与任务并行的使用技巧和注意事项,需要的朋友参考一下 数据并行 数据并行意味着在每个多个计算核心上并发执行同一任务。 让我们举个例子,对大小为N的数组的内容求和。对于单核系统,一个线程将简单地对元素[0]求和。。。[N-1]。但是,对于双核系统,在核0上运行的线程A可以对元素[0]求和。。。[N / 2-1],而在核心1上运行的线程B可以求和元素[N

  • 一个基于Actor的HttpServer会对同样的问题做出怎样的反应?。是否所有请求都排在委托的参与者前面,以按顺序处理它们并将消息发送给其他参与者?。如果是这样的话,这就是我不明白actor怎么能比线程模型提供更好的性能的一点,因为仅仅1个actor按顺序处理20个请求,并不能比10个线程并发处理20个请求更快。 我想了解的是,当多个请求同时出现时,actor是如何反应的?,而不是actor如何

  • 并行 理论上并行和语言并没有什么关系,所以在理论上的并行方式,都可以尝试用Rust来实现。本小节不会详细全面地介绍具体的并行理论知识,只介绍用Rust如何来实现相关的并行模式。 Rust的一大特点是,可以保证“线程安全”。而且,没有性能损失。更有意思的是,Rust编译器实际上只有Send Sync等基本抽象,而对“线程” “锁” “同步” 等基本的并行相关的概念一无所知,这些概念都是由库实现的。这