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

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

目录

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

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

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

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

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

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

如何并行地执行测试方法

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

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的文件并将下述代码写入该文件中。

<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测试套件方式运行它。你将会在控制台中看到以下输出信息:

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动态指派的。

如何并行地执行测试类

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

ParallelClassesTestOne.java
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
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的文件并将下述代码写入该文件中:

<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测试套件方式运行它。你将会在控制台中看到以下输出信息:

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来证明这一点。

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

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

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的文件并将以下代码写入该文件中:

<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测试套件方式运行它。你将会在控制台中看到以下输出信息:

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注解上配置一些信息,我们就能启用多线程模式。

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的文件,并写入下述代码:

<suite name="Independent test Suite" >
  <test name="Independent test">
    <classes>
     <class name="com.howtodoinjava.parallelism.IndependentTest" />
    </classes>
  </test>
</suite>

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

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

原文链接: Lokesh Gupta 翻译: ImportNew.com - 杨 昆仑
译文链接: http://www.importnew.com/14508.html

时间: 2024-08-07 23:57:16

TestNG系列教程:并行执行测试的相关文章

前端测试框架Jest系列教程 -- Expect(验证)

写在前面 在编写测试时,我们通常需要检查值是否满足某些条件,Jest中提供的expect允许你访问很多“Matchers”,这些“匹配器”允许您验证不同的东西. Expect 可以验证什么 Jest中提供了如下的验证方法: expect(value) expect.extend(matchers) expect.anything() expect.any(constructor) expect.arrayContaining(array) expect.assertions(number) ex

testng多线程并行执行测试

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

服务端协议测试系列教程

测试技术分享之服务端协议测试系列教程 童鞋看完后有啥想法,可以发给我改进 在线播放地址:http://www.iqiyi.com/u/2013029540/a 下载地址:链接: http://pan.baidu.com/s/1boDHpbp 密码: p76e

TestNG基础教程 - TestNG.xml中的测试级别和常用注解执行顺序

根据testng.xml 文件配置, 测试级别为suite -> test -> class -> methods. test 对应testng.xml 中的test 标签, 而不是测试类里的@Test. 测试类里的@Test 对应 testng.xml中的methods. 创建TestCase 如TC3 运行效果 所以在使用@BeforeSuite,@BeforeTest,@BeforeClass,@BeforeMethod 等标签时, 它们的实际执行顺序也是suite -> t

菜鸟窝React Native 视频系列教程

菜鸟窝React Native 视频系列教程 交流QQ群:576089067 Hi,我是RichardCao,现任新美大酒店旅游事业群的Android Developer.15年加入饿了么即时配送BU,后负责蜂鸟众包Android端,期间引入react-native技术,作为国内react-native 与 Android混合开发的早期商业项目,具有一定经验,同时也是react-native开源项目reading(https://github.com/attentiveness/reading)

TestNG 入门教程&lt;Java 入门&gt;

TestNG 入门教程 摘要:http://www.cnblogs.com/TankXiao/p/3888070.html 国庆7天假期,大部分朋友都出去旅游了,微信圈里全是晒旅游的照片, 东南亚游,欧洲游呀,真是羡慕呀. 悲惨的我只去了上海野生动物园, 在家休息,利用这段假期,把之前学过的东西都总结下. 我前段时间加班太多了,每天忙碌工作,都没精力去管自己的学习新技能的计划, 博客也没写几篇,很多想做的事情都因为工作太忙而耽搁了. 所以工作太忙了也不好,没有精力关注工作以外的事情. 最近写自动

【COCOS CREATOR 系列教程之二】脚本开发篇&事件监听、常用函数等示例整合

[Cocos Creator ](千人群):  432818031 上一篇,介绍了Himi在使用过cc所有组件后的一篇总结,没有具体介绍每个组件的原因在于官方文档很齐全,而且也有视频的介绍. 所以希望童鞋们可以把我这两篇博文当成对组件.脚本两部分开发的整理与总结. 后续的文章,Himi应该主要更新一些官方还未补充或者还没有的教程.避免无用功. 下面直接放出代码,因为不是很难理解.所以不再一一赘述,都是常用的函数.事件监听.动作回调.定时器等开发过程中必接触的. 大致内容如下: cc 属性介绍 获

ASP.NET MVC3 系列教程 - 模型

I:基础绑定的实现 1.在前面的两篇基础文章(路由 及 控制器&视图)当中,还没对QueryString的绑定进行介绍,因为我觉得它更适合放在这一章节中去介绍.我们在用WebForm去开发的时候,有时候会利用到QueryString去做一些功能如:http://localhost/First/QueryString.aspx?Sort=Desc,在MVC中,它的实现有两种方式: 控制器代码 public class QueryStringController : Controller { pub

微信公众号开发系列教程一(调试环境部署)

原文:微信公众号开发系列教程一(调试环境部署) 目录 C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) 微信公众号火了好一阵子了,笔者算是比较早接触微信公众号开发的了,大概做了一年半了,从最开始的到处网上找demo到现在也开发一些公众号.园子里关于微信开发的教程已经数不胜数了,我也准备来凑凑热闹.一是梳理下这段时间开发的经验,二是希望能帮到想做微信开发的小伙伴们,希望大大神们吐槽的时候悠着点,