Вопрос по – Отсутствующие ветви при использовании assertTrue вместо assertNull

16

В Java / Junit мне нужно проверить на ноль с некоторым объектом. Есть несколько способов проверить состояние, но я использовал assertTrue для большинства моих тестов. Когда я проверяю нулевые значения в assertTrue, EclEmma заявляет, что тестирует только одну ветку.

Когда я разрешаю оператор в переменную вручную (например, устанавливаю логическое значение результата и передаю его в assertTrue), покрытие кода считается завершенным в assert, но не в строке инициализации переменной.

Почему это происходит? Связано ли это с дополнительным байтовым кодом, который Java явно добавляет, как упомянуто наhttp://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions? Любые решения (кроме использования других утверждений assert).

assertTrue:

<code>assertTrue( myObject == null ); //1 of 2 branches
</code>

assertTrue:

<code>boolean test = (myObject == null); //1 of 2 branches missing
assertTrue(test); // complete
</code>

assertNull:

<code>assertNull( myObject ) //complete;
</code>
@nansen Это правда, и у меня нет проблем с использованием assertNull, если это является требованием, однако, IMO, все assert & quot; types & quot; это просто еще одна форма assertTrue. Могут быть добавлены преимущества использования различных типов утверждений, такие как добавление информации об ошибках / удобочитаемости, но здесь это не является проблемой. Dalin Seivewright
Основная проблема не связана с выполнением покрытия в тестовом коде и не связана с использованием assertNull по сравнению с assertTrue. avandeursen
@nansen Это не значит, что я отказываюсь использовать assertNull и, вероятно, буду его использовать, я просто нашел эту конкретную проблему интересной, поскольку я в основном проверяю одно и то же, но Эмма дает совершенно разные результаты. Dalin Seivewright
Почему вы используете покрытие кода в своем тестовом коде? Я не думаю, что кого-то должно волновать, проверены ли все ваши ветви тестового кода; это кажется глупым. Jesse Webb
Что не так с утверждением нуля с помощью assertNull? Обычно лучше использовать подходящий тип assert для того, что утверждается. Вы лучше поймете, что не так, когда тест не пройден, не копаясь в тестовом коде. nansen

Ваш Ответ

3   ответа
1

что Эмма рассматривает условное выражение как «что-то с ветвью» для (ветки) подсчета покрытия ИМХО кажется просто неработающим. Это не условная ветвь.

Мы можем спорить больше об Assert; если он был определен как «выдает исключение при ошибке подтверждения» тогда у этого действительно есть условная ветвь; если он определен [как я думаю, я не являюсь экспертом по Java] как «завершить мою программу при ошибке подтверждения» тогда это не совсем ветвь. Также неясны вызовы методов; этиare условные переходы в том смысле, что если вызываемый метод выдает исключение, поток управления не переходит к «остатку инструкции».

нашТестирование Java инструмент получает (ветвь) анализ покрытия по таким условным словам "правильно".

Я согласен, что назвав эту функцию Эмма / JaCoCobranch coverage (очень) сбивает с толку. (Отдельная) информация о покрытии, сообщающая мне для любого логического (под) выражения, было ли оно оценено как true и false, является полезной функцией.
Спасибо, Ира, ты заставил меня задуматься, и я серьезно отредактировал ответ.
В методах assertTrue / assertNull из JUnit API нет ничего особенного. Они просто генерируют ошибку java.lang.AssertionError, если условие не выполняется. Это не имеет прямого отношения к Javaassert ключевое слово.
@avandeursen: определить, каждый лиcondition в программе было реализовано как "правда" или "ложь" не является охватом филиала; это "покрытие условий". Конечно, наш инструмент не выполняет условия покрытия; Исходя из прошлого понимания, я не верю, что Эмма делает покрытие условий, но я могу быть удивлен.
0

выполните следующие действия.

Class RecordService{


    public boolean doesRecordExist(String id){

    return id!=null;

    }


    }

    //Method inside your mock
    @Test
    public boolean testDoesRecordExist(){
    RecordService recordService = mock(RecordService.class);
    when(recordService.doesRecordExists()).thenReturn(
                    anyString()).thenReturn(null);

    }
21

льные ветви в байтовом коде. JaCoCo производит «покрытие филиала»; основанный на сгенерированном байт-коде, не основанный на исходном коде Java, и, следовательно, показывает дополнительную информацию о покрытии ветви для почти любого логического выражения, которое вы бы использовали.

В вашем коде булево выражение, которое вы используетеmyObject == null.

Чтобы вычислить это значение, компилятор Java генерирует код, выдвигающий два аргумента в стеке, а затем выполняет условный переход для добавления 1 (true) или 0 (false) в стек. JaCoCo сообщает об охвате ветви этого условного перехода.

Таким образом, тот факт, что вы используетеmyObject == null запускает поведение, которое вы описываете.

Как некоторые другие примеры, попробуйте это:

boolean t = true;
boolean f = false;
boolean result1 = (t && f) || f; // 3 out of 6 missed.
boolean result2 = !t;            // 1 out of 2 missed.

Это может быть полезно, если булево выражение, например, возвращается функцией, которая используется в качестве условия в операторе if-then-else где-то еще. Хотя это в основном следствие того, как работает компилятор Java, оно помогает оценитьcondition покрытие (вместо простогоbranch покрытие) исходного кода Java.

Эта функция не слишком хорошо документирована, но вот несколько советов:

The JaCoCo test cases for Boolean Expressions A JaCoCo forum discussion on branches generated for the statement a = !a does anyone have a pointer to more documentation?

Таким образом, это действительно связано с генерируемым дополнительным байтовым кодом, но не с конкретными примерами синтетических конструкций байтового компилятора, для которых предназначены параметры фильтрации.

ПРИМЕЧАНИЕ. Значительная РЕДАКТИРОВАТЬ, так как первоначальный ответ был слишком много предположений. Спасибо @ ira-baxter за хорошее & amp; критическое обсуждение.

Похожие вопросы