简体   繁体   English

TestNG Dataprovider需要帮助以根据测试数据单独运行@Test

[英]TestNG Dataprovider Need help to run @Test individually based on test data

I'm working on Rest API testing (POST method) for which I'm reading json data from spreadsheet using TestNg Dataprovider. 我正在进行Rest API测试(POST方法),正在使用TestNg Dataprovider从电子表格读取json数据。 My Dataprovider returns HashMap with key: Integer Row_Number and value: ArrayList (String) of test data. 我的Dataprovider返回HashMap,其键为:测试数据的整数Row_Number和值:ArrayList(字符串)。 Below is the sample map returned by DataProvider. 以下是DataProvider返回的示例地图。 {0=[Sample1, Name1, sample1.name1@example.com, (000) 111-1111], 1=[Sample2, Name2, sample2.name2@example.com, (000) 111-1112]} {0 = [Sample1,Name1,sample1.name1@example.com,(000)111-1111],1 = [Sample2,Name2,sample2.name2@example.com,(000)111-1112]}

My current implementation of Dataprovider is, 我目前对Dataprovider的实现是

@DataProvider
public Object[][] JSONBODY()
{
String test_data = "json_data";
int row = ExcelUtils.getRowNum(test_data, col_num);
int total_col = ExcelUtils.getLastColumnNumber(row);
Map<Integer, ArrayList<String>> map = ExcelUtils.getTableArray(spreadsheet_location,test_data,total_col);
return new Object[][] { { map } };
}

getTableArray implementation getTableArray实现

public static Map<Integer, ArrayList<String>> getTableArray(String FilePath, String testdata, int total_Col) throws Exception {
Map<Integer, ArrayList<String>> map = new HashMap<Integer, ArrayList<String>>();
ArrayList<Integer> iTestCaseRow = null;
try
{
    FileInputStream ExcelFile = new FileInputStream(FilePath);
    ExcelWBook = new XSSFWorkbook(ExcelFile);
    ExcelWSheet = ExcelWBook.getSheet(SheetName);
    int startCol = 1;
    iTestCaseRow = ExcelUtils.getRowContains(testdata ,col_num); // getRowContains returns list of row numbers for value in testdata.
    int totalRows = iTestCaseRow.size();
    int totalCols = total_Col;
    for(int i=0; i<totalRows;i++)
    {
        ArrayList<String> str = new ArrayList<String>();
        for (int j=startCol;j<=totalCols;j++)
        {
            str.add (ExcelUtils.getCellData(iTestCaseRow.get(i),j));  
        }
        map.put(iTestCaseRow.get(i), str);
    }
    return map;
}
}

Test Method 测试方法

@Test(dataProvider = "JSONBODY")
public void TestMethod(Map<Integer, ArrayList<String>> map) throws Exception {
try
{
Log.startTestCase("Start executing Test Case");
Set<Integer> key = map.keySet();
for(Integer row: key)
{
    SamplePojo pojo = new SamplePojo();
    ArrayList<String> data = map.get(row);
    pojo.setFirstName(data.get(0));
    pojo.setLastName(data.get(1));
    pojo.setEmail(data.get(2));
    pojo.setPhone(data.get(3));
    Response res = RestAssured.given().contentType(ContentType).body(pojo).when().post(POST_URL);
    Log.info(res.asString());
    Assert.assertTrue(res.getStatusCode() == 200 , "Test Case failed");
}
}
}

Spreadsheet Test Data is, Spreadsheet Data 电子表格测试数据为, 电子表格数据

When I execute my @Test method, TestNG executes as one method instead of two as I have 2 rows of test data(value: json_data) in the spreadsheet. 当我执行@Test方法时,TestNG作为一种方法而不是两种方法执行,因为我在电子表格中有两行测试数据(值:json_data)。 Kindly help me in running the Test method individually for each key:value pair. 请帮助我为每个key:value对分别运行Test方法。 Thanks in advance! 提前致谢!

The problem is in your data provider. 问题出在您的数据提供者中。 After you obtain your map, you need to translate that map such that every entry in it is now part of the 2D Object array. 获取地图后,您需要转换该地图,以使其中的每个条目现在成为2D对象数组的一部分。 In your case, you have basically just added that entire map as one single data item in the 2D object array. 就您而言,您基本上只是将整个地图添加为2D对象数组中的单个数据项。

Please see below for a full fledged example that shows what I am referring to. 请参阅下面的完整示例,其中显示了我所指的内容。 For the sake of convenience I have basically excluded the excel spreadsheet reading logic etc., 为了方便起见,我基本上排除了Excel电子表格的读取逻辑等,

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

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestClass {

    @Test(dataProvider = "dp")
    public void testMethod(Map<Integer, List<String>> data) {
        Assert.assertTrue(data.size() == 1);
        List<String> values = data.values().iterator().next();
        System.err.println("Values = " + values);
    }


    @DataProvider(name = "dp")
    public Object[][] getData() {
        Map<Integer, List<String>> data = getTableArray();
        //Transform the Map into a 2D array such that every key/value
        //pair in the map becomes one element in the 2D array
        int size = data.size();
        Object[][] dataToUse = new Object[size][1];
        int i = 0;
        for (Map.Entry<Integer, List<String>> entry : data.entrySet()) {
            Map<Integer, List<String>> localMap = new HashMap<>();
            localMap.put(entry.getKey(), entry.getValue());
            dataToUse[i++] = new Object[]{localMap};
        }
        return dataToUse;
    }

    static Map<Integer, List<String>> getTableArray() {
        Map<Integer, List<String>> data = new HashMap<>();
        data.put(1, Arrays.asList("Sample1", "Name1", "sample1.name1@gmail.com", "(000) 111-1111"));
        data.put(2, Arrays.asList("Sample2", "Name2", "sample2.name2@gmail.com", "(000) 111-1112"));
        data.put(3, Arrays.asList("Sample3", "Name3", "sample3.name3@gmail.com", "(000) 111-1113"));
        return data;
    }
}

Here's the output 这是输出

Values = [Sample1, Name1, sample1.name1@gmail.com, (000) 111-1111]
Values = [Sample2, Name2, sample2.name2@gmail.com, (000) 111-1112]
Values = [Sample3, Name3, sample3.name3@gmail.com, (000) 111-1113]

===============================================
Default Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================

Two options: 两种选择:

Map<Integer, ArrayList<String>> map = ExcelUtils.getTableArray(spreadsheet_location,test_data,total_col);

Object[][] dataToBeReturned = new Object[map.size()][];

//Loop through map and build your array..code not tested..something to the effect
for(Entry<Integer, Arra..> datum : map.entrySet()) {
 dataToBeReturned[i++] = new Object[] {datum.getKey(), datum.getValue()}
}

return dataToBeReturned;

or in your excelreader itself, since you are in any case looping through the data, either put it in an array instead of map - something like 或在excelreader本身中,因为无论如何都要遍历数据,因此可以将其放入数组而不是映射中-类似于

    instead of map.put(iTestCaseRow.get(i), str);
use dataToBeReturned[i++] = new Object[] {iTestCaseRow.get(i), str}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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