简体   繁体   中英

Run parallel test methods which are dependent with different parameter using Data Provider in TestNg

I want to run test methods which are dependent and use ITestContext, to run in parallel with different parameters using Data Provider in TestNg. I am trying to call the test class pragmatically.

The code looks like this:

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();
    }

}

My functionality is to call the test class multiple times with different parameters and the classes being called should run parallelly

The issue with this is that the testclass1 would be invoked three times, but the testclass2 and testclass3 would be invoked only once because, the execution of those methods does not depend on the number of times testclass1 is executed. It only depends on whether testclass1 passed or not. To solve the issue, you need to use @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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM