JUnit: как избежать «неработающих методов» в тестовых классах утилит


118

Я перешел на JUnit4.4 с JUnit3.8. Я запускаю свои тесты с помощью ant, все мои тесты выполняются успешно, но тестовые служебные классы не работают с ошибкой «Нет исполняемых методов». Я использую шаблон, чтобы включить все классы с именем * Test * в тестовую папку.

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

В JUnit3.8 это не было проблемой, поскольку эти служебные классы не расширяли TestCase, поэтому бегун не пытался их выполнить.

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

Есть ли изящное решение этой проблемы?


Ваши тесты работают в Eclipse / NetBeans / вашей любимой среде IDE?
guerda

Я использую затмение. На самом деле проблем нет, как-то eclipse не пытается запускать эти классы. Я удивляюсь, как?
LiorH

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

1
@guerda: Вопрос мне кажется довольно ясным. Его задача Ant - найти классы, не содержащие тестов, потому что фильтр выбирает служебный класс. Отсюда и мой ответ, который я до сих пор считаю полностью актуальным.
Джон Скит,

LiorH: Спасибо за разъяснения, так что мой ответ - пустая трата времени :)
guerda

Ответы:


50

Предполагая, что вы контролируете шаблон, используемый для поиска тестовых классов, я бы предложил изменить его на соответствие, *Testа не *Test*. Так TestHelperне получится, но FooTestбудет.


1
Не думаю, что это поможет, потому что он перешел на JUnit 4.4, и это не имеет значения.
guerda

2
Вы, кажется, упустили суть моего ответа. У него есть фильтр имен для определения классов, которые следует рассматривать как тесты. Если он изменит фильтр, он может легко исключить вспомогательные классы.
Джон Скит,

1
Ваше предложение действительно, однако я проверил свои классы тестов, и некоторые из них начинаются с Test, а некоторые заканчиваются Test. нет четкого различия между служебными классами и реальными тестовыми классами. Считаете ли вы предложенную вами конвенцию хорошей практикой? (т.е. утилиты начинаются с Test, а тесты заканчиваются Test)
LiorH

4
Это почти соглашение, что вы добавляете к классам тестового набора суффикс * Test. Возможно, вам придется провести рефакторинг, соответствующим образом переименовав тестовые классы, а также переименовать помощников, чтобы они не использовали это соглашение о суффиксах.
Spoike,

2
Я согласен со Спойком - если вы не можете определить по названию класса, является ли он тестовым или вспомогательным, вам следует переименовать класс. Соглашение больше гласит: «Класс является тестом тогда и только тогда, когда он заканчивается тестом». Классы утилит могут начинаться или не начинаться с Test - это не имеет значения.
Джон Скит,

142

Аннотируйте свои служебные классы с помощью @Ignore. Это заставит JUnit не пытаться запускать их как тесты.


6
На самом деле нет, не должно. @Ignore предназначен для временного отключения тестов.
Элис Янг

1
Извините, но это плохая идея. Вы хотите начать аннотировать свой производственный код с помощью аннотаций, связанных с тестированием, только потому, что они могут соответствовать тестовой модели? Правильный ответ - исправить имена классов, если они запускают сопоставление с образцом для тестов. И убедитесь, что шаблон находит только классы, заканчивающиеся на Test. Это общепринятый образец
Кевин М.

Да, это плохо, и я не осознавал этого, пока не внес еще один голос, который я не могу удалить. Сделайте свой базовый класс абстрактным, тогда JUnit проигнорирует его. См. Ответ @ gmoore ниже.
Райан Шиллингтон

83

Мой конкретный случай имеет следующий сценарий. Наши тесты

public class VenueResourceContainerTest extends BaseTixContainerTest

все расширяются

BaseTixContainerTest

и JUnit пытался запустить BaseTixContainerTest. Бедный BaseTixContainerTest просто пытался настроить контейнер, настроить клиента, заказать пиццу и расслабиться ... чувак.

Как упоминалось ранее, вы можете аннотировать класс с помощью

@Ignore

Но это заставило JUnit сообщить, что этот тест пропущен (а не полностью проигнорирован).

Tests run: 4, Failures: 0, Errors: 0, Skipped: 1

Это меня раздражало.

Итак, я сделал BaseTixContainerTest абстрактным, и теперь JUnit действительно игнорирует его.

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

7
Намного лучше, чем@Ignore
neworld

Я попробовал подход @Ignore и подумал, хорошо , что хорошо, то я прочитал этот ответ и ударил себя в лоб, «О , конечно
dnuttle

38

Чтобы JUnit не создавал экземпляр вашего тестового базового класса, просто сделайте его

public abstract class MyTestBaseClass { ... whatever... }

(@Ignore сообщает, что он игнорируется, что я оставляю для временно игнорируемых тестов.)


3
Исполнители JUnit часто также пытаются создать экземпляры абстрактных классов, а затем терпят неудачу из-за ошибки создания экземпляра.
Holly Cummins

Отлично работает для моих базовых тестовых классов
ruX

3
Это работает из-за имени (оно не заканчивается на Test), а не из-за абстрактного модификатора. Измените имя класса на MyBaseClassTest, и он попытается создать экземпляр, как указано в @HollyCummins (и потерпит неудачу)
Hutch

В моем случае так и должно быть protected abstract class.
Мистик Лин

18
  1. Если это ваш базовый тестовый класс, например AbstractTest, и все ваши тесты расширяют его, тогда определите этот класс как абстрактный
  2. Если это класс Util, то лучше удалить * Test из класса, переименовать его в MyTestUtil или Utils и т. Д.

10

Будьте осторожны при использовании автозавершения кода в среде IDE для добавления импорта для @Test.

Так должно быть, import org.junit.Testа не import org.testng.annotations.Test, например. Если вы сделаете последнее, вы получите ошибку «Нет запускаемых методов».


Это должен быть комментарий, а не ответ.
Swaranga Sarma

3
Не понимаю почему. Это верное решение.
Шридхар Сарнобат

4
Intellij Idea 2017 возился с моим умом, импортировав org.junit.jupiter.api.Testвместо этого! но благодаря вам теперь это решено
AmiNadimi 03

Большое спасибо, я был сбит с толку, когда получил проблему «нет запускаемых методов».
Питер С.

7

Теперь Ant поставляется с skipNonTestsатрибутом, который был разработан, чтобы делать именно то, что вы, кажется, ищете. Не нужно менять базовые классы на абстрактные или добавлять к ним аннотации.


2
Похоже, что skipNonTestsатрибут доступен только в ant 1.9+, что очень досадно, так как он выглядит невероятно полезным. Это также исключит абстрактные тестовые суперклассы.
Holly Cummins

4

А что насчет добавления к этим классам пустого тестового метода?

public void avoidAnnoyingErrorMessageWhenRunningTestsInAnt() {
    assertTrue(true); // do nothing;
}

8
но это ложно увеличивает количество тестов, которые у нас есть :) не то чтобы это большое дело
Сударшан

1

В вашем тестовом классе, если вы написали import org.junit.jupiter.api.Test; удалите его и напишите import org.junit.Test; В этом случае это сработало и у меня.


1
удивительно, но это сработало. Я выполнил вручную в командной строке Windows. Однако другая проблема в том, что они @BeforeAllи @AfterAllне запускаются.
BingLi224

похоже, JUnit4 работал (с @BeforeClassand @AfterClass, но с JUnit5 нет. Ссылка: junit.org/junit5/docs/current/user-guide/#migrating-from-junit4
BingLi224

0

Я также столкнулся с аналогичной проблемой («нет запускаемых методов ...») при запуске самого простого или простого фрагмента кода (с использованием @Test, @Before и т. Д.) И нигде не нашел решения. Я использовал Junit4 и Eclipse SDK версии 4.1.2. Решил мою проблему, используя последнюю версию Eclipse SDK 4.2.2. Я надеюсь, что это поможет людям, которые борются с похожей проблемой.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.