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

Фотография

Параметризация @BeforeMethod из файла

testng parameterized DDT dataprovider java

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

#1 cpmBugHunter

cpmBugHunter

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

  • Members
  • Pip
  • 45 сообщений
  • ФИО:Евгений
  • Город:Ростов-на-Дону


Отправлено 22 декабря 2016 - 19:46

Приветствую, уважаемые форумчане!

Прошу знающих коллег направить меня на путь истинный. Задача такова(Java, TestNG, Maven):

1. Отправляем HTTP запрос на сервер, получаем ответ, парсим в объект класса.

2. В тестах сравниваем значения определенных параметров с ожидаемыми.

 

Думаю, логично было бы запрос и парсинг делать в @BeforeMethod, а сравнение в тестах. Но проблема в том, что запросы надо отсылать с разными параметрами каждый раз. И значений одного параметра может быть много. Тут, наверное, стоит привести пример... Файл с данными может выглядеть примерно так:

Parameter1: value1-1, value1-2, value1-3...value1-N

Parameter2: value2-1, value2-2

Parameter3: value3-1, value3-2, value3-3

......................................................................

Parameter250: value250-1, value250-2, value250-3...value250-M

 

т.е. количество значений может быть разным.

Но, конечно, можно в одну строку прописать все нужные параметры для одного теста... И тогда будет как-то так:

 

Parameters[0]: value1, value2, value3...valueN

Parameters[1]: value1, value2, value3...valueN

Parameters[2]: value1, value2, value3...valueN

 

и тогда запросы будут выглядеть примерно как-то так:

@BeforeMethod
public void setUp(){
    String url = Helper.composeRequestUrl(value1, value2);
    String body = Helper.composeRequestBody(value3, value4, value5, value6, value7);
    MyClass response = Helper.getResponse(url, body, value8, value9)
}

@Test
public void testName(){
    Assert.That(response.someFeild==value10);
}

Собственно вопрос состоит в том, как скормить @BeforeMethod'у и @Test'у файлик со значениями параметров(csv, XML, .property). И чтобы прогонов теста было столько, сколько строк в файле.

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

Помогите, пожалуйста. Хоть намекните, как это реализовать и по каким ключевым словам гуглить. Если будут примеры - буду безмерно благодарен.

 

 

 


  • 0

#2 Sheffsky

Sheffsky

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

  • Members
  • Pip
  • 8 сообщений

Отправлено 23 декабря 2016 - 10:40

DataProvider тут не поможет?


  • 1

#3 cpmBugHunter

cpmBugHunter

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

  • Members
  • Pip
  • 45 сообщений
  • ФИО:Евгений
  • Город:Ростов-на-Дону


Отправлено 23 декабря 2016 - 13:09

DataProvider тут не поможет?

Возможно, поможет. Просто сколько встречал примеров по использованию этой нотации, везде реализуется примерно так:

@DataProvider
  public Object[][] parseLocaleData() {
    return new Object[][]{
      {null, null},
      {"", LocaleUtils.ROOT_LOCALE},
      {"en", Locale.ENGLISH},
      {"en_US", Locale.US},
      {"en_GB", Locale.UK},
      {"ru", new Locale("ru")},
      {"ru_RU_some_variant", new Locale("ru", "RU", "some_variant")},
    };
  } 

Т.е. опять же в коде жестко прописывается. А я хочу, чтобы тестовые данные читались из файла, который сможет изменить абсолютно любой член команды в случае необходимости

Если кто знает, как заставить DataProvider подавать данные из файла, поделитесь пожалуйста секретом


  • 0

#4 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 23 декабря 2016 - 13:49

Если кто знает, как заставить DataProvider подавать данные из файла, поделитесь пожалуйста секретом

 

 

Нет тут секрета, просто ты должен использовать Iterator<String[]>

public static final String PATH_TO_DATA_FILES = "src/test/resources/";
	
	@Test(dataProvider = "loadUserDataFromFile")
	public void dpWithTXT(String... user) throws InterruptedException {
		System.out.println("Количество пользователей " + user.length);
		System.out.println(user[0] + " :  " + user[1] + ":" + user[2]);

	}

	

	@DataProvider
	public Iterator<String[]> loadUserDataFromFile() throws IOException {
		List<String[]> userData = new ArrayList<>();
		try (Scanner text = new Scanner(new File(PATH_TO_DATA_FILES + "user.data"))) {
			int i = 0;
			while (text.hasNext()) {
				i++;

				String print = text.nextLine();

				if (i > 1) {
					userData.add(print.split(";"));
				}
			}
		}
		return userData.iterator();
	}

Ну и содержание файла user.data

 

Login;Password;Age
admin1;passAadmin1;21
user1;passUser1;22
guest1;passGuest1;18

 

Ну и вывод на консоль:

Количество пользователей 3
admin1 :  passAadmin1:21
Количество пользователей 3
user1 :  passUser1:22
Количество пользователей 3
guest1 :  passGuest1:18


  • 1

#5 cpmBugHunter

cpmBugHunter

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

  • Members
  • Pip
  • 45 сообщений
  • ФИО:Евгений
  • Город:Ростов-на-Дону


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

 

Если кто знает, как заставить DataProvider подавать данные из файла, поделитесь пожалуйста секретом

 

 

Нет тут секрета, просто ты должен использовать Iterator<String[]>

public static final String PATH_TO_DATA_FILES = "src/test/resources/";
	
	@Test(dataProvider = "loadUserDataFromFile")
	public void dpWithTXT(String... user) throws InterruptedException {
		System.out.println("Количество пользователей " + user.length);
		System.out.println(user[0] + " :  " + user[1] + ":" + user[2]);

	}

	

	@DataProvider
	public Iterator<String[]> loadUserDataFromFile() throws IOException {
		List<String[]> userData = new ArrayList<>();
		try (Scanner text = new Scanner(new File(PATH_TO_DATA_FILES + "user.data"))) {
			int i = 0;
			while (text.hasNext()) {
				i++;

				String print = text.nextLine();

				if (i > 1) {
					userData.add(print.split(";"));
				}
			}
		}
		return userData.iterator();
	}

Ну и содержание файла user.data

 

Login;Password;Age
admin1;passAadmin1;21
user1;passUser1;22
guest1;passGuest1;18

 

Ну и вывод на консоль:

Количество пользователей 3
admin1 :  passAadmin1:21
Количество пользователей 3
user1 :  passUser1:22
Количество пользователей 3
guest1 :  passGuest1:18

 

Виктор, спасибо за код, очень поможет в будущем. Однако, у меня задача стоит немного в другом: как запихнуть строку из файла в метод BeforeMethod, а не в тест. Т.е. я спрашивал, можно ли как-то написать примерно такой код:

public class Tests extends MyBaseClass{
    public static final String PATH_TO_DATA_FILES = "src/test/resources/";

    @BeforeMethod(dataProvider = "loadUserDataFromFile")
    public void setUp(){
        actual = user[0];
        expected = user[1];
    }

    @Test(dataProvider = "loadUserDataFromFile")
    public void dpWithTXT(String... user) throws InterruptedException {
        Assert.assertEquals(actual, expected);
    }

    @DataProvider
    public Iterator<Object[]> loadUserDataFromFile() throws IOException {
        List<Object[]> testData = new ArrayList<>();
        try (Scanner text = new Scanner(new File(PATH_TO_DATA_FILES + "user.data"))) {
            int i = 0;
            while (text.hasNext()) {
                i++;

                String print = text.nextLine();

                if (i > 1) {
                    testData.add(print.split(";"));
                }
            }
        }
        return testData.iterator();
    }
}

class MyBaseClass {
    public String actual;
    public String expected;
}

Ну и текст файла user.data
Actual;Expected
admin1;admin1
admin2;admin2
admin3;admin5
admin4;admin4

 

Чтобы в BeforeMethod бралась первая строка файла, устанавливалось значение actual, а в тесте всё из той же первой строки бралось значение expected и они сравнивались между собой.

Второй тест - вторая строка, третий - третья и т.д.


  • 0

#6 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 26 декабря 2016 - 11:05

может имеется ввиду Dependency Injection? Можно установить контекст в Before и потом считать его в тесте

http://testng.org/do...dency-injection

 

пример:

http://www.programcr...ng.ITestContext


  • 1

#7 user12

user12

    Специалист

  • Members
  • PipPipPipPipPip
  • 894 сообщений
  • ФИО:Виктор
  • Город:Минск


Отправлено 26 декабря 2016 - 12:30

В @BeforeMethod хз как запихнуть DataProvider, м.б. сделай не BeforeMethod, а два теста идущих следом друг за другом


  • 0

#8 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 26 декабря 2016 - 12:32

Напишите ручной тест тут, чтобы было понятно какие данные где

И мы его тут же автоматизируем как надо
  • 0

#9 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 26 декабря 2016 - 12:34

BeforeMethod - это для сетапа. Если пробуем туда запихнуть Дата Провайдер, значит что-то делаем не так
  • 0

#10 cpmBugHunter

cpmBugHunter

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

  • Members
  • Pip
  • 45 сообщений
  • ФИО:Евгений
  • Город:Ростов-на-Дону


Отправлено 26 декабря 2016 - 15:11

BeforeMethod - это для сетапа. Если пробуем туда запихнуть Дата Провайдер, значит что-то делаем не так

Мне нужно:

1. Отправить запрос на сервер перед каждым тестом. Потому собственно и пихаю метод отправки в BeforeMethod. Дабы не копипастить один и тот же код по разным тестам. НО! Запрос каждый раз должен быть с РАЗНЫМИ параметрами. Не все и не всегда генерятся в коде. Какие-то вымучиваются в ходе тест дизайна (с применением граничных значений и всё такое). Поэтому, хочу создать файлик, из которого перед каждым тестом читать параметры для запроса. Выше советовали юзать DataProvider. Потому и пробую запихнуть...


  • 0

#11 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 26 декабря 2016 - 18:26

может так

1. сам ЗАПРОС (3 строки из первого поста) описываем в хелпер-методе, запрос принимает параметры

2. ПАРАМЕТРЫ кладём в дата-провайдер

3. тест вызывает ЗАПРОС из хелпер-метода и передаёт туда параметры, которые он получил из дата-провайдера (это одна строка кода)

4. тест делает проверки, используя expected данные, которые он получил от того же дата-провайдера

 

вроде так по теории...


  • 1

#12 cpmBugHunter

cpmBugHunter

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

  • Members
  • Pip
  • 45 сообщений
  • ФИО:Евгений
  • Город:Ростов-на-Дону


Отправлено 26 декабря 2016 - 22:04

Осознал свою вину: меру, степень, глубину...

В общем, делать как написал изначально - всё из теста и не выделываться со всякими там улучшениями через Before. Будем считать, решили.

Тогда, может, в продолжение темы коллеги поделятся опытом и соображениями о том, в каком файле лучше/удобнее хранить тестовые данные?

Ну хотя бы с точки зрения удобства их изъятия (как говорят - "это одна строка кода"). Ну там, из csv строки доставать и сплитить это воооот столько кода, а из XML - всего вот столечко. Может, либы какие уже готовые кто использует? Ну эт чтобы я не пытался городить MyOwnBycicle


  • 0

#13 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 26 декабря 2016 - 22:11

Я бы хранил в JSON файле, который бы лежал в том же проекте в разделе resources, конечно под Гитом как и весь проект. Кому надо менять - пусть через Гит и меняют тот джейсон.

Парсил бы используя стандартные библиотеки, хотя не - даже лучше наверное сериализовать/десериализовать(читай: конвертировать) JSON прямиком в Java объекты например в POJO с помощью Jackson или как там его

Пысы:
CSV это бардак, XML уже устаревший формат - JSON это его "новая жизнь"
  • 1

#14 Spock

Spock

    Профессионал

  • Members
  • PipPipPipPipPipPip
  • 1 772 сообщений
  • ФИО:Роман

Отправлено 27 декабря 2016 - 09:19

ещё генерируем JSON схему и всегда при загрузке проводим валидацию JSON файла с данными

+ в джейсон схеме для каждых properties добавляем "additionalProperties": false

 

так обеспечиваем правильность файла: что структура не сломана, и что все элементы добавлены в "правильные" места

 

разработчикам "тестовых данных" даём средство провалидировать их джейсон против схемы (и конечно менять схему тоже)


  • 1

#15 cpmBugHunter

cpmBugHunter

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

  • Members
  • Pip
  • 45 сообщений
  • ФИО:Евгений
  • Город:Ростов-на-Дону


Отправлено 28 декабря 2016 - 08:28

Благодарю за полезную информацию, код и пищу для размышлений!


  • 0



Темы с аналогичным тегами testng, parameterized, DDT, dataprovider, java

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

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