Умовно ігноруючи тести в JUnit 4


365

Гаразд, тому @Ignoreанотація хороша для того, щоб відмітити, що тестовий випадок не повинен працювати.

Однак іноді хочеться проігнорувати тест на основі інформації про час виконання. Прикладом може бути тест, якщо я маю тест на сумісність, який потрібно запустити на машині з певною кількістю ядер. Якби цей тест був запущений на однопроцесорній машині, я не думаю, що було б правильним просто пройти тест (оскільки він не був запущений), і це, безумовно, було б невірно провалити тест і зламати збірку .

Тому я хочу мати можливість ігнорувати тести під час виконання, оскільки це здається правильним результатом (оскільки тестова рамка дозволить скласти пройти, але записати, що тести не виконувалися). Я впевнений, що анотація не надасть мені такої гнучкості, і підозрюю, що мені потрібно буде вручну створити тестовий набір для відповідного класу. Однак у документації нічого про це не згадується, і переглядаючи API , також не зрозуміло, як це було б виконано програмно (тобто як я програматично створюю екземпляр Testчи подібне, що еквівалентно тому, що створюється в @Ignoreанотації?).

Якщо хтось робив щось подібне в минулому або має яскраве уявлення про те, як ще я міг би про це піти, я був би радий почути про це.

Відповіді:


476

Спосіб JUnit - це зробити під час виконання org.junit.Assume.

 @Before
 public void beforeMethod() {
     org.junit.Assume.assumeTrue(someCondition());
     // rest of setup.
 }

Ви можете це зробити @Beforeметодом або самим тестом, але не @Afterметодом. Якщо ви зробите це в самому тесті, ваш @Beforeметод запуститься. Ви також можете зробити це всередині, @BeforeClassщоб запобігти ініціалізації класу.

Невдача припущення спричиняє ігнорування тесту.

Редагувати: Щоб порівняти з @RunIfприміткою від junit-ext , їх зразок коду виглядатиме так:

@Test
public void calculateTotalSalary() {
    assumeThat(Database.connect(), is(notNull()));
    //test code below.
}

Не кажучи вже про те, що набагато простіше захопити та використовувати з'єднання Database.connect()методом таким чином.


1
@notnoop, це зовсім не моє спостереження. Їх ігнорують. Тест-бігун IDEA повідомляє про них таким чином, а погляд на вихідний код JUnit показує, що він повідомляє про тест як проігнорований.
Yishai

1
Цитую: "У майбутньому це може змінитися, і невдале припущення може призвести до ігнорування тесту". Це фактично змінилося, як на 4,5 я вірю. Поточний javadoc каже: "Бігун JUnit за замовчуванням трактує тести з відмовними припущеннями як ігноровані. Спеціальні бігуни можуть вести себе інакше". github.com/KentBeck/junit/blob/…
Yishai

4
Eclipse 3.6 з Junit 4.8.1 повідомляє про помилкові припущення як проходження тесту. Те саме з мурашкою 1.8.1.
fijiaaron

8
Про те, що Eclipse повідомляє про невдалі припущення, як проходження - це помилка: bugs.eclipse.org/bugs/show_bug.cgi?id=359944
Мартін

1
@JeffStorey, тоді ти шукаєш пару речей. Одне - це @BeforeClassанотація, де ви можете припустити, що там не вдасться, що пропустить весь клас. Інший - @ClassRuleдля тонкозернистого контролю, але протягом усього класу, один раз).
Ісіхай

51

Ви повинні замовити Junit-extпроект. Вони мають RunIfанотацію, яка виконує умовні тести, наприклад:

@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
    //your code there
}

class DatabaseIsConnected implements Checker {
   public boolean satisify() {
        return Database.connect() != null;
   }
}

[Зразок коду, взятого з їх підручника]


3
Дякую за цю відповідь - цікавий альтернативний синтаксис для функціональності, хоча я буду працювати Assumeбезпосередньо, щоб не вводити іншу залежність.
Анджей Дойль

3
Я особисто віддаю перевагу цьому рішенню. Якщо у вас є багато тестів, які слід запустити на одних і тих же умовах, це було б набагато ідеальніше, ніж використання Assume в кожному тесті. Крім того, якщо це можна використовувати на рівні класу, а не на рівні методу, це буде ще ідеальнішим.
Річард

Я вважаю за краще, бо це допомагає умовно запустити тест під час виконання. Він підходить, коли буде проведено ряд одиничних тестів, і вимога полягає в тому, щоб запустити одиничні тести на певній контрольній програмі. Я дуже здивований, побачивши, що junit-ext не доступний у сховищі Maven. Як ми могли б скористатися цим у проекті Maven.
шамху

4
Анотація @RunIfподіляє умову, коли тест повинен запускатися від фактичного тестового коду, що я вважаю гарним. Що мені не подобається, це те, що він вимагає певного бігу тесту. Тому я написав правило JUnit, щоб умовно ігнорувати тести.
Rüdiger Herrmann

2
Після встановлення jar-ext jar (знайдено тут code.google.com/p/junit-ext/downloads/… ) у нашому локальному сховищі та впровадити цю анотацію @RunIf ... нічого! Це повністю ігнорується, і я думаю, що причиною може бути те, що, здається, junit-ext залежить від 4.5 червня. Нам потрібно 4,9+ завдяки весняному тестуванню. Тож ... не майте на увазі цього.
Марк

7

У JUnit 4 ще одним варіантом для вас може бути створення примітки, яка позначає, що тест повинен відповідати вашим спеціальним критеріям, а потім розширити запуск за замовчуванням на власне та за допомогою рефлексії базувати своє рішення на користувацьких критеріях. Це може виглядати приблизно так:

public class CustomRunner extends BlockJUnit4ClassRunner {
    public CTRunner(Class<?> klass) throws initializationError {
        super(klass);
    }

    @Override
    protected boolean isIgnored(FrameworkMethod child) {
        if(shouldIgnore()) {
            return true;
        }
        return super.isIgnored(child);
    }

    private boolean shouldIgnore(class) {
        /* some custom criteria */
    }
}

Хоча це виглядає приємно і чисто, воно не працює з поточними версіями, якщо JUnit4, оскільки метод більше BlockJUnit4ClassRunnerне пропонує isIgnored.
Дейв

-2

Швидка примітка: Assume.assumeTrue(condition)ігнорує решту кроків, але проходить тест. Щоб провести тест, використовуйте org.junit.Assert.fail()всередині умовного твердження. Працює так само, як Assume.assumeTrue()і тест не піддається.


5
Як зазначалося у відповідях вище, невдале припущення не викликає тестування, воно повертає окремий статус. Деякі бігуни можуть помилково повідомити про це як би пропуск, але це слабкість / помилка в тестовому бігуні (а бігун JUnit за замовчуванням відображає тест як ігнорований). А що стосується вашого остаточного речення, то невдача тесту - це не те, що я хочу (ред.).
Анджей Дойл

О, добре. У моєму випадку тести проходили з невдалим припущенням, але я хотів, щоб вони повідомлялися про невдалі (я перевіряв виняток з Тестового спостерігача). Вимушення невдачі мені допомогло.
TIN TIn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.