Подтвердить что ты не робот

Maven - сборка сбоев, когда unit test занимает слишком много времени

У меня в моем проекте много модульных тестов, написанных в JUnit и TestNG. Процесс сборки основан на maven с плагином surefire.

Есть ли какой-либо способ/плагин для maven для сбоя сборки, если хотя бы один unit test занимает слишком много секунд? Я знаю, что есть некоторые плагины, которые не могут выполнить сборку в TeamCity, Дженкинс, но это "слишком далеко".

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

4b9b3361

Ответ 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;
    }
}