2012-02-16 4 views
12

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

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

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

+0

Неудачные тесты модулей, поскольку они слишком длинные, являются частью структуры, которую вы используете для запуска этих тестовых примеров. Используете ли вы JUnit или TestNG? – Gaurav

+0

Я не хочу отказываться от отдельного модульного теста, я хочу, чтобы все сбои не выполнялись, если хотя бы один модульный тест занимает слишком много времени. Я использую JUnit и TestNG – smas

+0

Если вы не прошли один единичный тест, он также выйдет из строя, если вы не спросите плагин не слишком. – Gaurav

ответ

0

У меня когда-то было такое же требование, и поскольку я использовал TestNG, я использовал "group feature".

Если вы застряли с JUnit, попробуйте использовать набор тестов (http://stackoverflow.com/questions/817135/grouping-junit-tests)

+1

Вы также можете просто установить тайм-аут на уровне набора в файле testng xml. Gaurav

1

вы пробовали указать тайм-аут для теста через @Test (таймаут = хх)? Найти официальный апи документацию здесь: http://junit.sourceforge.net/javadoc/org/junit/Test.html

EDIT ---

Вы также можете использовать свойство тайм-аут для пакета TestNG, вам придется переместить все тесты на TestNG, хотя, но это позволит вам указать тайм-ауты для групп.

Это официальная апи документация: http://testng.org/javadoc/org/testng/xml/XmlSuite.html#setTimeOut(java.lang.String)

+1

Я не могу этого сделать, потому что у меня довольно большой проект и огромное количество тестов. – smas

+0

Проверьте мои изменения, я думаю, что с помощью testNg вы сможете указать тайм-аут для всего пакета –

4

Почему бы не добавить тайм-аут на тест на основе. Я предполагаю, что вы программируете на Java, так что в JUnit вы можете сделать что-то вроде этого:

@Test(timeout=100) public void testQuickly() 

Если тест не заканчивается через 100 миллисекунд, она не будет выполнена.

+2

Что делать, если у вас есть тесты gazillions и вы хотите иметь одно постоянное значение в секундах для контроля этих требований? Он не может быть установлен для каждого теста. – smas

4

В maven surefire вы можете использовать forkedProcessTimeoutInSeconds, а также forkMode=once.

Это убьет раздвоенный jvm, если он займет слишком много времени. Если вы хотите сделать это за каждый тест, вы можете forkMode = pertest или forkMode = always (что делает это для каждого класса).

+1

в реальном мире - forking не эффективен – smas

0

Попробуйте использовать задачу 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; 
    } 
} 
+0

Я это рассматривал, но мне нужен режим вилки, что неприемлемо для больших проектов. – smas

9

Если все тесты распространения какой-то базовый класс, я думаю, что вы может придерживаться @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 в базовом классе.

+1

Но в его сценарии у нас много тестовых случаев. Нам нужно расширить все тесты до BaseTestConfiguration. – om39a

+0

Хотя это дополнительный шаг к созданию тестов, это, безусловно, самая простая реализация, которую я еще видел. –

+0

Да, я понял, что это определенно критическое оговорка, что вам, возможно, придется внести первоначальные затраты, чтобы все ваши тесты расширили что-то, когда они этого еще не сделали. Поскольку ОП имеет больше информации, чем мы, полагал, что это стоит упомянуть в любом случае. –

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