вторник, 3 апреля 2012 г.

Eliminate loops in tests with @DataProvider

В слайдах «Быстрое введение в TDD от А до Я» за авторством Andrey Bibichev приводятся критерии хорошо оформленного теста (33 cлайд). Один из которых гласит, что в тесте не должно быть циклов. Эта идея меня зацепила и я решил чуть-чуть порефакторить свои функциональные тесты. Вот пример такого теста:

@Test
public void emailShouldBeValid() {
final String[] emails = new String[] {
"login",
"login@domain"
};
for (final String invalidEmail : emails) {
page.registerUser(invalidEmail);
assertThat(page)
.field("email")
.hasError(tr("ru.mystamps.web.validation.jsr303.Email.message"));
}
}
view raw WithLoop.java hosted with ❤ by GitHub

Чтобы избавиться от цикла необходимо отделить логику теста (взять адрес, попробовать зарегистрироваться, получить ошибку) от тестовых данных. Т.к. я использую TestNG, то достигнуть этого разделения мне поможет @DataProvider.

Выделяем тестовые данные в один метод, который по соглашению должен возвращать двумерный массив Object-ов. Добавляем к этому методу аннотацию @DataProvider и указываем имя для данных, которые он возвращает. В исходный тест, в аннотации @Test указываем атрибут dataProvider, и тоже самое имя, что указали в аннотации к первому методу. Теперь для каждой «строки» с данными будет вызван наш тест, а объекты будут переданы ему в качестве аргументов. Таким образом, можно передать в метод тестовые данные и ожидаемый результат (в моём случае это была строка с сообщением об ошибке).

Вот, что у меня получилось:

@Test(dataProvider = "invalidEmails")
public void emailShouldBeValid(final String invalidEmail, final String expectedMessage) {
page.registerUser(invalidEmail);
assertThat(page).field("email").hasError(expectedMessage);
}
@DataProvider(name = "invalidEmails")
public Object[][] getInvalidEmails() {
final String expectedErrorMessage =
tr("ru.mystamps.web.validation.jsr303.Email.message");
return new Object[][] {
{"login", expectedErrorMessage},
{"login@domain", expectedErrorMessage}
};
}

Исходный тест у нас уменьшился в размерах, стал более простым и понятным. Суммарный размер кода увеличился, плюс мы добавили ещё один метод. Но всё-таки, по моему мнению, код стал лучше.

Комментариев нет:

Отправить комментарий