JUnit vs TestNG

Давайте немного поговорим на тему тестовых фреймворков, кто что использует, какие плюсы и минусы видит для себя и вообще. Как и куда движутся данные фреймворки в своем развитии.

Я недавно мигрировал с JUnit на те TestNG. В целом меня в JUnit почти все устраивало, но уж больно бесило что методы под анотацией @Before/AfterClass должны быть статическими, а еще не хватало датапровайдеров.

Но меня беспокоим что TestNG не так активно развивается как JUnit. Как бы не скопытился он :frowning:
Тему перенес в раздел Java*

Я с статик еще не особо хорошо знаком, а чем он плох? Эти аннотации я напримериспользовал только при запуске драйвера.

Модификатор static означает что переменная/метод будет принадлежать не объекту класса а самому классу. Это означает что эта переменная/метод будет всего одна на всех, во многих случаях это очень удобно, но так же рождает целую кучу проблем, особенно в многопоточных программах.
То есть сколько бы объектов вы не создавали, статичная переменная будет всего одна.

Думаю, что многое зависит от скоупа задач. Кому-то может хватать и JUnit. Кому-то нужны определенные фишки TestNG. Но не стоит забывать, что оба фреймворка направлены прежде всего на юнит тестирование. Т.е. если мы хотим их использовать на уровне системной интеграции, то глупо плеваться в сторону какого-либо из них, если он не сможет покрыть ваши high level требования.

В своей первой конторе, где я осваивал автоматизацию, мне сказали учить TestNG. Тогда я не задавался вопросом, почему. Я даже не знал о существовании альтернатив. В процессе роста я конечно почитал различные (1) сравнительные (2) характеристики (3) с JUnit. И во многом фреймворки очень схожи. Но, как человек, пишущий функциональные тесты, я бы не мог сейчас представить свою автоматизацию без гибкого data provider’a. Та же иерархия аннотаций более очевидна и потокобезопасна. Лично для себя обнаружил огромным плюсом простоту кастомизации ассертов. XML’и творят чудеса в вопросах масштабирования.

Я не соглашусь, что TestNG грозит погибель. У обоих продуктов есть свои поклонники и коммитеры. И в случае чего, Cedric Beust обязательно кому-то передаст по наследству свои труды. :blush:

Чем плохи @RunWith(Parameterized.class) и @RunWith(Theories.class)?

У JUnit’a есть имплементации под другие языки тот же NUnit.

1 лайк

При датапровайдерах можно для отдельных методов класса делать разные наборы параметров. в Junit - параметры будут применены ко всем методам класса.

У JUnit есть вот такая штука - GitHub - TNG/junit-dataprovider: A TestNG like dataprovider runner for JUnit with many additional features, которая хорошо работает :slight_smile:

1 лайк

Да, я знаю. Да и самому написать такую не сложно.

[quote=“heartwilltell, post:1, topic:5478”]
Как и куда движутся данные фреймворки в своем развитии.
[/quote]Никуда. Оба достигли своей “логической” завершенности и эволюционировать им дальше некуда в принципе. Оба “умрут” только, когда появится nextgen фреймворк - но это будет очень не скоро, и возможно “не при нас”. Джейюниту остается “перенимать” фичи TestNG (xml, groups, депенды), а Цедрику фиксить баги.

Мигрировал свой проект на TestNG и в принципе доволен, нравится как обустроена потокобезопасность.

Но дополнительная прослойка конфигурации их testng.xml меня жутко раздражает.

Например есть ситуация - я паралелю запуск тестов по классам:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="classes" thread-count="10">
    <test name="Test">
        <classes>
            <class name="projects.someproject.Class1"/>
            <class name="projects.someproject.Class2"/>
            <class name="projects.someproject.Class3"/>
            <class name="projects.someproject.Class4"/>
            <class name="projects.someproject.Class5"/>
        </classes>
    </test>
</suite>

Но я хочу перед каждым запуском задавать количество потоков. При использовании JUnit можно было сконфигурировать surefire-plugin и при запуске отдать мевену команду -DthreadCount=5 и получить 5 потоков

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.18</version>
    <configuration>
      <parallel>classes</parallel>
      <threadCount>10</threadCount>
    </configuration>
  </plugin>

В testNG же очень много конфигурируется в самом testng.xml и я не понимаю как работать с ним внешними командами которые я скармливал мавену

Насколько я знаю, TestNG не поддерживает placeholders в своих xml. Так что если очень хочется, придется писать утилитку, которая будет менять этот параметр перед запуском test goal. Но другой вопрос - зачем вам это? То, что гоняется на Jenkins, как правило, привязано к выделенным ресурсам. Т.е. если есть возможность запускать тесты в 10 потоков на 10 тачках, то почему этим не пользоваться? Если же нужна какая-то специфичная конфигурация, то можно просто подсовывать конкретный, сконфигурированный заранее xml. Я лично разбивал xml по характеристикам ОС / браузер, а кол-во потоков всегда было либо max - для full прогона, либо min - для smoke / debug. Конечно ситуации могут быть разные, не спорю. Но динамическое изменение числа потоков может пригодиться крайне редко и лишь в случае наличия достаточного кол-ва ресурсов / хорошо сконфигурированного грида.

1 лайк

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

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

А про написание утилитки я думал уже, наверное напишу что-то простенькое.

Ну для дебага я настраивал джобу, которая смотрит в отдельный бранч моего собственного форка. Т.е. в мастере мои debug suites никогда не появятся в случае чего.

Когда-то тоже писал утилитку, которая в динамике создает testng.xml, но по мере усложнения конфигураций самих xml, кол-во параметров в джобах начало расти до неприличных размеров. Тогда я забросил это дело и стал подсовывать уже готовые xml. :blush:

Кстати, сам suite можно динамически в pom инжектить из дженкинс параметра. Т.е. к примеру в репозитории будет N suites на все случае жизни. Тогда нам достаточно создать choice параметр, и читать его в:

<suiteXmlFile>${suite}.xml</suiteXmlFile>
1 лайк

О идея :slight_smile: воспользуюсь

А возможно есть какой-то интерфейс или что-то такое что позволит мне получить список всех методов внутри одного теста?

Имеется ввиду testng.xml или java test?

Java test. Получить список всех методов внутри метода @Test

Можно при определенных условиях перехватить вызовы внутренних методов, но ваш кейс даже при большом желании слабо реализуем. Т.е .список методов пост-фактум получить легко. Но перед выполнением - мало вероятно.