Test Data Supplier - TestNG Dataprovider на стероидах

Привет, друзья! Сегодня хочу поделиться рецептом, который поможет сделать тесты еще лучше. На большинстве своих проектов я сейчас использую связку инструментов Java/Kotlin + TestNG
Allure + Gradle. Ранее я уже писал о некоторых подходах, которые позволяют нам более удобно готовить данные для тестов, работать с базой данных и писать меньше аннотаций для Allure.

В этой заметке хочу рассказать о том, как улучшить Dataprovider. Очень часто в тестах приходится оперировать различными наборами данных. В каких-то случаях данные проще захардкодить, в каких-то - тащить из внешних источников. В большинстве случаев для оптимизации кода и параметризации я использую TestNG Dataprovider.

Давайте возьмем для примера простой тест - логин форма с тремя полями и валидацией.

@Test(dataProvider = "Authentication")
public void errorMessageOnLoginWithBadCredentials(String email, String password, String errMsg) {
    User badUser = new User(email, password);

    at(LoginPage.class)
            .loginAs(badUser)
            .errorMessage
            .shouldHave(exactText(errMsg));
}

@DataProvider(name = "Authentication")
public static Object[][] credentials() {
    return new Object[][]{
            {" ", " ", "Username is required"},
            {"admin@gmail.com", "UserTest@123", "Login and / or password do not match"},
            {"admin@gmail.com", " ", "Password is required"},
            {"ololo@ololo.com", "admin", "Login and / or password do not match"}
    };
}

Очень простой сценарий: в разных случаях пользователю будут показываться разные сообщения об ошибке. Здесь я применил Dataprovider, так как для каждой итерации у нас меняются лишь входные данные для теста.

Вроде как все отлично и даже работает.

Есть ли что-то, что можно улучшить? (люблю этот вопрос на собеседовании =))

Конечно, стоит посмотреть на уродливый дата провайдер. Вот этот Object[][] - то прям боль. Учитывая то, что мы живем в 2018 году, пишем на Java 8, которая поддерживает Stream API и имеет хороший Collection API. Двухмерный массив объектов - это несерьезно!

И даже с помощью няшного Котлина нельзя особо улучшить ситуацию.

@DataProvider
fun data(): Array<Array<String>> {
   return arrayOf(
              arrayOf(" ", " ", "Username is required"),
              arrayOf("admin@gmail.com", "UserTest@123", "Login and / or password do not match"),
              arrayOf("admin@gmail.com", " ", "Password is required")
   )
}

Остается смириться и писать такой вот говнокод. Но на самом деле ситуацию можно поправить с помощью библиотеки Test Data Supplier. Ее автором является один мой друг - Сергей Король.

Я о ней знал давно, но как-то попробовав ее еще на начальных этапах, не особо проникся идеей. Пока на днях не решил внедрить ее в один из новых проектов.

Подключение выполняется достаточно просто. Однако там есть один нюанс: для корректной работы требуется подключение DataProviderTransformer лисенер. Так вот подключать этот лисенер стоит либо через Gradle, либо через TestNG xml. Подключение через аннотацию @Listeners не даст желаемого результата. Учтите этот момент, я уже этот путь прострадал за вас=)

После подлючения вам станут доступны все плюшки этой библиотеки.

Можно легко переписать ваши унылые дейтапровайдеры на новый лад:

@DataSupplier
fun data(): Array<Array<String>> {
   return mapOf(
              User(" ", " ") to "Username is required"),
              User("admin@gmail.com", "UserTest@123") to "Login and / or password do not match"),
              User("admin@gmail.com", " ") to "Password is required"
   )
}

Тест в таком случае трансформируется в такую штуку:

@Test(dataProvider = "data")
fun errorMessageOnLoginWithBadCredentials(User user, String errMsg) {
    at(::LoginPage)
            .loginAs(user)
            .errorMessage
            .shouldHave(exactText(errMsg));
}

Все становится прям огненно круто. Есть, правда, один досадный момент: для полной поддержки нужно установить Idea плагин - test-data-supplier-plugin. Сама библиотека поддерживает разные навороты, о которых можно почитать в документации.

В общем всем рекомендую как минимум посмотреть на эту библиотеку, как максимум - прикрутить ее к себе в проект и пробовать.

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