Как сделать множественную проверку(Soft Assertion) в тесте с использованием jUnit 4

Подскажите, пожалуйста, есть ли что-то подобное в jUnit, как softAssert в testNG?
Нужно, чтобы тест не вылетал, когда делаю первую проверку. Искала разную информацию, но конкретного ничего не нашла. Столкнулась с AssertJ, но ничего для решения своей проблемы не смогла найти. Всем спасибо!

Привет!
Можно попробовать использовать ErrorCollector:
http://junit.org/junit4/javadoc/4.12/org/junit/rules/ErrorCollector.html

AssertJ содержит в себе SoftAssertions:

3 лайка

Спасибо, буду пробовать.

Еще раз спасибо. ErrorCollector помог, а вот с SoftAssertions не подружилась. Идея не видит їх (Can not resolve symbol SoftAssertions), хоть dependencies прописала (testCompile ‘org.assertj:assertj-core:3.6.2’). Может что-то еще надо добавить? Спасибо.

универсальное решение:
оборачиваете любой ассерт(любое условное выражение - если вы хотите делать скриншот на каждую ошибку) в try catch, и собираете ошибки не вылетая из программы
Подозреваю что ErrorCollector так и делает)

1 лайк

Спасибо. Да, такой принцип в ErrorCollector.

JUnit 5 предлагает метод Assertions.assertAll именно для такой цели - выполнить несколько assert, и увидеть в отчете результаты всех, даже если упал первый. Переходите на версию 5:slightly_smiling_face:

вероятно, что:
1 - вам не совсем подходит уровень доступа.
Когда вы пишете testCompile, то это значат что импортированная либа будет видна только в тестовых классах, просто compile - везде.
2 - возможно (в зависимости от того, на какой версии гредла вы находитесь) - вам нужно написать не testCompile/compile, а testImplementation/implementation, соответственно :slight_smile:

AssertJ - assert softly mode
пример
http://joel-costigliola.github.io/assertj/core/api/org/assertj/core/api/SoftAssertions.html

  1. Добавить в зависимости библиотеку assertj-core
    Пример для Gradle: testCompile group: 'org.assertj', name: 'assertj-core', version: '3.11.1'
  2. В Классе с тестами добавить импорт import org.assertj.core.api.SoftAssertions;
  3. Создать переменную типа SoftAssertions
    Например: private SoftAssertions softAssertions = new SoftAssertions();
  4. Использовать в тестах.
softAssertions.assertThat(actualRequiredResult)
                .isEqualTo(expectedRequiredResult);
        softAssertions.assertThat(actualRequiredResultIgnoreCase)
                .isEqualToIgnoringCase(expectedRequiredResultIgnoreCase);
  1. В конце теста проверить все
softAssertions.assertAll();

Мне показалось решение с рулой ErrorCollector’а куда удобнее. Сделал поле в базовом классе, в него через свою обертку добавляю ошибки, в конце через After или в TestWatcher в том же базовом классе проверяю коллекцию на наличие ошибок, если непустая, то вывожу их все. В итоге нет проблемы с тем, что что-то забыл обработать или вызвать в конце assertAll и т.п. Единственный минус (точнее недоработка, которая может потребовать допилки) кроется в том, если софт ассерт нужен на блоки теста, но при наличии ошибок блок и тест должен прерываться. Но это можно также реализовать через дополнительный метод по аналогии с assertAll

объек софт ассерта в базовый класс
soft assert object - в бефор ич
assertAll - в афтер ич

все тесты покрыты - тест класс чистый
никакой кастомной логики = 0 времени в год на саппорт
что важно - это принты ошибок assertj

 org.assertj.core.api.SoftAssertionError: The following 4 assertions failed:
 1) [Living Guests] expected:<[7]> but was:<[6]>
 2) [Library] expected:<'[clean]'> but was:<'[messy]'>
 3) [Candlestick] expected:<'[pristine]'> but was:<'[bent]'>
 4) [Professor] expected:<'[well kempt]'> but was:<'[bloodied and disheveled]'>

В обоих случаях саппорт = 0 или около того. Не вижу проблему в кастомных вещах. Если бы люди боялись кастомить, то не было бы ни AssertJ, ни Allure, ни Selenide, ни JDI, ни Atlas, и т.д. В моем случае я сразу получаю возможность выводить в отчёт аллюры и сами проверки, а не только упавшие, а также сделать проверку вариативную к данным для параметризированных сценариев. При этом я конечно вижу и минусы и более того тот проект был пробным для меня и многие вещи сейчас я бы делал уже по другому.

Свой предыдущий комментарий я написал даже не с целью агитации за AssertJ, ErrorCollector или что-то другое, а что важно при работе с софт-ассертами их обрабатывать в конце сценария и лучше всего это вынести в базовый класс в after метод и тогда это будет в едином месте и не будет проблемы с ложно-положительными проверками по забывчивости/оплошности.

А в чем смысл soft assert? Все равно ж писать все ассерты и потом еще одним обернуть.

чтобы проверить все а не падать сразу при первой ошибке

Пример:
Сразу все независимые друг от друга элементы на странице проверить.

Я делал просто:
Через цикл проверял элементы в Try.run() и собирал коллекцию ошибок

Смысл зависит от уровня тестирования. Если это модульные или компонентные и даже интеграционные тесты, то смысла в них не так много и там они почти не применяются, особенно в модульных тестах. Но чем выше по пирамиде, чем медленнее тесты и чем выше сложность тестируемого взаимодействия, то тем выше необходимость находить все проблемные места за один прогон теста, а не заниматься футболом: баг-фикс-снова баг-новый фикс. Наибольшую пользу данных проверок я вижу в API тестировании. Причём даже там проверки мягкие не отменяют жестких, они работают в симбиозе.

В играх есть такой термин - Triple A games (AAA). В тестировании также присутствует такой же термин, но с другим смыслом - AAA (Arrange, Act, Assert). Он означает, что нужно подготовить тестовый случай, выполнить действие и далее провести проверку. Так, вот в случае модульных тестов проверка делается чаще всего одна-две и выявляются ошибки и делаются исправления максимально быстро ещё в процессе разработки функционала, до передачи в тестирование. Поэтому там soft-assert’ы не очень нужны, хотя бывает и их применяют.

Но если мы хотим проверить что-то более глобальное, например, работу сервиса по заведению клиентов, допустим он называется createPerson, при его вызове будет создано несколько записей в разных таблицах: Person, Document, Address и т.д. Более того, данный сервис сделает запись в логе и в базе аудита, а также вызовет какие-то внешние системы и вернёт до кучи вам ответ об успешности выполнения и какую-то информацию об этом в ответе, например, Id этого пользователя. А теперь внимание вопрос: вам нужно проверить сценарий заведения нового клиента через вызов этого API. Как будете проверять? Допустим у вас реально есть 10 ошибок в реализации сервиса. Т.е. если использовать обычные assert, то вы упадете на первой же проверке, допустим на ответном сообщении. Но при этом вы не будете обладать никакой информацией о том, что произошло в базе, что записалось в лог и в аудит, что передалось во внешние системы и т.д. И после исправления этой ошибки, вы же нашли только одну ошибку при “жестком” ассерте, следующий прогон этого же теста выявит вторую, дальше третью… и т.д. Привет сборная программирования по футболу багов.

3 лайка

за такие советы вам на ревью от сеньоров не слабо так “влетит”

1 лайк