Не получается продебажить DataSupplier Interceptor в IntelliJ IDEA и подскажите как его правильно подключать

test-data
test-data-supplier
java
Теги: #<Tag:0x00007f7b6419e808> #<Tag:0x00007f7b6419e6c8> #<Tag:0x00007f7b6419e560>

(Nik Sidorenko) #1

Кто может подсказать как продебажить IAnnotationTransformerInterceptor для DataSupplier?

Есть класс, который имплементирует IAnnotationTransformerInterceptor

import io.github.sskorol.core.IAnnotationTransformerInterceptor;
import org.testng.annotations.IDataProviderAnnotation;

import java.lang.reflect.Method;

public class DataSupplierAnnotationTransformer implements IAnnotationTransformerInterceptor {
    @Override
    public void transform(IDataProviderAnnotation annotation, Method method) {
        annotation.setParallel(false);
    }
}

В ресурсы добавил папку META-INF/service. Создал файл с именем “io.github.sskorol.core.IAnnotationTransformerInterceptor” в нём текст “com.infrascale.qaa.draas.tests.core.listeners.DataSupplierAnnotationTransformer”
В классе DataSupplierAnnotationTransformer ставлю брек поинт

Запускаю такой тестовый класс из IDEA

public class LoginIT extends BaseIT {

    @DataSupplier(runInParallel = true)
    public List<UserCredential> accounts() {
        List<UserCredential> accounts = new ArrayList<>();
        accounts.add(UserCredential.builder().username("root").password("root").build());
        accounts.add(UserCredential.builder().username("admin").password("admin").build());

        return accounts;
    }

    @Test(dataProvider = "accounts")
    public void can_login_with_valid_credentials(final UserCredential account) {
        final LoginPage loginPage = new LoginPage();
        final AppliancePageObject page = loginPage.login(account);

        assertInstanceOf(page, TopPage.class, "Cannot log in with valid credentials");
    }
}

Ожидаю, что сработает брек поинт. Но нет


(Vatslau) #2

Стесняюсь спросить) но всё же
1 стандартного TestNg, Junit5 датапровайдера уже не достаточно?
2 зачем вам брейкойнт в провайдере? - ИМХО ставьте на метод теста - там увидете все объекты которые пишли в тест.


(Sergey Korol) #3

Это как? Средствами TestNG - кликом по gutter icons?

image

Это очень шаткий и нестабильный путь, ибо он полностью игнорит конфигурацию билд тула. Дебажте средствами maven / gradle и не морочьте себе голову.

Только что проверил на gradle. Breakpoints прекрасно работают.

П.С. И да, этот трансформер решит вашу изначальную задачу с динамическим изменением parallel флага.

UPDATE:

Надеюсь, это опечатка? Т.к. должно быть services (мн. ч.). Ну и на всякий случай - это 2 папки: META-INF, а внутри - services. :wink:


@DataSupplier Как поменять runInParallel значение в runtime
(Nik Sidorenko) #4

Можно было бы обойтись стандартным TestNG DataProvider. Но код не красивый + неудобная работа с массивами. Это как - зачем использовать Java 11, 7-я неплохо работает. DataProvider позволяет многое, но немного архаичен в плане удобства использования.

Брек поинт в интерсепторе нужен для того, чтобы посмотреть выполняется ли код интерсептора, а также callstack. Это попытка локализировать проблему.


(Vatslau) #5

это спорное замечание)
мне действительно интерестно, в чём преимущество этой билиотеки
над
импортом коллециий

    @Parameters({"path_generated", "stage", "country"})
    @BeforeClass(enabled = true)
    public void setUpSuite(String path_generated, String stage, String country) {
        this.userProfiles = new ImportDataUsers().userProfiles(pathToFile, stage, country);
        return;
    }

засовываем всё это в провайдер и живёт эта сущность с родительском классе от которого наследуем тесты.

    @DataProvider(name = "users", parallel = true)
    public Iterator<Object[]> users() {
        Collection<Object[]> data = new ArrayList<>();
        this.userProfiles.forEach(item -> data.add(new Object[]{item}));
        return data.iterator();
    }

3 строчки в тесте грузят объекты в данном случае из джейсона(можно из чего угодно)

ИМХО такой похдод - треш (только для дебага если, у меня объекты по 30-50 полей - билдить их в коде - портянки на +100500 строк будет). С юзерами + хранить их во внешнем файле - всегда можно по быстрому что-то поменять не меняя кода (например через дженкинс подсовывать разные юзер конфиги)

интерцептор это провайдер? (если нет поясните пожалуйста)
ИМХО провайдер просто поставляет объекты - если что-то нет так пошло на этапе создания коллекции будет обычно простой стектрейс…
зачем туда лезть?
для этого простой юнит тест на метод импорта коллекции в провайдер - он покроет 99% всех проблем.


(Михаил Братухин) #6

Интерцептор - это перехватчик. Шаблон проектирования такой. Человек хочет «красиво», а вы ему вопросы свои, сомнения.

Кстати, а что там в 10-й и 11-й java есть? Отстал от темы чуток.


(Nik Sidorenko) #7

Это исключительно для примера. В реальном проекте список UserCredential подгружается из файла.

Единственное, что я не понял в этом куске кода, это объекты какого типа возвращает DataProvider. Не просмотрев весь код DataProvider, я не смогу понять подходит он мне или нет, так как все мои дата провайдеры возвращают Iterator<Object[]>. При использовании DataSupplier это видно по сигнатуре метода.

Внутри DataProvider у Вас происходит превращение объектов из this.userProfiles (предполагаю что это что-то типа List) в Collection<Object[]>. Это для того чтобы удовлетворить ограниченному условию о типе возвращаемых значений DataProvider. При использовании DataSupplier мне самому этого превращения делать не нужно - я могу просто возвращать this.userProfiles. Не сомневаюсь, что внутри DataSupplier делает то же самое, но он это делает за меня.

Импорт коллекции - это классно. Но для DataProvider всё равно приходится превращать её в Iterator<Object[]>. Я думаю если бы сам TestNG предоставлял возможность DataProvider возвращать Collection<?> или List<?>, было бы удобнее. Конечно можно сразу собирать/загружать/импортировать данные в Object[] и Object[][], но согласитесь, мало кто сейчас в век Java 11 пользуется обычными массивами типа String[] - ведь работать со Stream, List, Collection намного приятние.

Как я понимаю, одна из целей, которую преследовал создатель DataSupplier @ArtOfLife, это помочь пользователю избежать написания рутинного кода по превращению List, Stream, Collection в Object[] и Object[][].

Но всё это дело вкуса. Спасибо Вам @VatslauX за Ваше мнение по поводу использования DataProvider. Давайте вынесем за пределы этого топика дискуссию о том, что удобнее DataProvider или DataSupplier, и вернёмся к проблеме.
Проблема заключается не в дебаге самого DataSupplier (прошу прощения если название топика вводит в заблуждение), а том что не срабатывает Interceptor для DataSupplier.

Interceptor - это не провайдер. Interceptor - это способ изменить параметры провайдера (например параллелить запуск провайдера или нет) налету.

Проблем с самими данными в провайдере, их получением и использованием нет.

Брек поинт в Interceptor - это способ понять отрабатывает его код или нет, правильно ли я его подключил. А об оригинальной проблеме вы можете почитать тут @DataSupplier Как поменять runInParallel значение в runtime


(Vatslau) #8

Спасибо за инфу. Теперь понятно - зачем это нужно в принципе.


(Nik Sidorenko) #9

Да, опечатка. В проекте это две папки, одна в другой META-INF и services

Да именно так.

Сложилось как раз такое мнение. Ибо уже не первый раз натыкаюсь на различия при запуске Maven и TestNG IDEA plugin.

Чтобы расставить все точки над “ё”. Уточните, что Вы имеете ввиду. Это?
image


(Sergey Korol) #10

Для maven просто так не получится продебажить тесты. Нужно следовать официальным докам.

Первый вариант предполагает создание дополнительной debug конфигурации. Т.е. вначале запускаются тесты и слушают определенный порт. Затем дебагером нужно к ним приатачиться.

Второй вариант можно с ходу запускать, передав соответствующий флаг.

А так, в целом направление верное: дебажить нужно через goals / tasks билд тула посредством создания соответствующей конфигурации из меню.

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