Одним из наиболее полезных нововведений в области JUnit были Правила. Я написал о правилах здесь . И я написал о случаях использования для правил JUnit здесь . Правила отличные. А с JUnit 4.9 они становятся еще лучше.
Вы можете думать о Правилах как о способе инкапсулировать установку и разбор теста в одном классе вместо двух методов. Но правила также способ изменить способ выполнения ваших тестов. Вы можете запускать тесты десятки раз вместо одного раза. Или в двадцати разных темах. Интересно, что были только Правила для одиночных испытаний. Поэтому, если вы хотите придерживаться сравнения с настройкой и разборкой, то есть, @Before и @After, в правилах не было эквивалента @BeforeClass и @AfterClass .
Теперь это изменилось. Теперь вы можете аннотировать открытое статическое поле типа TestRule с помощью @ClassRule, и оно будет вести себя подобно правилу, которое определено для всего класса теста, а не для одного теста. Так что он идеально подходит для вещей, которые нужно настроить один раз для всех тестов, а не для каждого теста. Давайте посмотрим на пример.
Реализация правила может выглядеть следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; public class LoggingRule implements TestRule { public class LoggingStatement extends Statement { private final Statement statement; public LoggingStatement(Statement aStatement, String aName) { statement = aStatement; } @Override public void evaluate() throws Throwable { System.out.println( "before: " + name); statement.evaluate(); System.out.println( "after: " + name); } } private final String name; public LoggingRule(String aName) { name = aName; } @Override public Statement apply(Statement statement, Description description) { System.out.println( "apply: " + name); return new LoggingStatement(statement, name); } } |
Большинство реализаций будет состоять из двух частей: реализация интерфейса TestRule и реализация интерфейса Statement.
TestRule заменяет устаревший интерфейс MethodRule, который использовался ранее. Это связано с тем, что новый интерфейс поддерживает оба правила на уровне класса и на уровне метода, поэтому его пришлось немного изменить. TestRule имеет единственный метод apply, который принимает Statement и возвращает Statement . Этот метод вызывается перед выполнением любого теста в области действия правила. Переданное утверждение фактически является тестами, которые могут быть выполнены. Здесь следует отметить две вещи: Statement может и будет представлять несколько тестов, если ваше правило будет использоваться с аннотацией @ClassRule ; И призыв применить не означает, что Заявление будет фактически выполнено. Так как все ваши возвраты Правил могут быть переданы другим Правилам, операторы могут быть искажены различными способами, прежде чем содержащиеся в них тесты будут фактически выполнены. Типичная вещь в методе apply — заключить оператор в новый оператор, который будет выполнять любую логику, необходимую для вашей цели.
Интерфейс Statement имеет единственный метод оценки, который должен выполнить тест или набор тестов в обычном случае. Поэтому, если вы придерживаетесь типичного подхода, упомянутого выше, вы выполняете некоторую оценку вызова установки для содержащегося в нем оператора и выполняете некоторые операции. В приведенном выше примере я печатаю материал на консоли, чтобы видеть, в каком порядке вызывается материал. Оператор также получает описание, которое содержит полезную мета-информацию о тесте (-ах). Он содержит имя, класс, в котором определен тест, имя метода и делает доступными аннотации. Таким образом, ваше Правило / Заявление может точно настроить его поведение на основе метода тестирования, с которым он работает.
Тестовый класс, использующий это правило, может выглядеть так:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; public class RuleTest { @ClassRule public static LoggingRule classRule = new LoggingRule( "classrule" ); @Rule public static LoggingRule rule = new LoggingRule( "rule" ); @Test public void testSomething() { System.out.println( "In TestSomething" ); assertTrue( true ); } @Test public void testSomethingElse() { System.out.println( "In TestSomethingElse" ); assertTrue( true ); } } |
Единственное изменение в правилах JUnit4.8 — это наличие аннотации @ClassRule . Обратите внимание, что один и тот же класс используется с аннотациями @ClassRule и @Rule .
При выполнении вывод тестового класса выглядит следующим образом:
01
02
03
04
05
06
07
08
09
10
11
|
apply: classrule before: classrule apply: rule before: rule In TestSomething after: rule apply: rule before: rule In TestSomethingElse after: rule after: classrule |
Как вы видите, сначала применяется правило уровня класса, и результирующий оператор оценивается. Только как часть оценки применяется правило уровня метода и результирующий оператор оценивается один раз для каждого теста.
Одно слово предостережения: будьте осторожны, чтобы использовать правильные модификаторы с вашими правилами. Они должны быть общедоступными, а правила уровня класса должны быть статическими. В зависимости от того, что вы делаете неправильно (и в какой среде вы работаете), возникающие ошибки могут быть не совсем полезными. Это считается ошибкой и исправления находятся в разработке.
Ссылка: правила в JUnit 4.9 (бета 3) от нашего партнера JCG Йенса Шаудера в блоге Schauderhaft .
Статьи по Теме :