В чем разница между отказом и ошибкой в ​​JUnit?


93

Я запускаю тесты JUnit на большой базе кода и понимаю, что иногда получаю «Ошибки», а иногда - «Сбои». Какая разница?

Ответы:


117

Хорошо, я только что заметил закономерность и думаю, что понял ее (поправьте меня, если я ошибаюсь). Мне кажется, что неудачи возникают, когда ваши тестовые примеры терпят неудачу, т.е. ваши утверждения неверны. Ошибки - это непредвиденные ошибки, возникающие при попытке запустить тест - исключения и т. Д.


5
Хотя, если что-то расширяется, java.lang.AssertionErrorэто будет показано как провал теста, а не как ошибка теста. Вам следует подумать о том, чтобы принять свой собственный ответ, потому что он правильный.
ponzao

Да, именно в этом разница. А с прагматической точки зрения «никакой разницы» нет - в том, что если вы получаете ошибку или сбой, то вам нужно это исправить. Поэтому, вероятно, было ошибкой подсчитывать «сбои» и «ошибки» в JUnit отдельно. JUnit 4 сочетает в себе два (как описано в ответе ниже).
Джефф Григг

И если ожидается исключение, вы должны аннотировать файл с @Testпомощью expected = SomeException.class.
Даунхиллски,

@JeffGrigg есть прагматическая разница. Если одно поведение используется в нескольких тестовых примерах, я все равно могу написать только один тестовый пример, который утверждает это поведение, при этом выбрасывая неперехваченные, вероятные исключения времени выполнения во всех остальных случаях. Это говорит о том, что остальные тестовые примеры проверяют что-то еще, хотя они все еще зависят от этого конкретного поведения для выполнения. Когда это поведение нарушено, только один тестовый пример сообщит об ошибке, а остальные сообщат об ошибке, и из этого я вижу, что мне нужно исправить ровно одну ошибку, даже если многие тестовые примеры не прошли.
RonJRH

org.junit.Assert.assertEquals () в случае сбоя считается ОШИБКОЙ в отчете JUnit4 HTML. Это противоречит вашему утверждению (о котором я знал до сих пор). Не могли бы вы пролить свет на это?
Кришном

15

Если ваш тест вызывает исключение, которое не всплывает через фреймворк Assertion в Junit, об этом сообщается как об ошибке. Например, исключение NullPointer или ClassNotFound сообщит об ошибке:

String s = null;
s.trim();

или,

try {

    // your code
} catch(Exception e) {
    // log the exception
    throw new MyException(e);
}

Сказав это, следующее сообщит об ошибке:

Assert.fail("Failure here");

или,

Assert.assertEquals(1, 2);

или даже:

throw new AssertionException(e);

Это зависит от версии Junit, которую вы используете. Junit 4- будет различать отказ и ошибку, но Junit 4 упрощает его только как отказы.

Следующая ссылка предоставляет более интересные материалы:

http://www.devx.com/Java/Article/31983/1763/page/2


Это не совсем так. В JUnit 4 не исчезло различие между провалом теста и ошибкой теста. Я только что его протестировал. Связанная статья вводила в заблуждение. В нем говорилось, что «JUnit 4 упрощает задачу, используя только отказы», ​​но следует подчеркнуть, что JUnit 4 превращает java.lang.AssertionError в сбои теста, поэтому вам не нужно использовать junit.framework.AssertionFailedError. Преимущество состоит в том, что вы можете начать писать тестовые утверждения в производственном коде без привязки проекта к JUnit. Различие между ошибкой теста и провалом теста также чрезвычайно полезно, и если бы его убрали, это было бы шагом назад.
RonJRH

RonJRH, можете ли вы увидеть ошибки в своем отчете junit по умолчанию?
Neel

Да, Нил. Я только что попробовал. Не совсем уверен в этике связывания изображений здесь, но это показывает результат моего теста: imagebucket.net/abpxucddkvn1/Capture.PNG
RonJRH

6

Из «Прагматического модульного тестирования в Java 8 с JUnit»:

Утверждения (или утверждения) в JUnit - это вызовы статических методов, которые вы добавляете в свои тесты. Каждое утверждение - это возможность проверить выполнение некоторого условия. Если заявленное условие не выполняется, тест сразу же останавливается, и JUnit сообщает об ошибке теста.

(Также возможно, что когда JUnit запускает ваш тест, возникает исключение, а не перехватывается. В этом случае JUnit сообщает об ошибке теста.)


5

Ниже тест объясняет разницу между ошибкой теста и провалом теста .

Я прокомментировал строку, которая выдает ошибку теста и провал теста.

    @Test
    public void testErrorVsTestFailure() {

        final String sampleString = null;

        assertEquals('j', sampleString.charAt(0) );
        //above line throws test error as you are trying to access charAt() method on null reference

        assertEquals(sampleString, "jacob");
        //above line throws Test failure as the actual value-a null , is not equal to expected value-string "jacob"
        }

Таким образом, Junit показывает ошибку теста всякий раз, когда вы получаете исключение, и провал теста, когда ожидаемое значение результата не соответствует фактическому значению.


2

Исходный класс: JUnitReportReporter.java

public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String defaultOutputDirectory) {
//......

            for (ITestResult tr : (Set) entry.getValue()) {
                TestTag testTag = new TestTag();

                boolean isSuccess = tr.getStatus() == 1;
                if (!(isSuccess)) {
                    if (tr.getThrowable() instanceof AssertionError)
                        ++errors;
                    else {
                        ++failures;
                    }
                }
}

Как вы можете видеть ниже, в приведенном выше методе

tr.getThrowable () instanceof AssertionError

количество ошибок увеличивается, если это экземпляр AssertionError, в противном случае (любой Throwable) считается ошибкой.


1

Вы правы в том, что сбои происходят из-за AssertionErrors, вызванных методами утверждения JUnit, или путем выброса AssertionError, или путем выброса исключения, которое вы объявили в своей @Testаннотации, а ошибки происходят из других, неожиданных исключений. Но между ними есть важное различие:

Ошибка означает, что ваш тест прошел правильно и выявил дефект в вашем коде.

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

Короче говоря, сбой означает, что вам нужно переписать тестируемый код. Ошибка означает, что это может быть юнит-тест, который нужно переписать. Это может означать это, даже если ошибка была в вашем коде, например NullPointerException, потому что вы обнаружили недостаток, который вы даже не тестировали, поэтому было бы разумно проверить это.


0

По иронии судьбы, junit и другие связанные с тестированием фреймворки (testng, hamcrest) предоставляют операции assert, которые проверяют условие, и в случае сбоя «под капотом» выдается ошибка java.lang.AssertionError, которая, кстати, расширяет java.lang.Error.

Но это никоим образом не противоречит приведенным выше ответам, которые, конечно, полностью действительны. Итак, чтобы пометить конкретный поток теста как сбой, можно выбросить AssertionError, однако я не уверен, что это действительно задокументировано в соответствующих руководствах, потому что более целесообразно использовать выделенный API fail (). Другие виды Throwable будут считаться ошибками, а не сбоями.


0

В основном, ошибки относятся к невыполненным утверждениям, в то время как ошибки возникают из-за ненормального выполнения теста . и я думаю, что в каждой IDE есть символические значки с разными цветами для проверки пройденного , неудачного и с ошибками .

Для получения дополнительной информации проверьте это .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.