2010-11-04 3 views
16

ВопросУстановка JUnit таймаут в затмении

Когда я запускаю все наши JUnit тесты, используя затмение, можно установить тайм-аут по умолчанию?

фон

Мой менеджер настаивает на написании юнит-тестов, которые иногда принимают до 5 минут. Когда я пытаюсь запустить весь комплект тестов (всего около 300 тестов), он может занять более 30 минут. Я хочу положить что-то на место, которое остановит любой тест, который займет больше 10 секунд.

Я знаю, индивидуальный тест может быть с аннотацией:

@Test(timeout=10000) 

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

Я также знаю, что могу создать муравья задачу установить тайм-аут по умолчанию для всех тестов, вдоль линий:

<junit timeout="10000"> 
    ... 
</junit> 

Проблема, что мы обычно работают наши тесты внутри затмения с Щелкните правой кнопкой мыши > Run As> JUnit Test.

Резюме

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

+0

Испытания, которые занимают 5 минут? Похоже, они либо делают * далеко * слишком много за тест, либо являются интеграционными тестами, а не модульными тестами ... –

+4

Вы можете отделить интеграционный тест от junit-тестов. Долгосрочные тесты должны выполняться на сервере-сборщике, таком как hudson, а не на вашей локальной машине. –

+0

@ Дональд: к сожалению, это единичные тесты. Мне они не нравятся. Я не согласен с ними. Но я ничего не могу с ними поделать. Отсюда мой вопрос ... Моя цель - по крайней мере, нейтрализовать проблему на моей коробке. Я думаю, что я собираюсь написать аспект, чтобы аннотировать все методы тестирования с помощью '@test (timeout = 10)'. Тогда я просто не проверю этот аспект на Subversion. Это мой план, я думаю ... – gMale

ответ

-2

Я знаю, что это действительно не отвечает на ваш вопрос, но простой ответ нет!

Установка тайм-аутов условно неверна beacseue, тогда у вас будет единичные тесты на вашем компьютере, которые вы всегда будете терпеть неудачу. Точка модульных тестов - это возможность быстро увидеть, что вы ничего не сломали. Чтобы проверить неудачный тестовый список, чтобы убедиться, что это просто длинные тесты, мы сделаем некоторые ошибки, проходящие через трещины.

Как отметили некоторые из комментаторов, вы должны разделить тесты на единичные тесты, которые выполняются быстро, и более медленные тесты интеграции с запуском, т. Е. Есть исходная папка с именем src/main/java для вашего кода, src/test/java для единицы тесты и src/integration-test/java для более длительных тестов.

+0

спасибо, что нашли время ответить, но вы проповедуете хор;) Я согласен с вами на 100%, но я не могу вносить такие изменения. Поэтому мой вопрос больше связан с нейтрализацией эффекта дрянных модульных тестов. – gMale

+0

@gmale: Мы все были там, но если вы не будете продолжать свой босс, ничего не изменится.Если бы вы быстро взглянули на исходный код Ant и время, которое они применяют, это не вещь JUnit. Возможно, вы захотите использовать @Ignore для конкретных тестов, которые вы не хотите запускать, вместо произвольного таймаута. Единственное, что вы можете сделать, это отредактировать исходный код JUnit, чтобы установить тайм-аут по умолчанию. Вам придется изменить, какую библиотеку JUnit вы используете. – brain

+0

Это было бы более подходящим в качестве комментария. – byxor

1

Если вы хотите настроить тесты, чтобы работать в течение более десяти секунд, вы можете попробовать это:

@Test(timeout=10000)

+2

Спасибо, но это решение не сработает для ситуации, описанной в первоначальном вопросе: «делать это, чтобы его длинные тесты всегда терпели неудачу. Я хочу, чтобы они работали, когда он запускал их на своей коробке. , , удаление тайм-аутов из 40 различных тестовых файлов [до проверки] нецелесообразно. – gMale

0

Мой менеджер настаивает на тестах Блок записи, что иногда занимает до 5 минут комплект

Это почти вертикально указывает, что эти испытания не являются модульными испытаниями.Вырежьте это Gordian knot: попробуйте рефакторинг вашего testuite, чтобы обеспечить эквивалентное покрытие для тестирования, не требуя тестового сценария, который работает так долго.

+1

К сожалению, они * являются единичными тестами. Он проверяет, что функция низкого уровня истекает через 5 минут после сбоя. :(Эта функция имеет 3 строки кода. – gMale

+5

Использование тайм-аута требует наличия часов. Реальный код будет использовать системные часы, но вам не нужны те тесты, которые вам нужны. Абстрактные часы - это объект и использование инъекции зависимостей для удаления прямую зависимость от системных часов, то есть вместо прямого вызова функции системных часов, введите интерфейс «Clock» (или абстрактный базовый класс), переданный в код тайм-аута. Для модульных тестов используется 'MockClock' (что IS-A 'Clock'), который имитирует тайм-аут. Для реального интегрированного кода используйте' SystemClock' (это IS-A 'Clock'), который вызывает функцию системных часов. – Raedwald

+0

Хотя он не использует часы , Я вижу вашу точку зрения. В этом случае тайм-аут фактически основан на неудачном вызове библиотеки (который в конечном итоге истекает во время ввода-вывода). Было бы неплохо, если бы он высмеял этот звонок, но он этого не сделает. действительно меняют все свои тесты повсюду, используя макеты, где я считаю нужным. Поэтому я искал способ просто установить ti meout для всех тестов. В эти дни мы вернулись к использованию муравья, поэтому я мог просто использовать тайм-аут, встроенный в задачу junit, как я упоминал в исходном сообщении. Муравей велика. – gMale

0

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

В любом случае, более прагматичный и дипломатический подход, чем противоборство с вашим боссом, может состоять в том, чтобы просто попытаться запустить более быстрые себя. Я видел взломы, чтобы сделать это в проекте, где медленные тесты имели SytemTest в их именах. Тогда в файле сборки было создано два объекта ant. Один, который провел все тесты, и тот, который отфильтровывался по названию класса SytemTest. Чтобы реализовать это, вам нужно будет переименовать некоторые из тестов и написать свою цель муравья.

1

Так что, возможно, комбинация использования Infinitest с включенным «Медленным тестовым предупреждением» вместе с фильтрующей функцией сделала бы трюк. Вы можете определить тесты, которые превышают ваш лимит времени и добавить их в список фильтров, это повлияет только на тестирование изнутри Eclipse. Запуск тестов с помощью сценария возможной сборки через CLI/CI и т. Д. Не будет затронут вообще. Вы можете найти больше по их настройке здесь: http://improvingworks.com/products/infinitest/infinitest-user-guide/

+0

Это выглядит фантастически! В значительной степени именно то, что я искал, и что-то, что я мог бы использовать часто, в других ситуациях. Я попробую это, и если это сработает, я продаюсь ... – gMale

11

Возможное решение: Продлить все классы тестов из другого класса: TestBase, например

Добавить в TestBase глобальный тайм-аут. Этот тайм-аут будет применяться ко всем расширенным классам:

public class TestBase { 
    @Rule 
    public Timeout globalTimeout = new Timeout(10000); 
} 
+1

Это отличное предложение. Что-то, что можно было бы точно использовать в других ситуациях. Но в этом случае потребовалось бы изменить все его тесты, что не было возможным. – gMale

+0

Приятный трюк, но есть ли способ переопределить это значение для конкретного теста (например, только одного), расширяющего этот класс? –

+0

Конечно. Вы можете использовать '@Test (timeout = 10)' для определенного метода в тестовом классе – alaster

0

Похоже, что тестовые комплекты помогут вам.

У вас может быть два набора тестов; QuickTests и AllTests. Включите QuickTests в пакет AllTests, а также тесты, которые занимают много времени. Затем все остальные тесты войдут в набор быстрых тестов.

Из затмения вы можете запустить весь комплект тестов сразу. Таким образом, вы запускаете QuickTests, и таким образом все остальные медленные тесты не будут выполняться.

Или see this question о том, как применить тайм-аут к набору, который будет применяться к вложенным наборам и классам в пакете. Который может достигнуть аналогичного того, что вы хотите, в сочетании с моим предложением выше.

Смежные вопросы