Хобрук: Ваш путь к мастерству в программировании

Заставить JUnit запускать один тестовый пример за раз

У меня проблематичная ситуация с некоторыми довольно продвинутыми модульными тестами (с использованием PowerMock для насмешек и JUnit 4.5). Не вдаваясь в подробности, первый тестовый пример тестового класса всегда будет успешным, но все последующие тестовые наборы в том же тестовом классе не пройдут. Однако, если я выберу, например, только запуск теста 5 из 10, он пройдет. Таким образом, все тесты проходят при индивидуальном запуске. Есть ли способ заставить JUnit запускать один тестовый пример за раз? Я вызываю JUnit из ant-скрипта.

Я знаю о проблеме зависимых тестовых случаев, но я не могу точно определить, почему это так. В тестовых примерах нет сохраненных переменных, поэтому в аннотации @Before делать нечего. Вот почему я ищу экстренное решение, например, заставить JUnit запускать тесты по отдельности.


  • Пожалуйста, отредактируйте эту информацию в своем вопросе, чтобы все могли ее прочитать. 13.02.2009
  • В тестовых примерах нет сохраненных переменных, вы уверены в этом? А статические переменные? 13.02.2009
  • Как именно тест терпит неудачу, то есть что вы тестируете? 16.02.2009

Ответы:


1

Ваша проблема не в том, что JUnit запускает все тесты одновременно, ваша проблема в том, что вы не видите, почему тест терпит неудачу. Решения:

  1. Добавьте в тесты больше утверждений, чтобы убедиться, что каждая переменная действительно содержит то, что вы думаете.
  2. Загрузите IDE из Интернета и используйте встроенный отладчик для просмотра различных переменных.
  3. Сбросьте состояние ваших объектов непосредственно перед точкой, где тест не пройден.
  4. Используйте часть «сообщение» утверждений для вывода дополнительной информации о причине сбоя (см. ниже).
  5. Отключите все тесты, кроме нескольких (в JUnit 3: замените все строки «void test» на «void dtest» в исходном коде; в JUnit 4: замените «@Test» на «//D@TEST»).

Пример:

assertEquals(list.toString(), 5, list.size());
13.02.2009

2

Я в курсе всех рекомендаций, но, чтобы наконец ответить на ваш вопрос, вот простой способ добиться того, чего вы хотите. Просто поместите этот код в тестовый пример:

Lock sequential = new ReentrantLock();

@Override
protected void setUp() throws Exception {
    super.setUp();
    sequential.lock();
}

@Override
protected void tearDown() throws Exception {
    sequential.unlock();
    super.tearDown();
}

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

30.01.2013

3

Создается впечатление, что ваши тест-кейсы зависимы, то есть: выполнение кейса-X влияет на выполнение кейса-Y. Такой системы тестирования следует избегать (например: нет гарантии порядка, в котором JUnit будет запускать ваши случаи).

Вы должны реорганизовать свои дела, чтобы сделать их независимыми друг от друга. Во многих случаях использование методов @Before и @After может помочь вам распутать такие зависимости.

13.02.2009
  • +1, я бы не сказал, что этого следует избегать, но его следует избегать, чтобы избежать именно этого сценария. 13.02.2009
  • Я знаю о проблеме зависимых тестовых случаев, но я не могу точно определить, почему это так. В тестовых примерах нет сохраненных переменных, поэтому в аннотации @Before делать нечего. Вот почему я ищу экстренное решение, например, заставить JUnit запускать тесты по отдельности. 13.02.2009
  • У зависимости много лиц: базы данных, файлы, системные свойства и т. д. Вы должны сократить свой набор до двух противоречивых тестов. Начните комментировать код в одном тесте, пока они не добьются успеха. Затем раскомментируйте и сделайте то же самое во втором тесте. Это даст вам некоторое представление о причине вашей проблемы. 13.02.2009
  • В тестовых примерах нет сохраненных переменных, вы уверены в этом? А статические переменные? 13.02.2009

  • 4

    Поздравляем. Вы нашли ошибку. ;-)

    Если тесты «не должны» влиять друг на друга, возможно, вы обнаружили ситуацию, когда ваш код может войти в неисправное состояние. Попробуйте добавить утверждения и ведение журнала, чтобы выяснить, где код идет не так. Возможно, вам даже потребуется запустить тесты в отладчике и проверить внутренние значения вашего кода после первого теста.

    13.02.2009

    5

    Извините, если я не отвечу на ваш вопрос напрямую, но разве ваша проблема не связана с тем, что должны решать TestCase.setUp() и TestCase.tearDown()? Это методы, которые среда JUnit всегда будет вызывать до и после каждого тестового примера, и обычно они используются для обеспечения того, чтобы вы начинали каждый тестовый пример в одном и том же состоянии.

    См. также JavaDoc для TestCase.

    13.02.2009

    6

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

    Maven и Ant содержат параметр forkmode для запуска тестов JUnit, который указывает, получает ли каждый тестовый класс свою собственную JVM или все тесты выполняются в одной JVM. Но у них нет возможности запускать каждый тестовый метод на отдельной JVM.

    13.02.2009

    7

    Я знаю о проблеме зависимых тестовых случаев, но я не могу точно определить, почему это так. В тестовых примерах нет сохраненных переменных, поэтому в аннотации @Before делать нечего. Вот почему я ищу экстренное решение, например, заставить JUnit запускать тесты по отдельности.

    Оператор @Before безвреден, потому что он вызывается для каждого теста. Класс @BeforeClass опасен, потому что он должен быть статическим.

    13.02.2009

    8

    Мне кажется, что, возможно, дело не в том, что вы неправильно настраиваете или удаляете свои тесты (хотя дополнительная настройка/удаление может быть частью решения), а в том, что, возможно, у вас есть общее состояние в вашем коде, которым вы не являетесь. в курсе. Если ранний тест устанавливает статическую/одиночную/общую переменную, о которой вы не знаете, более поздние тесты потерпят неудачу, если они этого не ожидают. Даже с Mocks это очень возможно. Вам нужно найти эту причину. Я согласен с другими ответами в том, что ваши тесты выявили проблему, которую не следует решать, пытаясь запустить тесты по-другому.

    13.02.2009

    9

    Ваше описание показывает мне, что ваши модульные тесты зависят друг от друга. Это настоятельно не рекомендуется в модульных тестах.

    Модульный тест должен быть независимым и изолированным. Вы должны быть в состоянии выполнить их в одиночку, все (в каком порядке, это не имеет значения).

    Я знаю, это тебе не поможет. Проблема будет в ваших утверждениях @BeforeClass или @Before. Будут зависимости. Поэтому проведите их рефакторинг и попытайтесь изолировать проблему.

    Вероятно, ваши макеты создаются в вашем файле @BeforeClass. Подумайте о том, чтобы поместить его в оператор @Before. Таким образом, нет экземпляра, который длится дольше, чем тестовый пример.

    13.02.2009
  • Ладно, настоятельно не рекомендуется. 14.02.2009
  • Новые материалы

    Мой процесс подачи заявки в Школе программного обеспечения и дизайна Тьюринга
    Мой последний пост на Medium был в конце августа, и в нем я пообещал написать еще раз, рассказывая историю моего процесса подачи заявки в Школу программного обеспечения и дизайна Тьюринга ...

    Генерация ваших собственных удивительных QR-кодов с использованием Python
    QR-код (код быстрого ответа) — это разновидность матричных штрих-кодов (или двумерных штрих-кодов), изобретенных в 1994 году японской автомобильной компанией Denso Wave . Штрих-код —..

    Прогресс в технологии Трансформеров часть 3
    Многомасштабный управляющий сигнальный преобразователь для бесфазного синтеза движения (arXiv) Автор: Линтао Ван , Кун Ху , Лей Бай , Юй Дин , Ваньли Оуян , Чжиюн Ван . Аннотация:..

    Представляем поддержку компонентов Vue.js. Мгновенный HMR и многое другое.
    Хотя у FuseBox уже был плагин Vue, он был базовым и не имел многих функций, которые делали работу с Vue.js такой приятной. Однако с этим выпуском мы рады сообщить, что в FuseBox..

    Приключения в Javascript, часть 1
    Я продолжаю думать о том, чтобы писать больше, но чем больше я думаю об этом, тем меньше я это делаю. Итак, сегодня я перестал думать и начал писать. Отсюда можно только спускаться… В..

    Понимание дженериков в TypeScript: подробное руководство
    Введение TypeScript, строго типизированный надмножество JavaScript, хорошо известен своей способностью улучшать масштабируемость, удобочитаемость и ремонтопригодность приложений. Одной из..

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..