Групировка и запуск тестов по тегам

Привет, интересует реализовывал ктонибудь такую штуку как в thucydides, где над каждым тестов можно было поставить анотацию со значение тега, а потом при запуске через мавен - просто указать какие теги запускать. и оно соберет в один класс все тесты с определенным тегом и запустит их.

Возможно что-то подобное уже и так есть в JUnit / TestNG. Делитесь примерами, советуйте.

В TestNG есть группы тестов

Соответственно, в surefire-maven-plugin их можно указывать и сработает именно так, как ты написал.
Скомпилирует и соберет он все тесты, а запустит те, которые в группе

Использование групп в коде тестов интересная фича, но я не нашёл удобного способа ей пользоваться.

Расскажи кстати, как ты хочешь их использовать? Как будет выглядеть процесс запуска группы тестов, начиная от формирования тестплана?

На мой взгляд пользование группами не очень удобно. Удобнее иметь интеграцию с какой-то Test Management tool, в которой хранятся все тесты и которая предоставляет удобный интерфейс по их группированию в разные тестпланы. Она же предоставляет различные средства для пометки тегами и прочее.

У меня в одном проекте абсолютно все тесты, которые затрагивают абсолютно разные участки нашей системы, а то и вообще системы другого проекта. И соответственно мне для того что бы быстро проверить одну функциональность - не хочется гонять абсолютно все, потому это удобно бить по сюитам и запускать сюиты.
Порой нужно проверить лишь очень узкие кейсы, и часто так выходит что эти кейсы сквозные - затрагивают практически все участки по немногу, и потому теги тут очень ок помогают.
Если сьюит у меня отвечает за покрытие определенной функциональности, то тегами я покрываю специфические сквозные сценарии.
Сюиты запускаются на регулярной основе по расписанию, одни реже другие чаще, сквозные кейсы запускаются по требованию.

Документацию как таковую практически не веду, никаких тест менеджмент тулов нету, хотя пробовали и тестрейл и зефир, но все впадло поддерживать, имперически пришли к выводу что для нас лучшая документация это читаемый код тестов с нормальными коментариями, так как у нас нету менеджеров/заказчиков/прочихЛюдейДляКогоВажныБумажки которым нужно предоставлять отчеты.

А ручных тестов нет у вас? Всё автоматизировано?

Ручные есть конечно, тестирование верстки, мобайл версии и прочее, но для этого используются быстрые чек листы. Функциональная часть после первого ручного тестирования и доведения до готовности сразу покрывается автотестами.

Отклонились от темы :slight_smile:

пользуюсь у junit этой штукой уже достаточно давно
Есть класс с интерфейсами, которые описывают группы тестов
Каждый класс имеет аннотацию вида

@Category({TestGroup.SavingTriggerTest.class, TestGroup.Export.class})

для того, чтобы иметь возможность гибко использовать группы в CI подключаю их в pom

<properties>
       ...
        <groups>
            com.datapine.core.TestGroup$SavingTriggerTest,
            com.datapine.core.TestGroup$Export,
        </groups>
    </properties>

в тимсити это выглядит так http://joxi.ru/ucQiVP3JTJBIXTqGtq4
можно отметить одну или несколько групп одновременно для запуска тестов
В параметрах запуска билда только нужно дополнительно указать -Dgroups=%test%, где %test% - это как раз сформированный список групп

Если я не о том, прошу прощения ))

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

Допустим у нас есть 20 классов с тестами. И в каждом классе нас интересует допустим по 1 методу. Я не хочу запускать еще 380 тестов, когда меня интересует только 20, и пложить еще один класс куда я бы вынес эти 20 я тоже не хочу.

Я хочу сделать так

public class SomeTestClass1 {

@Test
@Tag("SomeCaseTag")
public void testMethod() {
doSomething();
}
}

public class SomeTestClass2 {

@Test
@Tag("SomeCaseTag")
public void testMethod2() {
doSomething();
}
}

И при запуске указать мевену mvn clean test -Dtag=SomeCaseTag site - в следствии чего мавен запустит мне 2 теста - testMethod() и testMethod2()

Сново же таки в фукудите реализован этот функционал, но читать код фукудита сложнее чем строить адронный колайдер.

Мне показалось, что surefire plugin может таки запускать методы выборочно. Или я ошибся?

Ага вроде оно, но давайте представим теперь с таким синтаксисом команду запуска в maven

mvn -Dtest=TestClass1#method1+method2,TestClass2#method1+method3+method5 и тд. Это в принципе решение моего вопроса, но уж больно не лаконичное.

1 лайк

Ну да, длинновасто. А это будет варьироваться каждый запуск или будет готовая джоба на CI вроде samity check?

вот, написала как бы я это решала (пример положила в наш at.info мега склад примеров)

сам ранер

тесты в соседнем пекедже. Запускать все это следующим образом

  test -Dtest=TestRunner -Dtags=tag1

или

 test  -Dtest=TestRunner "-Dtags=tag1, tag3"

Будет время, подумаю что-нибудь по-красивее. Критика принимается :smile:

1 лайк

У TestNG есть чудесный интерфейс IMethodInterceptor, который позволяет нам переопределить не менее чудесный метод intercept. Собственно он возвращает список методов, которые должны быть запущены. Когда-то использовал следующий кусок для приоритезации тестов, вычитываемых из xml. Тут используется кастомная аннотация Priority. Никто не мешает вам по аналогии сделать нечто похожее для тэгов. Достаточно задать нужные правила Comparator’у, и отсортировать список, как вам будет угодно.

    public List<IMethodInstance> intercept(final List<IMethodInstance> methods, final ITestContext context) {        
        final Comparator<IMethodInstance> comparator = new Comparator<IMethodInstance>() {            
            private int getPriority(final IMethodInstance methodInstance) {
                final Priority methodPriority = methodInstance.getMethod().getMethod().getAnnotation(Priority.class);                
                return methodPriority != null ? methodPriority.value() : 0;
            }

            public int compare(final IMethodInstance firstMethodInstance, final IMethodInstance secondMethodInstance) {
                return firstMethodInstance.getMethod().getTestClass().getName().
                        compareTo(secondMethodInstance.getMethod().getTestClass().getName()) == 0 ?
                        getPriority(firstMethodInstance) - getPriority(secondMethodInstance) : 0;
            }
        };

        final IMethodInstance[] outputMethods = methods.toArray(new IMethodInstance[methods.size()]);
        Arrays.sort(outputMethods, comparator);

        return Arrays.asList(outputMethods);
    }

Сама имплементация зашивается в кастомный листенер, который в свою очередь подключается в maven-surefire-plugin:



              <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.16</version>
                    <configuration>
                        <properties>
                            <property>
                                <name>usedefaultlisteners</name>
                                <value>false</value>
                            </property>

                            <property>
                                <name>listener</name>
                                <value>
                                    your.listener.class
                                </value>
                            </property>
                        </properties>
                    </configuration>
                </plugin>
2 лайка

В junit есть 2 способа - сделать раннер и там смотреть на основании этого тэга, запускать или нет метод. Второй - написать рулу, которая будет так же читать аннотацию и делать что надо.
В тестng - есть ран листенеры.
И еще есть способ - использовать aspectJ.
В нем будет разбор аннотации и будете смотреть, запускать вам метод или нет.

Так в TestNG есть же группы - TestNG

Зачем раннеры или инцепторы?

Если делать рулу в junit, то просто пропустить тест не получится, только выкидывать эксепшн о том, что тест должен быть заигнорен, а это значит много хлама в логе. Если просто не запускать base.evaluate(), то тест обозначается как пройденный успешно, что в такоом случае не является правдой. Раннер в этом плане более чистый

Правда, я только что попробовала, стандартная junit аннотация @Category работает и для тест-метода, не только для класса, так что все эти костыли не неужны. А запуск такой же, как я и говорила в первом сообщении, -Dgroups=…

Автору группы не подошли, мы предложили альтернативы.

Не вижу этого. С моей точки зрения “хотелки” автора полностью совпадают с возможностями групп в testng.

хм. Не вижу ничего плохого в том, чтобы выделять тесты пропущенными с указанием причины.
В итоге в отчете будет видно, что тесты не были запущены по причине несоответствия тэгов.
Опять же - это просто один из вариантов.

да, но опять же если запускать 10 тестов из 1000, то как по мне не очень красиво
а бонус в текстовых тегах вижу только один, не нужно создавать много интерфейсов для группировки, просто строка все же более гибкая