Подтвердить что ты не робот

Должно ли сообщение JUnit указывать состояние успеха или неудачи?

Я могу написать сообщение об утверждении одним из двух способов. Успех объявления:

assertEquals( "objects should be identical", expected, actual );

Или заявив условие нарушения:

assertEquals( "objects aren't identical", expected, actual );

Есть ли стандарт для этого в JUnit? Если нет, то каковы аргументы для каждой стороны?

P.S. Я видел статьи в Интернете, демонстрирующие их без объяснения причин, поэтому просто сказать "искать Google" - это не ответ!

[ОБНОВЛЕНИЕ]

Все зацикливаются на том, что я использовал assertEquals, и поэтому сообщение, вероятно, бесполезно. Но, конечно, только потому, что я хотел просто проиллюстрировать вопрос.

Итак, представьте себе, что это:

assertTrue( ... big long multi-line expression ... );

Если сообщение полезно.

4b9b3361

Ответ 1

Я редко даже беспокоюсь о сообщении, по крайней мере, для assertEquals. Любой разумный тестировщик объяснит, что вы использовали assertEquals и две вещи, которые должны были быть равными. Ни одно из ваших сообщений не дает больше информации.

Я обычно обнаруживаю, что unit test неудачи - это переходные вещи - я быстро узнаю, что неправильно и исправить. "Обнаружение того, что неправильно" обычно включает в себя достаточно подробностей, что одно сообщение не будет иметь большого значения. Рассмотрим "время, сохраненное при наличии сообщения", и "время, потраченное на мышление сообщений":)

EDIT: Хорошо, один случай, когда я мог бы использовать сообщение: когда в тексте есть компактное описание, которое не очевидно из строкового представления объекта.

Например: "Ожидаемая дата должна быть 1 декабря" при сравнении дат, сохраненных в миллисекундах.

Я бы не стал беспокоиться о том, как вы это выражаете, хотя: просто убедитесь, что это очевидно из сообщения, которое вы подразумеваете. Либо "должно быть", либо "не было" - это хорошо - просто "1 декабря" не будет очевидно.

Ответ 2

В соответствии с API-интерфейсом junit сообщение является "идентификационным сообщением для AssertionError", поэтому это не сообщение, описывающее условие, которое должно выполняться, но сообщение, описывающее, что неправильно, если условие не выполняется. Поэтому в вашем примере "объекты не идентичны", как представляется, более совместимы.

Ответ 3

В отличие от многих других, я чувствую, что использование сообщения чрезвычайно полезно по многим причинам:

  • Лицо, просматривающее журналы неудавшегося теста, может быть не тем человеком, который написал тест. Это может занять время, чтобы прочитать код и понять, в каком случае это утверждение предназначено для решения. Полезное сообщение сэкономит время.

  • Даже в случае, если разработчик теста просматривает журналы, это может быть дни или месяцы с момента написания теста, и снова сообщение может сэкономить время.

Моим советом было бы написать сообщение с выражением о ожидаемом поведении. Например:

assertEquals("The method should be invoked 3 times", 3, invocationCount);

Ответ 4

Я не думаю, что это имеет значение вообще. Вы уже знаете, что произошел сбой, и поэтому не имеет значения, говорится ли в сообщении, что должно было произойти, или что не должно произойти.

Цель сообщения - помочь вам, когда это возможно, а не получить некоторую полноту.

Очевидно, что в случае assertEquals это менее важно, но сообщение важно в случае общих утверждений. Сообщение должно помочь вам получить достаточно контекста, чтобы сразу понять, что именно не удалось.

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

Ответ 5

Я хотел бы ответить на вопрос, не учитывая, полезно ли сообщение в generel.

Если тест не прошел, что-то не так. Я знаю это. Я хочу знать, почему он сломан. Это очень легко узнать, потому что я просто должен открыть тестовый пример и SUT. Как сказал Джон, очень легко исправить это (надеюсь,;-)).

Но как насчет сообщения? Сообщение для меня - совет, что можно сделать, чтобы превратить его в зеленый тестовый пример. Поэтому я был бы признателен, если бы в тексте сообщения были рекомендации, как исправить эту проблему или где искать проблему.

Еще один интересный аспект - использование положительных выражений. Стоит рассмотреть возможность использования положительных текстовых сообщений. В вашем примере я бы использовал Objects should be identical. Но это небольшая причина.

Ответ 6

Проголосуйте также (например, Jon), но единственный раз, когда я когда-либо использовал такое сообщение (на assert equals), является создание одного теста с матрицей значений и один из тестовых элементов: я используйте сообщение, чтобы указать, какой тестовый пример завершился неудачно. В противном случае текст полностью избыточен.

Ответ 7

Из javadocs JUnit:

Утверждает, что два объекта равны. Если они не являются AssertionFailedError бросается с данным сообщением.

Согласно API, сообщение может быть любым, что вы хотите. Я бы сказал, что два варианта, которые у вас есть, одинаковы и оба лишние. Успех или неудача assert уже предоставляет всю информацию, которую вы предоставляете в сообщении.

Из этого следует, что у вас должно быть либо ничего (есть утверждение, которое не принимает целую строку) ИЛИ включать сообщение со значением, выходящим за пределы того, что уже существует.

Итак, я думаю, что это повторение ответа Джона, но слишком подробный, чтобы быть комментарием.

Ответ 8

Я вижу этот вопрос с двух сторон,

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

Вторая перспектива - это тот, кто читает/поддерживает/просматривает код: Как мы говорили с возрастом о читаемости и простоте кода. Таким образом, это также не менее важно.

Мы убеждены, что мой код должен быть простым и самоочевидным, чтобы не было явных комментариев, и я категорически согласен с ним.

С этой точки зрения:

Эти сообщения облегчают чтение и просмотр кода, поскольку они служат для двойной цели документации, а также для сообщения об ошибках:

assertEquals( "objects should be identical", expected, actual );
assertTrue( "flag should have been set", flag );
assertNotNull( "object must not be null", object );

Эти сообщения не настолько дружелюбны к читателям, поскольку они говорят о неожиданном состоянии:

assertEquals( "objects aren't identical", expected, actual );
assertTrue( "flag is not set", flag );
assertNotNull( "object is null", object );

Ответ 9

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

Ответ 10

Я согласен с тем, что предоставление сообщения полезно, и я всегда предоставляю его.

Для меня полезной вещью является четкое утверждение о том, что пошло не так - обычно с участием слов "should" или "should not".

Например, "объекты равны" неоднозначны - означает ли это, что объекты равны и почему тест не прошел? Или что объекты должны быть равными, но это не так? Но если вы говорите: "Объекты должны быть равны" или "Объекты не должны быть равными", это очевидно, почему утверждение не получилось.

Ответ 11

Мне особенно нравится, как среда тестирования Spock поощряет тесты, которые читаются как история, и аналогичным образом пришли к структурным испытаниям в разных рамках. Меня не особенно беспокоит индивидуальное сообщение об ошибке, имеющее большой смысл, я стремился быстро обернуть мою голову вокруг всего теста, как только открою его:

assertEquals("Cloned and persisted items", mockedTiCount, clonedTis.size());
assertTrue("Belong to new transaction", clonedTis.stream().allMatch(ti -> ti.getTransaction().getId().equals(cloned.getId())));
assertNotEquals("Which has a different ID", t.getId(), cloned.getId());
assertEquals("While the originals are left intact", mockedTiCount, transactionItemRepository.findByTransactionId(t.getId()).size());

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

Ответ 12

Согласно спецификациям, сообщение должно описывать ошибку, когда это происходит. И полезно, когда вы создаете приложение в среде CI, например, Jenkins, и используете плагины для анализа результатов ошибок.

http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertTrue (java.lang.String, boolean)

Parameters:
message - the identifying message for the AssertionError (null okay)
condition - condition to be checked