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

目录

  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>

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

原文:http://www.importnew.com/14508.html

TestNG并行测试的更多相关文章

  1. Maven捆绑TestNG实现测试自动化执行、部署和调度

    一. 需求介绍 自动化测试,尤其是接口测试时,要写大量的测试用例,这些测试用例我们当然首选使用TesteNG编写,用例数量大,还涉及各种依赖包之类的问题,因此用Maven管理也是最方便最易实现的. 面 ...

  2. TestNG 搭建测试框架 自动化测试

    框架层级及基本组件:    参考:https://www.cnblogs.com/jier888/p/8998724.html Java作为开发语言 Maven管理项目及Jar包 Testng作为测试 ...

  3. 使用 TestNG 并发测试 ;

    使用TestNG对IE /Chrome/firefox 进行兼容性并发测试 : package testNGTest; import org.openqa.selenium.By; import or ...

  4. U3D协程Coroutine之WWW与Update()的并行测试

    using System.Collections; using UnityEditor; using UnityEngine; using UnityEngine.UI; /************* ...

  5. TestNG之测试执行后没有生成默认测试报告(IDEA)

    使用IDEA+TestNG进行测试,没有生成 测试报告,是因为没有勾选监听器使用默认报告,具体操作如下: “Run” -> "Edit Configurations" -&g ...

  6. appium多机并行测试

    在实际应用中需要对多个机型并行测试,节省时间 多机测试的思路 启动多个appium server与多台机器交互(android和ios均可)   注意:一定要使用node安装appium的命令行,使用 ...

  7. testng入门教程10 TestNG参数化测试

    在TestNG的另一个有趣的功能是参数测试.在大多数情况下,你会遇到这样一个场景,业务逻辑需要一个巨大的不同数量的测试.参数测试,允许开发人员运行同样的测试,一遍又一遍使用不同的值. TestNG让你 ...

  8. testng入门教程9 TestNG依赖测试

    有时候,你可能需要在一个特定的顺序调用方法在测试案例,或你想分享一些数据和方法之间的状态.TestNG支持这种依赖测试方法之间的显式依赖它支持声明. TestNG允许指定依赖,无论与否: 使用属性de ...

  9. testng入门教程8 TestNG异常测试

    TestNG跟踪异常处理代码提供了一个选项.可以测试是否需要代码抛出异常或不抛出. @Test注释expectedExceptions 参数一起使用.现在,让我们来看看@Test(expectedEx ...

随机推荐

  1. 【转】String字符串相加的问题

    String字符串相加的问题 前几天同事跟我说我之前写的代码中在操作字符串时候,使用字符串相加的方式而不是使用StringBuffer或者StringBuilder导致内存开销很大.这个问题一直在困扰 ...

  2. bzoj1968 COMMON 约数研究

    Input只有一行一个整数 N(0 < N < 1000000).Output只有一行输出,为整数M,即f(1)到f(N)的累加和.Sample Input 3 Sample Output ...

  3. Vim的基本使用(二)

    本文为原创文章,转载请标明出处 目录 11.可视模式 12.指定计数 13.重复命令 14.外部命令 15.命令行编辑 16.文件编辑 17.分割窗口 18.GUI命令 19.配置 20.Vim Ch ...

  4. spring 内部工作机制(二)

    本章节讲Spring容器从加载配置文件到创建出一个完整Bean的作业流程及参与的角色. Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表, ...

  5. VTL(Velocity Templates Language,即Velocity模板语言)初识语法总结

    1.velocity是一门基于Java语言的视图表现层模板引擎,它可以取代jsp,比jsp更高效. 2.velocity变量的定义与引用 (1).定义一个变量:#set ($a = "vel ...

  6. 网站常用的一些javascript封装 简化调用

    //用于网页地址参数 //参数中包含出了英文中文数字之外的其他符号时进行编码并在前面加"=="进行标识,否则直接返回 //解码时根据是否含有"=="标识来决定是 ...

  7. python apschedule安装使用与源码分析

    我们的项目中用apschedule作为核心定时调度模块.所以对apschedule进行了一些调查和源码级的分析. 1.为什么选择apschedule? 听信了一句话,apschedule之于pytho ...

  8. springboot mybatis优雅的添加多数据源

    springboot的原则是简化配置,本文试图不通过xml配置,使用configuration配置数据源,并进行简单的数据访问. 并且配置了多数据源,在开发过程中这种场景很容易遇到. 1.依赖 spr ...

  9. 【记录】Spring项目转化为Spring Web项目

    前言 在将Spring项目转化为Spring Mvc项目时出现了点问题,总是无法成功部署,查阅资料也并没有找到一个完美的解决方案,最后是参考在idea中创建maven web app项目后的目录才成功 ...

  10. DevOps之软件定义网络SDN

    唠叨话 关于德语噢屁事的知识点,仅提供专业性的精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <软件定义网络SDN(Software Defined Network)> 关于软 ...