首页 > 解决方案 > 如何使用对象迭代器 DataProvider 并在 java 中并行运行多个测试?

问题描述

所以我需要检查多个 CSV(超过 500k)并且数量永远不会相同。每个 CSV 文件有一行或多行,30 行。我需要获取每个文件,并使用 API 中的数据验证字段。

我现在想的解决办法是:

一个 DataProvider 可以为 Object 迭代器提供我需要检查的所有文件。对于每个文件,我将执行多个测试(10-15)。所有这些都与多个线程并行运行。为了不为每个测试执行 API 请求,我需要发出请求 @BeforeSuite。

我没有找到与这种类型的 DataProvider 并行执行测试的任何方法。测试首先对所有数据集运行 test1,然后对所有数据集运行 test2,因此使 API 调用 @BeforeSuite 没有任何价值。任何想法?

这是一个代码示例:

数据工厂:

import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class DataFactory {
    @Factory(dataProvider = "dp")
    public Object[] createInstances(String filename) {
        return new Object[]{new TestSuite(filename)};
    }

    private static final String CSV_PATH = "src/main/resources/files/";

    @DataProvider(name = "dp")
    public Iterator<Object[]> getFileList() {
        File[] files = new File(CSV_PATH).listFiles();
        List<Object[]> data = new ArrayList<>();

        for (File file : files) {
            data.add(new String[]{file.getName()});
        }

        return data.iterator();
    }
}

测试类:

import java.lang.reflect.Method;
import org.testng.annotations.Test;

public class TestSuite {
    String filename1 = "";

    public TestSuite(String filename) {

        filename1 = filename;
    }

    @Test
    public void test1(Method res) {
        System.out.println("…Executing…" + res.getName() + " dataProviderData " + filename1 + " thread number " + Thread.currentThread().getId());
    }

    @Test
    public void test2(Method res) {
        System.out.println("…Executing…" + res.getName() + " dataProviderData " + filename1 + " thread number " + Thread.currentThread().getId());
    }

TestNG XML 配置:

<suite name="Tests Suite" thread-count="20" parallel="methods">
    <test name="CSV test">
        <classes>
            <class name="DataFactory" group-by-instances="true"/>
        </classes>
    </test>
</suite>

标签: javacsvtestngtestng-dataprovider

解决方案


找到了一个解决方案:

在我的测试套件文件中添加了@BeforeClass:

    @BeforeClass
        public void getIdFromFilename(ITestContext context) throws IOException {

            String id = "";
            String name = "";

    //Get data from API
    //Get data from CSV

            context.setAttribute("product", product);
            context.setAttribute("id", id);
            context.setAttribute("name", name);
        }

@Test
    public void test1(ITestContext context) {
        PojoApi product = (PojoApi) context.getAttribute("product");
        String idFromApi = product.getId();
        String id = (String) context.getAttribute("id");

        System.out.println("Test id: ");
        System.out.println("Product id from api: " + idFromApi);
        System.out.println("Product id from CSV: " + id);
        System.out.println(Thread.currentThread().getId());

        Assert.assertEquals(id, idFromApi);
    }

    @Test
    public void test2(ITestContext context) {

        PojoApi product = (PojoApi) context.getAttribute("product");
        String name = (String) context.getAttribute("name");
        String nameFromAPI = product.getName();

        System.out.println("Test name: ");
        System.out.println("Product name from api: " + nameFromAPI);
        System.out.println("Product name from CSV: " + name);
        System.out.println(Thread.currentThread().getId());

        Assert.assertEquals(name, nameFromAPI);

    }

我在 TestNG XML 配置中将并行模式更改为 parallel="instances"

<suite name="CSV Suite" group-by-instances="true" parallel="instances" thread-count="10">
    <test name="CSV Test" >
        <classes>
            <class name="DataFactory"/>
        </classes>
    </test>
</suite>

推荐阅读