Написание класса провайдера данных, принимающего Hashmap как коллекцию и передающего его для нескольких параметров в API Test - PullRequest
2 голосов
/ 03 июня 2019

Я пытаюсь минимизировать строку кода в моих тестах, написав повторно используемый компонент в форме TestNG DataProvider. Моя тестовая спецификация, которую нужно отправить на сервер, принимает карту>.

 @Test(dataProvider = "provideData")
 public void TestMethod(Map<String,Object> map) throws Exception {
RequestSpecification spec = generateCommonReqSpecJsonWithQueryParams(map);
Response res = RestOperationUtils.get(url, spec, null);
}


@DataProvider(name="provideData")
    public static Object[][] getData() throws Exception {
        Map<String, ArrayList<String>> map = new HashMap<>();
        ArrayList<String> a1 = new ArrayList<>();
        a1.add("First Value");
        a1.add("Second Value);
        a1.add("Third Value");
        a1.add("Fourth Value");
        map.put("Test[]", a1);
        map.put("month_start", new ArrayList(Arrays.asList("2019-06-01")));
        map.put("month_end", new ArrayList(Arrays.asList("2019-06-30")));
        map.put("viewers[]", new ArrayList(Arrays.asList("ESPN")));
        ArrayList<String> b1 = new ArrayList<>();
        b1.add("Fifth Value");
        b1.add("Sixth Value");
        b1.add("Seventh Value");
        map.put("Result[]", b1);

Начиная с TestNG, мы обязуемся вернуть Object [] [] из DataProvider, вот разные подходы, которые я пробовал:

Подход 1:

String[] keys = new String[map.size()];
        ArrayList<ArrayList<String>> values = new ArrayList<>();
        int index = 0;
        for (Map.Entry<String, ArrayList<String>> mapEntry : map.entrySet()) {
            keys[index] = mapEntry.getKey();
            values.add(index, (ArrayList<String>) mapEntry.getValue());
            //   x[index] = mapEntry.getValue();
            index++;
        }
        Object[][] result = new Object[values.size()][];
        index = 0;
        int index2;
        for (List<String> list : values) {
            result[index] = new Object[list.size()];
            index2 = 0;
            for (String item : list) {
                result[index][index2] = item;
                index2++;
            }
            index++;
        }
return result ;

Подход 2:

     Object[][] arr = new Object[map.size()][2];
        Set entries = map.entrySet();
        Iterator entriesIterator = entries.iterator();
        int i = 0;
        while(entriesIterator.hasNext()){
            Map.Entry mapping = (Map.Entry) entriesIterator.next();
            arr[i][0] = mapping.getKey();
            arr[i][1] = mapping.getValue();
            i++;
        }
        return arr;

Подход 3:

Просто верните следующее:

return new Object[][] {{map}};

Подход 1: Используя подход 1, он дает 5 ожидаемых параметров, но так как мне нужно передать map в моей спецификации как queryParameters, мне трудно использовать его в моем методе Test для чтения их из класса DataProvider.

Подход 2: Он возвращает мне 2 параметра, а с Map<String,Object> map в качестве параметра он принимает только 1.

Подход 3: Я не понял, почему / как это работает, но после отладки обнаружил, что это ожидается как особый случай для библиотеки TestNg, иначе нам нужно использовать подход 1/2 для преобразования hashmap в Object [] [].

Пожалуйста, дайте мне знать, если какая-либо другая информация требуется в этом запросе.

1 Ответ

0 голосов
/ 11 июня 2019

Подход 3 кажется мне вполне уместным. Объект [] [] - это просто способ хранения всех тестовых случаев, где каждый индекс объекта [] будет просто тестовым примером. Каждый тестовый пример должен соответствовать количеству и типу аргументов, ожидаемых методом теста.

Object [] [] выбран для хранения тестовых случаев, поскольку все объекты в java либо расширяются от Object, либо в случае примитивов могут быть автоматически упакованы в его объектную форму, которая расширяется от Object.

TestNG затем будет обрабатывать подключение поставщика данных к каждому из своих тестов, а также применять и приводить параметры тестового примера для каждого.

Например:

@Test(dataProvider="getTestCases")
public void test(List<Integer> list, double d){
    // test code
}

Ожидается что-то вроде:

@DataProvider
public Object[][] getTestCases(){
    return new Object[][] {
        {Arrays.asList(1, 2, 3), 1.0},
        {Arrays.asList(4, 5, 6), 2.0}
    };
}

Где {Arrays.asList (1, 2, 3), 1.0} будет тестовый пример 1, а {Arrays.asList (4, 5, 6), 2.0} будет тестовый случай 2.

EDIT:

Чтобы решить проблему изменения кода для очистки поставщика данных, Хольгер представил следующее:

@DataProvider(name="provideData")
public static Object[][] getData() {
    Map<String, List<String>> map = new HashMap<>();
    map.put("Test[]", Arrays.asList("First Value", "Second Value", "Third Value", "Fourth Value"));
    map.put("month_start", Arrays.asList("2019-06-01"));
    map.put("month_end", Arrays.asList("2019-06-30"));
    map.put("viewers[]", Arrays.asList("ESPN"));
    map.put("Result[]", Arrays.asList("Fifth Value", "Sixth Value", "Seventh Value"));
    return new Object[][]{{map}};
}

Что касается причины, по которой подходы 1 и 2 не работают для вас, это связано с несоответствием типа DataProvider / количества возвращенных тестовых случаев. Ваш тест ожидает, что ему будет предоставлена ​​карта

public void TestMethod(Map<String,Object> map) 

, который ожидает один параметр типа Map<String,Object> от поставщика данных, однако вы пытаетесь передать строку и строки переменного размера для подхода 1 или строку и список строк для подхода 2. Оба из которых имеют разные типы и количество параметров, чем одна карта.

Я бы рекомендовал изменить тест, чтобы он принимал Map<String, List<String>> для обеспечения большей ясности в тесте, если только последний не является тем, что требуется для самой функции, которая тестируется.

В тестировании предпочтение отдается простоте, потому что если вы добавите слишком много сложности к самому тесту. Тест может стать более подверженным ошибкам, чем тестируемый объект. Таким образом, простого возврата карты должно быть достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...