Статьи

Правило JUnit для условного игнорирования тестов

Я всегда считал, что использование @Ignore для деактивации тестов — плохая идея. За исключением, может быть, одного из способов поместить тесты, которые периодически прерываются, в карантин, чтобы потом заняться ими (как это описывает Мартин Фаулер здесь ). Это несет в себе опасность того, что набор тестов затухает, поскольку все больше и больше тестов продолжают игнорироваться и забываться. Поэтому у вас должна быть политика, гарантирующая, что тесты не будут помещены в карантин слишком долго. Ну, так я думал до недавнего времени, когда мы столкнулись с этим:

В проекте, над которым мы с Фрэнком работаем, мы столкнулись с проблемой SWT, описанной здесь .
На платформах, отличных от Windows, подтверждение того, что виджет SWT получил фокус ввода, не работает с автоматическими тестами.

Мы решили пока игнорировать фокус-тесты на платформах, отличных от Windows. Хотя наш сервер сборки работает на Linux, мы нашли его достаточно безопасным, поскольку обе наши среды разработки работают на Windows.

В JUnit допущения являются средством пропуска тестов, которые не имеют смысла при данном условии. Выражаясь таким образом, наш тест будет выглядеть так:

1
2
3
4
public void testFocus() {
  assumeTrue( isRunningOnWindows() );
  // ...
}

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

Это привело нас к созданию аннотации ConditionalIgnore и соответствующего правила для ее привязки к среде выполнения JUnit. Это просто и лучше всего объяснить на примере:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
public class SomeTest {
  @Rule
  public ConditionalIgnoreRule rule = new ConditionalIgnoreRule();
 
  @Test
  @ConditionalIgnore( condition = NotRunningOnWindows.class )
  public void testFocus() {
    // ...
  }
}
 
public class NotRunningOnWindows implements IgnoreCondition {
  public boolean isSatisfied() {
    return !System.getProperty( "os.name" ).startsWith( "Windows" );
  }
}

Для аннотации ConditionalIgnore требуется свойство ‘condition’, которое указывает на класс, реализующий IgnoreContition. Во время выполнения создается экземпляр реализации IgnoreCondition, и его метод isSatisfied () решает, будет ли тест проигнорирован (возвращает true) или нет (возвращает false). Наконец, есть IgnoreConditionRule, который подключает аннотации в среду выполнения JUnit.

Если реализация IgnoreCondition решает игнорировать контрольный пример, генерируется исключение AssumingViolatedException. Следовательно, аннотация ConditionalIgnore имеет такой же эффект, как если бы условие Assume вернуло false. С небольшим отличием, которое мы считаем преимуществом: методы @Before и @After не выполняются для игнорируемых тестов.

Исходный код правила и связанных с ним классов можно найти здесь .

Остается проблема с предположением , что это влияет на статистику теста. Если условие Assume окажется ложным, тест будет считаться пройденным, даже если он не был выполнен. Чтобы преодолеть это, вы должны предоставить своего собственного бегуна, который обрабатывает AssumpViolatedException так, как вы хотите.

Несмотря на то, что я только что написал об игнорировании длительности тестов, я все же убежден, что тесты в лучшем случае не следует игнорировать, и если да, то только в исключительных случаях.

Ссылка: Правило JUnit об условном игнорировании тестов от нашего партнера по JCG Рудигера Херрманна в блоге Code Affine .