TestNG - 多線程測試

一、前言

  隨着企業內部自動化資產的持續積累以及持續集成的推進,對自動化測試的運行速度要求越來越高,某些應用的自動化測試用例可能多達幾千條,如何加速這些自動化用例的運行速度,讓自動化落實到每一次版本變更和持續集成當中,是一個需要解決的問題。

二、TestNG 中的多線程使用姿勢

1、測試方法中的併發

  有些時候,我們需要對一個測試用例,比如一個 http 接口,執行併發測試,即一個接口的反覆調用,TestNG 中也提供了優雅的支持方式。

@Test(threadPoolSize = 5,invocationCount = 10)
    public void test1(){
        Assert.assertEquals(2,2);
        System.out.println("this is thread"+ Thread.currentThread().getId());
    }

  說明: threadPoolSize 表明用於調用該方法的線程池容量,該例就是同時起 5 個線程並行執行該方法;invocationCount 表示該方法總計需要被執行的次數。

該例子中 5 個線程同時執行,當總計執行次數達到 10 次時停止,執行結果如下:

 2、XML中的併發

  通常,在 TestNG 的執行中,測試的級別由上至下可以分爲suite -> test -> class -> method,箭頭的左邊元素跟右邊元素的關係是一對多的包含關係。

  這裏的 test 指的是 testng.xml 中的 test tag,而不是測試類裏的一個@Test。測試類裏的一個@Test實際上對應這裏的 method。所以我們在使用@BeforeSuite、@BeforeTest、@BeforeClass、@BeforeMethod這些標籤的時候,它們的實際執行順序也是按照這個級別來的。

1) test, class, method級別的併發,可以通過在 testng.xml 中的 suite tag 下設置,如:

<suite name="Testng Parallel Test" parallel="tests" thread-count="5">
<suite name="Testng Parallel Test" parallel="classes" thread-count="5">
<suite name="Testng Parallel Test" parallel="methods" thread-count="5">
說明:它們的共同點都是最多起 5 個線程去同時執行不同的用例。

 它們的區別如下:

  • tests 級別:不同 test tag 下的用例可以在不同的線程執行,相同 test tag 下的用例只能在同一個線程中執行。
  • classes 級別:不同 class tag 下的用例可以在不同的線程執行,相同 class tag 下的用例只能在同一個線程中執行。
  • methods 級別:所有用例都可以在不同的線程去執行。

  搞清楚併發的級別非常重要,可以幫我們合理地組織用例,比如將非線程安全的測試類或 group 統一放到一個 test 中,這樣在併發的同時又可以保證這些類裏的用例是單線程執行。也可以根據需要設定 class 級別的併發,讓同一個測試類裏的用例在同一個線程中執行。

2)實例演示

測試代碼:TestMethods.java

package com.test.extent;
import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.Test;

public class TestMethods {

    @Test
    public void test1(){
        Assert.assertEquals(2,2);
        System.out.println("this is thread"+ Thread.currentThread().getId());
    }

    @Test
    public void test2(){
        Assert.assertEquals(1,1);
        System.out.println("this is thread"+ Thread.currentThread().getId());
    }

    @Test
    public void test3(){
        Assert.assertEquals("sss","sss");
        System.out.println("this is thread"+ Thread.currentThread().getId());
    }

}

xml設置:tests級別併發示例

<?xml version="1.0" encoding="UTF-8" ?>

<suite name="Suite1" parallel="tests" thread-count="2">
    <test name="測試用例1">
        <classes>
            <class name="com.test.extent.TestMethods"></class>
        </classes>
    </test>
    <test name="測試用例2">
        <classes>
            <class name="com.test.extent.TestMethods"></class>
        </classes>
    </test>
    <test name="測試用例3">
        <classes>
            <class name="com.test.extent.TestMethods"></class>
        </classes>
    </test>
</suite>

 說明:在當前測試規劃的執行過程中,爲每個測試用例(指的是xml中的<test>)的執行使用單獨的線程(該測試用例中的測試方法共享一個線程),

最多併發2個線程,執行結果如下圖:<test name="測試用例1">的3個方法的線程id均爲16

xml設置:classes級別併發示例

<?xml version="1.0" encoding="UTF-8" ?>

<suite name="Suite1" parallel="classes" thread-count="2">
    <test name="測試用例1">
        <classes>
            <class name="com.test.extent.TestMethods"></class>
            <class name="com.test.extent.TestMethods2"></class>
        </classes>
    </test>
</suite>

 說明:在當前測試規劃的執行過程中,爲每個測試類(指的是xml中的<class>)的執行使用單獨的線程(該測試類中的測試方法共享一個線程),最多併發2個線程。執行結果如下圖:

xml設置:methods級別併發示例

<?xml version="1.0" encoding="UTF-8" ?>

<suite name="Suite1" parallel="methods" thread-count="2">
    <test name="test1">
        <classes>
            <class name="com.test.extent.TestMethods"></class>
        </classes>
    </test>
</suite>

  說明:在當前測試規劃的執行過程中,爲每個測試方法(指的是每個@Test)的執行使用單獨的線程,最多併發2個線程,執行結果如下圖:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章