Перейти к содержимому

Фотография

Не могу использовать списки с параметризацией в JUnit4

webdriver java junit selenium

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 9

#1 Azur

Azur

    Новый участник

  • Members
  • Pip
  • 54 сообщений
  • ФИО:Александр Згнетов
  • Город:Омск

Отправлено 28 декабря 2018 - 10:26

Добрый день. Пытаюсь сделать параметризированные тесты на Webdriver 3 / JUnit4, пока локально в Idea. Начинаю с простого, обход по ссылкам, которые предварительно собраны в виде URL в простой список. Этот список я не могу использовать в качестве параметра. Насколько я понимаю, параметрами могут выступать только объекты.

 

Например я могу объявить объект заранее

Object[] testvalues = new Object[]{"google.com","ya.ru","twitter.com"};

И тогда в тесте он отработает правильно

@RunWith(Parameterized.class)
public class TestParam {

@Parameterized.Parameter
public String domainName;

@Parameterized.Parameters(name = "{index}:TestOf {0}")
public static Object[] data() {
return testvalues;
}

@Test
public void paramTest() {
System.out.println(domainName);
}

}

Фокусы начинаются когда я пытаюсь использовать список ссылок.

1. Я могу сделать объект через toArray()

2. Я могу сделать объект через stream().toArray(n -> new String[n])

3. Я могу сделать объект через stream().toArray(String[]::new)

4. Я не могу добавлять ссылки сразу в объект, потому что он имеет фиксированный размер

 

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


  • 0

#2 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 28 декабря 2018 - 16:10

@azur если я правильно понял вы хотите параметры в аннотациях заполнять динамически . это здоровое желание but  похоже идет completely вразрез с первоосновами  (и в testng тоже)...

 

попробуйте держать в файле  - я когда то такие провайдеры написал - 

https://github.com/s...t-dataproviders


  • 0

#3 Azur

Azur

    Новый участник

  • Members
  • Pip
  • 54 сообщений
  • ФИО:Александр Згнетов
  • Город:Омск

Отправлено 04 января 2019 - 07:17

похоже идет completely вразрез с первоосновами  (и в testng тоже)

 

 

С удовольствием почитаю почему параметризация идет вразрез с первоосновами. Серьезно, я в java не настолько разбираюсь, чтобы понимать даже очевидные для многих вещи. Я понимаю, что использование юнит-фреймворка в функциональном тестировании это всегда компромиссы. Еще я понимаю, что TestNG в этом аспекте лучше, но в данный момент мне хочется реализовать параметризацию в Junit.

 

попробуйте держать в файле

Я уже думал об этом. Но ссылки, составляющие список параметров теста, могут меняться между прогонами, поэтому придется их записывать в файл заблаговременно. А в Junit нет четкого порядка выполнения тестов. Да и зависимости между тестами не комильфо. В крайнем случае будет использоваться старый список, который обновится в произвольном порядке между другими проверками, а значит для полной проверки тест придется запускать 2 раза. Этот вариант я оставил на потом.

 

Тем не менее, я все же нашел причину. Упростил до итератора:

@Parameterized.Parameters(name = "{index}:TestOf {0}")
public static Iterable data() {
return testvalues;
}

Теперь testvalues это простой список. Но именно при работе со списком появилась другая странность. Тест с параметрами выполняется только по значениям, которые я инициализирую в самом начале тестового класса, если я список пополняю, то новые значения игнорируются. Вот как это выглядит:

List<String> testvalues = new ArrayList<String>(Arrays.asList("google.com","ya.ru","twitter.com"));
@BeforeClass
public static void setup() throws Exception {
...
testvalues.add("link1.ru");
testvalues.add("link2.ru");
testvalues.add("link3.ru");
...
}

В @Test я среди прочего вывожу в консоль testvalues, чтобы убедиться, что новые значения добавились в список. Но параметры теста их игнорируют, только 3 первоначальных значения используются, 3 теста запускается. Сам @BeforeClass работает правильно, ведь там инициализируется драйвер и прочее, а порядок легко проверить. Я не понимаю в чем дело, я не нашел ни в одном мануале по JUnit даже намека на происходящее.


  • 0

#4 Alex

Alex

    Постоянный участник

  • Members
  • PipPipPip
  • 237 сообщений
  • ФИО:Алексей

Отправлено 04 января 2019 - 08:19

 

похоже идет completely вразрез с первоосновами  (и в testng тоже)

 

 

С удовольствием почитаю почему параметризация идет вразрез с первоосновами. Серьезно, я в java не настолько разбираюсь, чтобы понимать даже очевидные для многих вещи. Я понимаю, что использование юнит-фреймворка в функциональном тестировании это всегда компромиссы. Еще я понимаю, что TestNG в этом аспекте лучше, но в данный момент мне хочется реализовать параметризацию в Junit.

 

попробуйте держать в файле

Я уже думал об этом. Но ссылки, составляющие список параметров теста, могут меняться между прогонами, поэтому придется их записывать в файл заблаговременно. А в Junit нет четкого порядка выполнения тестов. Да и зависимости между тестами не комильфо. В крайнем случае будет использоваться старый список, который обновится в произвольном порядке между другими проверками, а значит для полной проверки тест придется запускать 2 раза. Этот вариант я оставил на потом.

 

Тем не менее, я все же нашел причину. Упростил до итератора:

@Parameterized.Parameters(name = "{index}:TestOf {0}")
public static Iterable data() {
return testvalues;
}

Теперь testvalues это простой список. Но именно при работе со списком появилась другая странность. Тест с параметрами выполняется только по значениям, которые я инициализирую в самом начале тестового класса, если я список пополняю, то новые значения игнорируются. Вот как это выглядит:

List<String> testvalues = new ArrayList<String>(Arrays.asList("google.com","ya.ru","twitter.com"));
@BeforeClass
public static void setup() throws Exception {
...
testvalues.add("link1.ru");
testvalues.add("link2.ru");
testvalues.add("link3.ru");
...
}

В @Test я среди прочего вывожу в консоль testvalues, чтобы убедиться, что новые значения добавились в список. Но параметры теста их игнорируют, только 3 первоначальных значения используются, 3 теста запускается. Сам @BeforeClass работает правильно, ведь там инициализируется драйвер и прочее, а порядок легко проверить. Я не понимаю в чем дело, я не нашел ни в одном мануале по JUnit даже намека на происходящее.

 

Это не является проблемой testng или junit. Это специфика работы аннотаций в java. Чтобы делать то, что вы хотите надо смотреть варианты каких-нибудь инжекторов или трансформеров. И то не уверен, что это прокатит именно с аннотациями

 

В testng есть dataprovider для таких целей, который может возвращать итератор (соответственно там дополнять коллекцию можно чуть ли не постоянно). Как с этим в junit я не знаю.


  • 0

#5 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 04 января 2019 - 13:34

в junit тоже самое есть класс 
 

https://junit.org/ju...ameterized.html

https://github.com/junit-team/junit4/wiki/parameterized-tests

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

// Boilerplate code for straightforward JUnit test class constructor parameter injection
// public parameter properties is possible too
@RunWith(Parameterized.class)
public class StandardParamConstructorTest extends DataTest {

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] { { 1.0, "junit", 204 },
                { 2.0, "testng", 51 }, { 3.0, "spock", 28 } });
    }

    private double rowNum;
    private String keyword;
    private int count;

    // constructor injection
    public StandardParamConstructorTest(double rowNum, String keyword, int count) {
        this.rowNum = rowNum;
        this.keyword = keyword;
        this.count = count;
    }

    @Test
    // java.lang.Exception: Method test should have no parameters
    // public void test(double rowNum, String keyword,
    // double count) {
    // java.lang.IllegalArgumentException: wrong number of arguments
    public void parameterizedTest() {
        try {
            dataTest(keyword, count);
        } catch (IllegalStateException e) {
            System.err
                    .println(String.format("keyword: %s , count : %d ", keyword, count));
        }
    }
}

  • 0

#6 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 04 января 2019 - 13:52

@Azur  опишите пожауйста ситуацию где надо изменять параметры именно из  `@Before` ? 
кстати думаю file based  junit parameter project может тут как раз помочь -  
https://github.com/s...t-dataproviders


  • 0

#7 Azur

Azur

    Новый участник

  • Members
  • Pip
  • 54 сообщений
  • ФИО:Александр Згнетов
  • Город:Омск

Отправлено 06 января 2019 - 08:04

@Azur  опишите пожауйста ситуацию где надо изменять параметры именно из  `@Before`

Я изучил как раз parameterized-tests и сделал аналогично. Во всех примерах используется готовая коллекция, которая не изменяется во время теста. Мне ее нужно менять.

 

Есть список проектов и ссылки на них на нескольких страницах, пользователи добавляют новые проекты, удаляют старые, список хоть и нечасто, но меняется, я обхожу все страницы и собираю ссылки или id с них в переменную. Внутри каждого проекта нужно выполнить тестовый сценарий, это и есть параметризированный тест, где параметром выступает например id проекта. Я хотел сбор ссылок включить в @BeforeClass, чтобы получать актуальный список перед тестированием.


  • 0

#8 sergueik

sergueik

    Постоянный участник

  • Members
  • PipPipPip
  • 166 сообщений
  • ФИО:кузьмин сергей

Отправлено 06 января 2019 - 16:23

@Azur

воспроизвел проблему  - изменения в test param data  сделанные  что из @Test что из @Before не приводят к выполнению дополнительных тестов @RunWith(Parameterized.class)

 

что тут можно посоветовать - делайте итератор вокруг этого специального indtended-to-be-flexible теста руками и не рассчитывайте не Junit
или выделяйте в отдельный класс чтобы все модификации параметров  были сделаны до DI конструетора  или проперти


  • 0

#9 Alex

Alex

    Постоянный участник

  • Members
  • PipPipPip
  • 237 сообщений
  • ФИО:Алексей

Отправлено 08 января 2019 - 07:47

 

@Azur  опишите пожауйста ситуацию где надо изменять параметры именно из  `@Before`

Я изучил как раз parameterized-tests и сделал аналогично. Во всех примерах используется готовая коллекция, которая не изменяется во время теста. Мне ее нужно менять.

 

Есть список проектов и ссылки на них на нескольких страницах, пользователи добавляют новые проекты, удаляют старые, список хоть и нечасто, но меняется, я обхожу все страницы и собираю ссылки или id с них в переменную. Внутри каждого проекта нужно выполнить тестовый сценарий, это и есть параметризированный тест, где параметром выступает например id проекта. Я хотел сбор ссылок включить в @BeforeClass, чтобы получать актуальный список перед тестированием.

 

Ну там в примере есть вариант с public static Iterable<? extends Object> data() 

 

Использовать именно итератор вместо коллекции не помогает? По идее если чуть помучиться, то через Iterable тест может хоть сам себе параметры накидывать. Главное переопределить методы next, hasNext


  • 0

#10 Azur

Azur

    Новый участник

  • Members
  • Pip
  • 54 сообщений
  • ФИО:Александр Згнетов
  • Город:Омск

Отправлено 10 января 2019 - 06:45

делайте итератор вокруг этого специального indtended-to-be-flexible теста руками

Извините, не понял о чем речь. Расшифруйте или дайте наводки на мануалы по теме.

 

 

Главное переопределить методы next, hasNext

 

Можете показать пример?


  • 0



Темы с аналогичным тегами webdriver, java, junit, selenium

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных