Maven - сборка сбоев, когда unit test занимает слишком много времени
У меня в моем проекте много модульных тестов, написанных в JUnit и TestNG. Процесс сборки основан на maven с плагином surefire.
Есть ли какой-либо способ/плагин для maven для сбоя сборки, если хотя бы один unit test занимает слишком много секунд? Я знаю, что есть некоторые плагины, которые не могут выполнить сборку в TeamCity, Дженкинс, но это "слишком далеко".
В моем проекте я хочу иметь только быстрые тесты для эффективного модульного тестирования. Я могу улучшить свои старые тесты, но мне нужно защитить будущие обязательства.
Ответы
Ответ 1
Если все ваши тесты расширяют некоторый базовый класс, я думаю, вы можете придерживаться @Rule
, который будет применяться ко всем @Test
в дочернем классе.
например.
import org.junit.rules.Timeout;
public abstract class BaseTestConfiguration {
@Rule public Timeout testTimeout = new Timeout(60000); // 60k ms = 1 minute
}
public class ThingTests extends BaseTestConfiguration {
@Test
public void testThis() {
/*will fail if not done in 1 minute*/
}
@Test
public void testThat() {
/*will fail if not done in 1 minute*/
}
}
Мы обнаружили, что это проще всего, а не возиться с AspectJ или секретными конфигурационными директивами. Разработчики более склонны вычислять части Java, чем все секретные XML, что это и что.
Вы можете поместить @Before
@After
и любое количество других директив junit в базовый класс.
Ответ 2
Почему бы не добавить таймаут для каждой тестовой базы. Я предполагаю, что вы программируете на Java, поэтому в JUnit вы можете сделать что-то вроде этого:
@Test(timeout=100) public void testQuickly()
Если тест не заканчивается через 100 миллисекунд, он не работает.
Ответ 3
В maven surefire вы можете использовать forkedProcessTimeoutInSeconds вместе с forkMode=once
.
Это убьет разветвленный jvm, если он займет слишком много времени. Если вы хотите сделать это за каждый тест, вы можете forkMode = pertest или forkMode = always (что делает это для каждого класса).
Ответ 4
Пробовали ли вы указывать таймаут для теста через @Test (timeout = xx)? Найдите официальную документацию api здесь: http://junit.sourceforge.net/javadoc/org/junit/Test.html
ИЗМЕНИТЬ ---
Вы также можете рассмотреть возможность использования свойства timeout для набора TestNg, однако вам придется переместить все ваши тесты на TestNg, но это позволит вам указать тайм-ауты для групп.
Это официальная документация api: http://testng.org/javadoc/org/testng/xml/XmlSuite.html#setTimeOut(java.lang.String)
Ответ 5
У меня было одно и то же требование, и поскольку я использовал TestNG, я использовал "групповая функция" .
Если вы застряли в JUnit, попробуйте использовать набор тестов (http://stackoverflow.com/questions/817135/grouping-junit-tests)
Ответ 6
Попробуйте использовать задачу junit Ant с параметром таймаута.
http://ant.apache.org/manual/Tasks/junit.html
EDIT:
Еще одна вещь, которую вы можете сделать, - это использовать aspectj со следующим типом:
public aspect TestTimeoutChecker {
long TIMEOUT = 60000;
pointcut invokeEvent() :
execution(@Test * *(..));
Object around() : invokeEvent() {
long start = System.currentTimeMillis();
Object object = proceed();
long took = System.currentTimeMillis() - start;
if (took > TIMEOUT) {
throw new RuntimeException("timeout! it took:" + took);
}
return object;
}
}