testng多线程并行执行测试

并行(多线程)技术在软件术语里被定义为软件、操作系统或者程序可以并行地执行另外一段程序中多个部分或者子组件的能力。TestNG允许我们以并行(多线程)的方式来执行测试。这就意味着基于TestNG测试组件的配置,多个线程可以被同时启动然后分别执行各自的测试方法。相对于传统的单线程执行测试的方式,这种多线程方式拥有很大的优势,主要是它可以减少测试运行时间,并且可以验证某段代码在多线程环境中运行的正确性。

invocationCount----表示执行的次数

threadPoolSize-----表示线程池的内线程的个数

timeOut-------超时时间-毫秒

目录

  1. 并行执行测试的优势
  2. 如何并行地执行测试方法
  3. 如何并行地执行测试类
  4. 如何并行地执行同一测试套件内的各个测试组件
  5. 如何配置需要在多线程环境中执行的测试方法

并行执行测试的优势

并行(多线程)执行测试可以给用户带来很多好处,主要包括以下两点:

1)减少了执行时间:并行测试也就意味着多个测试可以在同一时间被同时执行,从而减少了整体测试所花费的时间。

2)允许多个线程并行地测试同一个测试组件:有了这个特性,我们就能够写出相应的测试用例来验证应用程序中包含多线程部分的代码的正确性。

以上特性被广泛地应用在QA领域的自动化功能测试方面。通过简单的配置,QA人员就可以很轻松地使得他们的测试用例在多个浏览器或者操作系统中并行地执行。

TestNG提供了三种不同类型的配置方案来实现并行测试。

如何并行地执行测试方法

TestNG为我们提供了多种方式来实现并行测试,其中一种就是每一个独立的线程分别执行各自的测试方法。这种方式能够显著地减少测试执行时间,这是因为当有越多的测试方法被并行执行时,总体测试消耗时间将会越少。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

package com.howtodoinjava.parallelism;

import org.testng.annotations.AfterMethod;

import org.testng.annotations.BeforeMethod;

import org.testng.annotations.Test;

public class ParallelMethodTest

{

    @BeforeMethod

    public void beforeMethod() {

        long id = Thread.currentThread().getId();

        System.out.println("Before test-method. Thread id is: " + id);

    }

    @Test

    public void testMethodsOne() {

        long id = Thread.currentThread().getId();

        System.out.println("Simple test-method One. Thread id is: " + id);

    }

    @Test

    public void testMethodsTwo() {

        long id = Thread.currentThread().getId();

        System.out.println("Simple test-method Two. Thread id is: " + id);

    }

    @AfterMethod

    public void afterMethod() {

        long id = Thread.currentThread().getId();

        System.out.println("After test-method. Thread id is: " + id);

    }

}

上述测试类包含了两个测试方法,每个测试方法在执行时都会在控制台中打印出一条信息。每个测试方法以及它们各自的beforeMehod、afterMethod方法都会通过Thread.currentThread.getId()这段代码打印出执行该测试方法的线程的ID。

在项目中新建一个名为methods-test-testng.xml的文件并将下述代码写入该文件中。


1

2

3

4

5

6

7

<suite name="Test-method Suite" parallel="methods" thread-count="2" >

  <test name="Test-method test" group-by-instances="true">

    <classes>

      <class name="com.howtodoinjava.parallelism.ParallelMethodTest" />

    </classes>

  </test>

</suite>

在Eclipse中选中该文件并且以TestNG测试套件方式运行它。你将会在控制台中看到以下输出信息:


1

2

3

4

5

6

Before test-method. Thread id is: 10

Before test-method. Thread id is: 9

Simple test-method Two. Thread id is: 10

Simple test-method One. Thread id is: 9

After test-method. Thread id is: 10

After test-method. Thread id is: 9

注意:上述截图中的ThreadId可能与你本地控制台中输出的ThreadId不同,这是因为ThreadId的值是在程序运行时由JVM动态指派的。

从上述测试结果中我们可以很清晰地看出:上述两个测试方法以及各自相应的beforeMethod和afterMethod方法是在两个独立的线程中执行的。我们可以通过在控制台中输出的ThreadId来证明这一点。

如何并行地执行测试类

在下个例子中,我们会说明如何并行地执行测试类:同一个测试组件(test execution)中的各个测试类将会在独立的线程中并行地执行。

ParallelClassesTestOne.java


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

public class ParallelClassesTestOne

{

    @BeforeClass

    public void beforeClass() {

        long id = Thread.currentThread().getId();

        System.out.println("Before test-class. Thread id is: " + id);

    }

    @Test

    public void testMethodOne() {

        long id = Thread.currentThread().getId();

        System.out.println("Sample test-method One. Thread id is: " + id);

    }

    @Test

    public void testMethodTwo() {

        long id = Thread.currentThread().getId();

        System.out.println("Sample test-method Two. Thread id is: " + id);

    }

    @AfterClass

    public void afterClass() {

        long id = Thread.currentThread().getId();

        System.out.println("After test-class. Thread id is: " + id);

    }

}

ParallelClassesTestTwo.java


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

public class ParallelClassesTestTwo

{

    @BeforeClass

    public void beforeClass() {

        long id = Thread.currentThread().getId();

        System.out.println("Before test-class. Thread id is: " + id);

    }

    @Test

    public void testMethodOne() {

        long id = Thread.currentThread().getId();

        System.out.println("Sample test-method One. Thread id is: " + id);

    }

    @Test

    public void testMethodTwo() {

        long id = Thread.currentThread().getId();

        System.out.println("Sample test-method Two. Thread id is: " + id);

    }

    @AfterClass

    public void afterClass() {

        long id = Thread.currentThread().getId();

        System.out.println("After test-class. Thread id is: " + id);

    }

}

在项目中新建一个名为classes-test-testng.xml的文件并将下述代码写入该文件中:


1

2

3

4

5

6

7

8

<suite name="Test-class Suite" parallel="classes" thread-count="2" >

  <test name="Test-class test" >

    <classes>

      <class name="com.howtodoinjava.parallelism.ParallelClassesTestOne" />

      <class name="com.howtodoinjava.parallelism.ParallelClassesTestTwo" />

    </classes>

  </test>

</suite>

或者可以在测试用例的每一个被测的方法的注释@Test后面加上具体的线程信息如下:(只是举例并没有参与实际的eclipse运行)

@Test(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)

@BeforeClass(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
    public void beforeClass() {
        long id = Thread.currentThread().getId();
        System.out.println("Before test-class. Thread id is: " + id);
    }

    @Test(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
    public void testMethodOne() {
        long id = Thread.currentThread().getId();
        System.out.println("Sample test-method One. Thread id is: " + id);
    }

    @Test(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
    public void testMethodTwo() {
        long id = Thread.currentThread().getId();
        System.out.println("Sample test-method Two. Thread id is: " + id);
    }

    @AfterClass(threadPoolSize = 2, invocationCount = 10, timeOut = 1000)
    public void afterClass() {
        long id = Thread.currentThread().getId();
        System.out.println("After test-class. Thread id is: " + id);
    }

在Eclipse中选中该文件并且以TestNG测试套件方式运行它。你将会在控制台中看到以下输出信息:


1

2

3

4

5

6

7

8

Before test-class. Thread id is: 10

Before test-class. Thread id is: 9

Sample test-method One. Thread id is: 9

Sample test-method One. Thread id is: 10

Sample test-method Two. Thread id is: 10

After test-class. Thread id is: 10

Sample test-method Two. Thread id is: 9

After test-class. Thread id is: 9

从上述测试结果中我们可以很清晰地看出:上述两个测试类以及各自相应的beforeClass和afterClass方法是在独立的两个线程中执行的。我们可以通过在控制台中输出的ThreadId来证明这一点。

如何并行地执行同一测试套件内的各个测试组件

接下来我们会一起学习如何并行地执行同一个测试套件内的各个测试组件,即各个测试组件会分别在独立的线程中执行。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

package com.howtodoinjava.parallelism;

import org.testng.annotations.AfterClass;

import org.testng.annotations.AfterTest;

import org.testng.annotations.BeforeClass;

import org.testng.annotations.BeforeTest;

import org.testng.annotations.Parameters;

import org.testng.annotations.Test;

public class ParallelSuiteTest

{

    String testName = "";

    @BeforeTest

    @Parameters({ "test-name" })

    public void beforeTest(String testName) {

        this.testName = testName;

        long id = Thread.currentThread().getId();

        System.out.println("Before test " + testName + ". Thread id is: " + id);

    }

    @BeforeClass

    public void beforeClass() {

        long id = Thread.currentThread().getId();

        System.out.println("Before test-class " + testName + ". Thread id is: "

                + id);

    }

    @Test

    public void testMethodOne() {

        long id = Thread.currentThread().getId();

        System.out.println("Sample test-method " + testName

                + ". Thread id is: " + id);

    }

    @AfterClass

    public void afterClass() {

        long id = Thread.currentThread().getId();

        System.out.println("After test-method  " + testName

                + ". Thread id is: " + id);

    }

    @AfterTest

    public void afterTest() {

        long id = Thread.currentThread().getId();

        System.out.println("After test  " + testName + ". Thread id is: " + id);

    }

}

在项目中新建一个名为suite-test-testng.xml的文件并将以下代码写入该文件中:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

<suite name="Test-class Suite" parallel="tests" thread-count="2">

    <test name="Test-class test 1">

        <parameter name="test-name" value="test-method One" />

        <classes>

            <class name="com.howtodoinjava.parallelism.ParallelSuiteTest" />

        </classes>

    </test>

    <test name="Test-class test 2">

        <parameter name="test-name" value="test-method One" />

        <classes>

            <class name="com.howtodoinjava.parallelism.ParallelSuiteTest" />

        </classes>

    </test>

</suite>

在Eclipse中选中该文件并且以TestNG测试套件方式运行它。你将会在控制台中看到以下输出信息:


1

2

3

4

5

6

7

8

9

10

Before test Test One. Thread id is: 9

Before test Test Two. Thread id is: 10

Before test-class Test One. Thread id is: 9

Before test-class Test Two. Thread id is: 10

Sample test-method Test One. Thread id is: 9

Sample test-method Test Two. Thread id is: 10

After test-method  Test Two. Thread id is: 10

After test-method  Test One. Thread id is: 9

After test  Test One. Thread id is: 9

After test  Test Two. Thread id is: 10

从上述测试结果中我们可以很清晰地看出:上述两个测试组件是在独立的两个线程中分别执行的。我们可以通过在控制台中输出的ThreadId来证明这一点。

如何配置一个需要在多线程环境中执行的测试方法

之前我们讨论了如何并行(多线程)地执行测试方法,测试类以及测试组件。TestNG同时也提供了一种灵活的方式来配置需要在多线程环境下运行的测试方法:只要在该测试方法的@Test注解上配置一些信息,我们就能启用多线程模式。


1

2

3

4

5

6

7

8

9

public class IndependentTest

{

    @Test(threadPoolSize = 3, invocationCount = 6, timeOut = 1000)

    public void testMethod()

    {

        Long id = Thread.currentThread().getId();

        System.out.println("Test method executing on thread with id: " + id);

    }

}

上述测试方法是通过在@Test注解中配置threadPoolSize这个属性来进入多线程模式的。threadPoolSize被设为3,这就说明了该测试方法将会在三个不同的线程中同时执行。剩余两个属性:invocationCount配置的是该测试方法应被执行的总次数,timeOut配置的是每次执行该测试方法所耗费时间的阈值,超过阈值则测试失败。

在项目中新建一个名为independent-test-testng.xml的文件,并写入下述代码:


1

2

3

4

5

6

7

<suite name="Independent test Suite" >

  <test name="Independent test">

    <classes>

     <class name="com.howtodoinjava.parallelism.IndependentTest" />

    </classes>

  </test>

</suite>

在Eclipse中选中该文件并以TestNG测试套件方式运行。你将会在控制台中看到以下输出信息


1

2

3

4

5

6

Test method executing on thread with id: 11

Test method executing on thread with id: 10

Test method executing on thread with id: 9

Test method executing on thread with id: 11

Test method executing on thread with id: 11

Test method executing on thread with id: 10

在这里,我们可以看出该测试方法被执行了多次,而且它的执行次数跟invocationCount所指定的次数相同。而且从输出信息中,我们也可以很清晰地看到该测试方法每次执行都是在不同的线程中完成的。当我们需要按照某一固定次数,在多线程环境下运行某些测试方法时,上述特性会很有帮助,因为它避免了我们把整个测试套件都并行执行多次的代价。

test,class,method级别的并发,可以通过在testng.xml中的suite tag下设置,区别如下:tests级别:不同test tag下的用例可以在不同的线程执行,相同test tag下的用例只能在同一个线程中执行。classs级别:不同class tag下的用例可以在不同的线程执行,相同class tag下的用例只能在同一个线程中执行。methods级别:所有用例都可以在不同的线程去执行。
时间: 2024-08-07 23:57:12

testng多线程并行执行测试的相关文章

TestNG系列教程:并行执行测试

并行(多线程)技术在软件术语里被定义为软件.操作系统或者程序可以并行地执行另外一段程序中多个部分或者子组件的能力.TestNG允许我们以并行(多线程)的方式来执行测试.这就意味着基于TestNG测试组件的配置,多个线程可以被同时启动然后分别执行各自的测试方法.相对于传统的单线程执行测试的方式,这种多线程方式拥有很大的优势,主要是它可以减少测试运行时间,并且可以验证某段代码在多线程环境中运行的正确性. 目录 并行执行测试的优势如何并行地执行测试方法如何并行地执行测试类如何并行地执行同一测试套件内的

将MySQL去重操作优化到极致之三弹连发(二):多线程并行执行

上一篇已经将单条查重语句调整到最优,但该语句是以单线程方式执行.能否利用多处理器,让去重操作多线程并行执行,从而进一步提高速度呢?比如我的实验环境是4处理器,如果使用4个线程同时执行查重sql,理论上应该接近4倍的性能提升. 一.数据分片        我们生成测试数据时,created_time采用每条记录加一秒的方式,也就是最大和在最小的时间差为50万秒,而且数据均匀分布.因此先把数据平均分成4份. 1. 查询出4份数据的created_time边界值 select date_add('20

TestNG的参数化测试、共享线程池配置、参数默认值配置

在使用TestNG进行测试时,经常会使用到一些参数化配置,比如数据库.连接池.线程池数, 使用TestNG的参数@Parameter注解进行自动化读取 使用多线程的方式运行测试代码配置: 在'<suite>'标签中配置data-provider-thread-count="20" Java代码: /** * * <p> * Title: TestngParameters * </p> * * <p> * 参考配置文件testng-para

改进Threadglog并增加多线程写测试

写了个objectpool,很简单,就是个线程安全的队列. #pragma once #include <iostream> #include <concurrent_vector.h> #include <concurrent_queue.h> #include <algorithm> template <typename T> class ObjectPool { public: ObjectPool(size_t chunk_size =

TestNG如何取得测试类名

在A类中,如果要得到类名,可以用this.getClass().getSimpleName()或者使用this.getClass().getName(),通过以下方法区别这两个方法 package com.cn.plant; public class tree { @Test public void getClassName(){ String strName=this.getClass().getName(); System.out.println("getName输出结果:"+st

testNG 多线程测试(xml文件实现)

测试用例一般是单线程模式,为了提高测试效率.testNG的多线程可以分为test,class,method级别的并发,可以通过在testng.xml中的suite tag下设置. methods级别:所有用例都可以在不同的线程去执行.classs级别:不同class tag下的用例可以在不同的线程执行,相同class tag下的用例只能在同一个线程中执行.tests级别:不同test tag下的用例可以在不同的线程执行,相同test tag下的用例只能在同一个线程中执行. 如: <suite n

利用Testng注释实现多线程并发测试

Testng 是一款非常优秀的测试框架,真正从测试角度出发,为测试所想.在测试过程中我们经常会遇到对某一个场景做并发请求,主要想了解该程序在并发时是否会有异常或者没考虑到的其他情况,这时往往不是要做性能测试,又不能因为这个而去用LR来做这件事情.如果你对Testng 比较了解,你会发现只需2个简单的注释就可以实现这个需求. 1.主要使用了@Test 中的2个属性,一个是ThreadPoolSize 和invocationCount,分别是线程池大小,和调用次数线程池属于对象池.所有对象池都具有一

TestNG运行JUnit测试

现在,您已经了解了TestNG和它的各种测试,如果现在担心如何重构现有的JUnit代码,那就没有必要,使用TestNG提供了一种方法,从JUnit和TestNG按照自己的节奏.也可以使用TestNG执行现有JUnit测试用例.TestNG可以自动识别和运行JUnit测试,所以你可以使用TestNG运行所有的测试,并编写新的测试使用TestNG.所有你必须做的就是把JUnit的库TestNG的类路径上,它可以发现并使用JUnit类,改变测试运行从JUnit和TestNG Ant中,然后运行Test

C++ boost库无锁队列多线程并行测试与编译方法

阅读了网络中关于Boost库无锁队列的源代码,但却缺少编译方法.经过测试,确定了ubuntu 14.04中编译boost库的方法,特做记录. 无锁(free-lock)是实现高性能多线程并发编程的重要技术. 作为C++11 STL参考实现的boost库,不仅支持11标准,而且做了许多扩展,掌握其使用方法,对于提高代码质量,尤其重要. 以其多线程并行无锁队列为例,结合代码和说明,演示了无锁boost库的使用和编译方法. 代码及说明如下: //source: boost_queue.cpp //目的