Яке фактичне використання "провалу" у тестовому випадку JUnit?


Відповіді:


137

Деякі випадки, коли я вважаю це корисним:

  • позначте тест, який є неповним, тому він провалюється та попереджає вас, поки не зможете його закінчити
  • переконайтесь, що викид:
try{
  // do stuff...
  fail("Exception not thrown");
}catch(Exception e){
  assertTrue(e.hasSomeFlag());
}

Примітка:

Оскільки JUnit4, існує більш елегантний спосіб перевірити викид виключення: Використовуйте примітку @Test(expected=IndexOutOfBoundsException.class)

Однак це не спрацює, якщо ви також хочете перевірити виняток, тоді вам все одно потрібно fail().


5
Розгляньте цю публікацію в блозі про відносні достоїнства невдач та очікуваної анотації: blog.jooq.org/2016/01/20/…
lbalazscs

4
@sleske "якщо ви також хочете перевірити виняток, тоді вам все одно потрібні fail ()" - nope. Очікуваневизнання - це шлях, дивіться github.com/junit-team/junit4/wiki/exception-testing
kraxor

@kraxor: Правда, не знав про це, коли я писав відповідь (це, мабуть, тоді навіть не було).
sleske

14

Скажімо, ви пишете тестовий випадок для потоку -ve, де тестований код повинен створити виняток

try{
   bizMethod(badData);
   fail(); // FAIL when no exception is thrown
} catch (BizException e) {
   assert(e.errorCode == THE_ERROR_CODE_U_R_LOOKING_FOR)
}

10

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

Щось на зразок наступного псевдо-коду:

test_addNilThrowsNullPointerException()
{
    try {
        foo.add(NIL);                      // we expect a NullPointerException here
        fail("No NullPointerException");   // cause the test to fail if we reach this            
     } catch (NullNullPointerException e) {
        // OK got the expected exception
    }
}

3
Якщо ви не перевірите щось у блоці вилову, ви можете використовувати анотацію методу @ExpectedException (NullNullPointerException.class), щоб заявити, що очікуєте винятку (спеціального виду).
FrVaBe

8

Я використовував його в тому випадку, коли щось могло зіпсуватися в моєму методі @Before.

public Object obj;

@Before
public void setUp() {
    // Do some set up
    obj = new Object();
}

@Test
public void testObjectManipulation() {
    if(obj == null) {
        fail("obj should not be null");
     }

    // Do some other valuable testing
}

1
Так, передумови тестування хороші. Однак якщо ви хочете переконатися, що @Beforeметод досяг успіху, можливо, краще перевірити його безпосередньо в цьому методі. Як бонус, принаймні JUnit і TestNG навіть повідомлять про інший збій за помилки з @Before/ @Afterметодів, тож можна побачити, що проблема була не в самому тесті.
sleske

4

Ось так я використовую метод Fail.

Є три стани, до яких може закінчитися ваш тестовий випадок

  1. Пройдено: Тестова функція успішно виконується і повертає дані, як очікувалося
  2. Не пройшов: Тестова функція виконана успішно, але повернуті дані були не такими, як очікувалося
  3. Помилка: Функція не виконувалася успішно, і це не було

призначений (на відміну від негативних тестових випадків, які очікують винятку).

Якщо ви використовуєте затемнення, три стани позначені зеленим, синім та червоним маркером відповідно.

Я використовую операцію відмови для третього сценарію.

наприклад: public Integer add (integer a, Integer b) {повернути новий Integer (a.intValue () + b.intValue ())}

  1. Пройдений випадок: a = новий Interger (1), b = новий цілий номер (2) і функція повертається 3
  2. Не пройдений випадок: a = новий Interger (1), b = новий цілий число (2) і функція повертає сумарне значення, відмінне від 3
  3. Failed Case: a = null, b = null, і функція передає NullPointerException

1
Якщо ви подивитесь на вихідний код JUnit, ви побачите, що твердження використовують fail().
Даніель К. Собрал

3

Я, наприклад, використовую fail()для позначення тестів, які ще не закінчені (це буває); інакше вони показали б як успішні.

Можливо, це пов'язано з тим, що я не знаю про якийсь неповний () функціонал, який існує в NUnit.


2

У паралельних та / або асинхронних налаштуваннях ви можете переконатися, що певні методи (наприклад, делегати, слухачі подій, обробники відповідей, ви їх називаєте) не викликаються. Знущаючись з фреймворків убік, можна зателефонуватиfail() ці методи провалити тести. Термін очікування, який минув, є ще одним природним умовою відмови в таких сценаріях.

Наприклад:

final CountDownLatch latch = new CountDownLatch(1);

service.asyncCall(someParameter, new ResponseHandler<SomeType>() {
    @Override
    public void onSuccess(SomeType result) {
        assertNotNull(result);
        // Further test assertions on the result
        latch.countDown();
    }

    @Override
    public void onError(Exception e) {
        fail(exception.getMessage());
        latch.countDown();
    }
});

if ( !latch.await(5, TimeUnit.SECONDS) ) {
    fail("No response after 5s");
}

0

Найважливіший випадок використання - це, мабуть, перевірка виключень.

Хоча junit4 включає очікуваний елемент для перевірки того, чи стався виняток, схоже, що він не є частиною нової версії5. Ще одна перевага використання fail()над тим expected, що ви можете комбінувати його з finallyдозволом очищення тестових випадків.

dao.insert(obj);
try {
  dao.insert(obj);
  fail("No DuplicateKeyException thrown.");
} catch (DuplicateKeyException e) {
  assertEquals("Error code doesn't match", 123, e.getErrorCode());
} finally {
  //cleanup
  dao.delete(obj);
}

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

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