首页 > 解决方案 > 使用 TestNg 中的数据提供程序运行依赖于不同参数的并行测试方法

问题描述

我想运行依赖并使用 ITestContext 的测试方法,以使用 TestNg 中的数据提供程序与不同的参数并行运行。我正在尝试务实地调用测试类。

代码如下所示:

package com.ExploringTestNg;

import java.util.Random;

import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class ParallelMethodTest {
    
    @Test(dataProvider = "dataprovider")
    public void testclass1(ITestContext context,String deviceId) {
        
        long id = Thread.currentThread().getId();
        System.out.println("TestClass1 is being called and context is being setup");
        System.out.print("The thread id is "+id);
        System.out.println("device id is "+deviceId);
        context.setAttribute("deviceId",deviceId);
    }
    @Test(dependsOnMethods = {"testclass1"})
    public void testclass2(ITestContext context) {
        long id = Thread.currentThread().getId();
        System.out.println("TestClass2 is being called and context is being retrieved "+(String)context.getAttribute("deviceId"));
        System.out.println("The thread id is "+id+"\n");
    }
    @Test(dependsOnMethods = {"testclass2"})
    public void testclass3(ITestContext context) {
        long id = Thread.currentThread().getId();
        System.out.println("TestClass3 is being called and context is being retrieved "+(String)context.getAttribute("deviceId"));
        System.out.println("The thread id is "+id);
    }
    @DataProvider(name = "dataprovider",parallel = true)
    public Object[][] getDataFromDataprovider(){
        return new Object[][]
                {
                    {"1001"},
                    {"1002"},
                    {"1003"}
                };
    }
}
package com.ExploringTestNg;

import java.util.ArrayList;
import java.util.List;

import org.testng.TestNG;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

public class DynamicXMLSetuo  {

    public static void main(String[] args) {
        XmlSuite suite = new XmlSuite();
        suite.setName("TempSuite1");
        XmlTest test = new XmlTest(suite);
        test.setName("Functional usecase 1");
        List<XmlClass> classes = new ArrayList<XmlClass>();
        classes.add(new XmlClass("com.ExploringTestNg.ParallelMethodTest"));
        test.setXmlClasses(classes);
        
        List<XmlSuite> suites = new ArrayList<XmlSuite>();
        suites.add(suite);
        TestNG tng = new TestNG();
        tng.setXmlSuites(suites);
        tng.setThreadCount(5);
        tng.setParallel(XmlSuite.ParallelMode.METHODS);
        tng.run();
    }

}

我的功能是使用不同的参数多次调用测试类,并且被调用的类应该并行运行

标签: javatestng

解决方案


这样做的问题是testclass1会被调用 3 次,而testclass2andtestclass3只会被调用一次,因为这些方法的执行不依赖于testclass1执行的次数。只看testclass1通过与否。要解决此问题,您需要使用@Factory

public class ParallelMethodTest {

    private final String deviceId;

    ParallelMethodTest(String id) {
        this.deviceId = id;
    }

    @DataProvider(parallel = true)
    public static Object[][] dataProvider() {
        return new Object[][] { { "1001" }, { "1002" }, { "1003" } };
    }

    @Factory(dataProvider = "dataProvider")
    public Object[] createInstances(String id) {
        // The factory method uses the dataProvider to initialize
        // multiple instances of the test class.
        return new Object[] { new ParallelMethodTest(id) };
    }

    @Test
    public void testclass1() {

        long id = Thread.currentThread().getId();
        System.out.println("TestClass1 is being called and context is being setup");
        System.out.print("The thread id is " + id);
        System.out.println("device id is " + deviceId);
    }

    @Test(dependsOnMethods = { "testclass1" })
    public void testclass2() {
        long id = Thread.currentThread().getId();
        System.out.println("TestClass2 is being called and context is being retrieved " + deviceId);
        System.out.println("The thread id is " + id + "\n");
    }

    @Test(dependsOnMethods = { "testclass2" })
    public void testclass3() {
        long id = Thread.currentThread().getId();
        System.out.println("TestClass3 is being called and context is being retrieved " + deviceId);
        System.out.println("The thread id is " + id);
    }
}

With this, there is no need for storing the deviceId in test context as the corresponding deviceId would be available in the class itself.

UPDATE : To run in parallel, you need to do one more thing inside DynamicXMLSetuo.

suite.setParallel(XmlSuite.ParallelMode.METHODS);

By adding ParallelMode.METHODS, TestNG will run all your test methods in separate threads. Dependent methods will also run in separate threads but they will respect the order that you specified.


推荐阅读