我如何将多个二维数组的测试数据构建到一个属性文件中并读取它们用于我的测试?

How can I structure multiple 2D arrays of test data into a properties file and read them for my tests?

我需要将所有测试数据保存到 properties 文件或 JSON 文件中(因为它们比 XML 更容易阅读)。我正在考虑使用单个属性文件来存储整个项目的数据。不确定这是否可行。

我正在使用 TestNG 测试框架及其 @DataProvider 注释来标记将 return 二维数组的函数。这是一个示例:

/*
* This returns 2 parameters for each test execution
*/
@DataProvider(name = "info on cars")
public Object[][]  testDataOnCars(){

   return new Object[][]{
      {"Mercedes as key", "Value with any special char ~!@#$%^&*()_'\",./<>?+"}, {"Jaguar", "<>?,./;':\"[]\{}|~!@#$%^&*()_+`"}
      }

}

相应的测试可能如下所示:

@Test(dataprovider = "info on cars")
public void testAllCars(String carName, String carDetails){
   
   // Do something with carName and carDetails

}

对于不同的数据集,某些测试可能需要不同数量的参数。例如:

/*
* This returns 4 parameters for each test execution
*/
@DataProvider(name = "info on bank statements")
public Object[][]  testDataOnBankStatements(){

   return new Object[][]{
      {"Credit card payment", "200", "debit", "5th May, 2022"},
      {"Salary credit", "5200", "credit", "5th May, 2022"},
      }

}

这可能会被带有 4 个参数的测试函数消耗:

@Test(dataprovider = "info on bank statements")
public void testAllCars(String description, Integer amount, String debitOrCredit, String date){
   
   // Do something with the 4 params

}

有谁知道:

  1. 如何将测试数据组织到一个文件中?拥有属性文件或 JSON 文件或其他类型的文件更好吗?它是一个包含许多参数的二维数组。
  2. 是否建议将不同的测试数据存储到同一个属性文件中?或者我应该为每种测试数据创建一个单独的文件(比如 1 个文件用于银行资料 - 5 个参数,另一个文件用于旅行资料 - 3 个参数等)。
  3. 如何从文件中读取这种结构化数据并将它们作为 Object[][] 的二维数组传递?

假设您有 src/test/resources/test_data.json 个看起来像

的文件
{
  "infoOnCars": [
    ["Mercedes as key", "Value with any special char ~!@#$%^&*()_'\\",./<>?+"],
    ["Jaguar", "<>?,./;':\\"[]\{}|~!@#$%^&*()_+`"]
  ],
  "infoOnBankStatements": [
    ["Credit card payment", "200", "debit", "5th May, 2022"],
    ["Salary credit", "5200", "credit", "5th May, 2022"]
  ]
}

然后你可以在你的项目中添加org.json依赖,实现如下:

public class DataProviderTest {

  private JSONObject jsonObject;

  private JSONObject getJsonObject() throws URISyntaxException, IOException {
    if(jsonObject == null){
       jsonObject = new JSONObject(
          Files.readString(Paths.get(DataProviderTest.class.getClassLoader().getResource("test_data.json").toURI()))
            );
        }
        return jsonObject;
    }

    @DataProvider(name = "cars")
    Iterator<Object[]> getCars() throws URISyntaxException, IOException {
        return getIterator(getJsonObject(), "infoOnCars");
    }

    @DataProvider(name = "banks")
    Iterator<Object[]> getBanks() throws URISyntaxException, IOException {
        return getIterator(getJsonObject(), "infoOnBankStatements");
    }

    Iterator<Object[]> getIterator(JSONObject jsonObject, String key){
        Map<String, Object> map = jsonObject.toMap();
        Object val = map.get(key);
        if(val instanceof ArrayList){
            Iterator<ArrayList> valArray = ((ArrayList) val).iterator();
            return new Iterator<>() {
                @Override
                public boolean hasNext() {
                    return valArray.hasNext();
                }

                @Override
                public Object[] next() {
                    return valArray.next().toArray();
                }
            };
        }
        return null;
    }

    @Test(dataProvider = "cars")
    public void test1(String carName, String carDetails){
        System.out.println(">>>> Cars test started");
        System.out.println("Car name: " + carName);
        System.out.println("Car details: " + carDetails);
    }

    @Test(dataProvider = "banks")
    public void test2(String description, String amount, String debitOrCredit, String date){
        System.out.println(">>>> Bank test started");
        System.out.println("Description: " + description);
        System.out.println("Amount: " + amount);
        System.out.println("Debit / Credit: " + debitOrCredit);
        System.out.println("Date: " + date);
    }
}

它将所有数据解析为字符串。这样您就需要进行一些转换才能将数字用作数字。