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

Кто может подсказать как продебажить 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");
    }
}

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

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

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

image

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

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

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

UPDATE:

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

1 лайк

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

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

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

    @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% всех проблем.

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

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

Это исключительно для примера. В реальном проекте список 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 - #8 от пользователя NikS

1 лайк

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

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

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

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

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

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

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

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

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

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

1 лайк