本文介绍了如何使用来自excel文件的不同测试数据集在testng中运行多个测试用例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 testng.xml,我的项目包含多个类,每个类都有一个 @Test testNG 方法及其相关的数据提供程序(意味着类 I1_DoLoginTest 包含一个方法及其数据提供程序,类 I2_CreateScenarioTest 包含一个方法及其数据提供程序和类 I3_RunSimulationTest 包含一种方法及其数据提供者)

I have following testng.xml, my project contains multiple classes each with one @Test testNG Method and its relevant Data Provider (means class I1_DoLoginTest contain one method and its dataprovider, class I2_CreateScenarioTest contain one method and its dataprovider and class I3_RunSimulationTest contain one method and its dataprovider)

参考这 3 个类中每一个的结构与此非常相似:

Refer Structure of each of these 3 class very similar to this:

public class I1 {

@Test(priority = 1,dataProvider="dp_i1_Login")
public void I1_LoginTestCase(){
//Processing data from dataprovider given below
}
@DataProvider(name="dp_i1_Login")
public Object[][] dp_i1_Login() throws Exception{
//return fetching single row data in the form object array from excelsheet
//to be processed by test case
}
}

所以基本上我有一个带有 dataprovider 的类,它一次提供一行数据,每个单元格将作为参数传递给同一类的 @Test 方法,然后控制移动到下一个类,即 I2_CreateScenarioTest 和 I3_RunSimulationTest(两者都是I2_CreateScenarioTest 和 I3_RunSimulationTest 结构与 I1_LoginTestCase 相同)
testng.xml 结构如下:

So basically I have class with dataprovider which provides one row data from at a time, each cell will be passed as a parameter to @Test method of same class and then control moves to next class that is I2_CreateScenarioTest and then I3_RunSimulationTest (Both I2_CreateScenarioTest and I3_RunSimulationTest have same structure as I1_LoginTestCase)
testng.xml structure is as:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite guice-stage="DEVELOPMENT" name="Default suite">
  <test verbose="2" name="Default test">
    <classes>
      <class name="com.als.I1"/>
      <class name="com.als.I2"/>
      <class name="com.als.I3"/>
    </classes>
  </test> <!-- Default test -->
</suite> <!-- Default suite -->

我的问题是所有这 3 个类的执行顺序,我从不同的 excel 表中选择了 1 行(在此处参考 excel 表的结构 Excel 表格)

My problem is execution sequence of all these 3 classes, I have picked 1 row from different excel sheets (refer structure of excel sheet here Excel Sheet)

例如,如果每个工作表中有 2 行提供数据,那么当前执行 testngsuit(testng.xml) 就像执行 I1-I1-I2-I2-I3-I3 类,但我想执行类像 I1-I2-I3-I1-I2-I3.

For example if there are 2 rows in every sheet which provides data then, Current execution of testng suit(testng.xml) is like executing classes as I1-I1-I2-I2-I3-I3 but I want to execute classes like I1-I2-I3-I1-I2-I3.

单一方法在其各自的工作表中将其数据提供者的数据执行两次作为两行,但我需要将执行控制移动到第二类 I2,一旦类 I1 从 Excel 工作表读取和处理第一行,对于类 I2 也是如此, I2 也处理一行并移动到 I3 并且整个执行序列 (I1-I2-I3) 应该对各自工作表的第二行重复,每个单独的 Excel 工作表中的每一行共同代表一个测试服数据,第二行在每个单独的 Excel 表中共同代表第二套测试服数据.我希望将 testng 类执行为 I1-I2-I3-(对于所有第 1 行)-I1-I2-I3-(对于所有第 2 行)而不是 I1-I1-I2-I2-I3-I3(第 1 行2,第1行-第2行,第1行-第2行)

single method executing its dataprovider's data twice as 2 rows in its respective sheet, but I need to move execution control to second class which is I2 as soon as class I1 reads and process 1st row from excel sheet, and similarly for class I2, I2 also process one row and move to I3 and this whole execution sequence(I1-I2-I3) should be repeat for second rows of their respective sheets, each row in each individual excel sheet collectively represent one test suit data, and second row in each individual excel sheet collectively represent second test suit data. I want execution of testng classes as I1-I2-I3-(for all rows 1)-I1-I2-I3-(for all rows 2) instead of I1-I1-I2-I2-I3-I3(row 1-row 2,row 1-row 2,row 1-row 2)

推荐答案

您目前无法在 TestNG 中执行此操作.TestNG 基本上会运行一个具有由数据提供者提供支持的 @Test 测试的类,并在它选择 中的下一个类之前迭代所有数据提供者提供的数据集; 标签.如果您启用了并行性,这将并行发生,但不是您期望的方式.

You cannot do this currently in TestNG. TestNG would basically run through a class which has a @Test test powered by a data provider and iterate all the data provider provided data sets, before it picks up the next class in your <test> tag. If you have enabled parallelism this would happen in parallel but not the way in which you are expecting.

但是,您可以尝试执行以下操作:

However, you can try doing the following :

构建一个由 @Factory 注释构造函数驱动的测试类,并将此构造函数的 @Factory 注释绑定到 @DataProvider 注释数据提供者.

Build a test class that is driven by a @Factory annotated constructor and tie this constructor's @Factory annotation to a @DataProvider annotated data provider.

在您的测试类中包含所有当前分散在多个类中的 @Test 方法.

Within your test class house all of your @Test methods which are currently scattered across multiple classes.

这种安排会导致 TestNG 从你的数据提供者那里选择一行数据,将它提供给构造函数来实例化你的测试类,然后你的 @Test 方法基本上可以处理数据通过构造函数注入它.因此,对于您的数据提供者提供的每一行数据,都会创建一个测试类实例.只有这样,您才能实现您的目标.

This arrangement would cause TestNG to pick a row of data from your data provider, feed it to the constructor to instantiate your test class and after that, your @Test methods can basically work with the data that was injected into it via the constructor. So for every row of data that your data provider gives, a test class instance is created. That is the only way in which you can achieve what you are looking for.

这是一个示例:

import static org.testng.Assert.assertTrue;

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

import java.util.HashMap;
import java.util.Map;

public class SampleTestClass {
    private String name;
    private int age;
    private Map<String, Integer> marks;

    @Factory(dataProvider = "getData")
    public SampleTestClass(String name, int age, Map<String, Integer> marks) {
        this.name = name;
        this.age = age;
        this.marks = marks;
    }

    @DataProvider(name = "getData")
    public static Object[][] testData() {
        return new Object[][]{
                {"Amar", 16, marksInSubjects(45, 55, 65)},
                {"Akbar", 16, marksInSubjects(55, 65, 75)},
                {"Antony", 16, marksInSubjects(35, 45, 55)},
        };
    }

    @Test
    public void testName() {
        assertTrue(name != null && !name.trim().isEmpty(), "Should have received a valid name");
    }

    @Test
    public void testAge() {
        assertTrue(age > 0 && age < 30, "Should have received a valid age.");
    }

    @Test(dataProvider = "marks")
    public void testMarks(String subject, int marks) {
        boolean validSubject = subject != null && !"sports".equalsIgnoreCase(subject.trim());
        assertTrue(validSubject, "Should have received a valid subject");
        assertTrue(marks >= 40, this.name + " didn't pass in " + subject);
    }

    @DataProvider(name = "marks")
    public Object[][] getMarks() {
        Object[][] marks = new Object[this.marks.size()][1];
        int index = 0;
        for (Map.Entry<String, Integer> mark : this.marks.entrySet()) {
            marks[index++] = new Object[]{mark.getKey(), mark.getValue()};
        }
        return marks;
    }

    private static Map<String, Integer> marksInSubjects(int m1, int m2, int m3) {
        Map<String, Integer> marks = new HashMap<>();
        marks.put("english", m1);
        marks.put("science", m2);
        marks.put("mathematics", m3);
        return marks;
    }
}

这篇关于如何使用来自excel文件的不同测试数据集在testng中运行多个测试用例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 02:15