Я вижу несколько причин для этого, особенно при использовании JUnit для запуска функциональных тестов или тестирования постоянных объектов. Например, рассмотрим объект Article
, который сохраняется в каком-то постоянном хранилище. Если бы я хотел проверить функциональность вставки, обновления и удаления объекта Article
, следуя принципу модульного теста «все тесты должны быть переупорядочиваемыми и тестировать только определенную часть функциональности», у меня было бы три теста:
testInsertArticle()
testUpdateArticle()
testDeleteArticle()
Однако, чтобы протестировать функциональность обновления, мне сначала нужно вставить статью. Чтобы проверить функциональность удаления, мне также нужно вставить статью. Таким образом, на практике функциональность вставки уже проверена как в testUpdateArticle()
, так и в testDeleteArticle()
. Затем возникает соблазн просто создать тестовый метод testArticleFunctionality()
, который все это делает, но такие методы в конечном итоге получат огромный объем (и они не будут просто тестировать часть функциональности объекта Article
).
То же самое относится и к запуску функциональных тестов, например, против успокоительного API. JUnit отлично подходит и для этих случаев, если бы не недетерминированный порядок тестов.
Тем не менее, я расширил OrderedRunner
Майкла Д., чтобы использовать аннотации для определения порядка тестов, просто подумал, что должен поделиться. Его можно расширить, например, указав, от каких именно тестов зависит каждый тест, но сейчас я использую это.
Вот как это используется. Это позволяет избежать необходимости называть такие тесты, как AA_testInsert()
, AB_testUpdate()
, AC_testDelete()
, ..., ZC_testFilter()
и т. Д.
@RunWith(OrderedRunner.class)
public class SomethingTest {
@Test
@Order(order=2)
public void testUpdateArticle() {
// test update
}
@Test
@Order(order=1)
public void testInsertArticle() {
// test insert
}
@Test
@Order(order=3)
public void testDeleteArticle() {
// test delete
}
}
Независимо от того, как эти тесты помещаются в файл, они всегда будут запускаться как order=1
первый, order=2
второй и последний order=3
, независимо от того, запускаете ли вы их из Eclipse, с помощью Ant или любого другого Другой путь.
Реализация следует. Сначала аннотация Order
.
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
public int order();
}
Затем модифицированный OrderedRunner
.
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> list = super.computeTestMethods();
Collections.sort(list, new Comparator<FrameworkMethod>() {
@Override
public int compare(FrameworkMethod f1, FrameworkMethod f2) {
Order o1 = f1.getAnnotation(Order.class);
Order o2 = f2.getAnnotation(Order.class);
if (o1 == null || o2 == null)
return -1;
return o1.order() - o2.order();
}
});
return list;
}
}