Здравствуйте, scf, Вы писали:
K>>И у меня из этого возникла некая концепция “тяжёлых ассертов”, которую я хочу рассказать.
scf>property based testing?
scf>https://dev.to/jdsteinhauser/intro-to-property-based-testing-2cj8
Ассерты это совсем не тесты. Ассерты это проверка предусловий, постусловий, инвариантов в самом коде. Если ассерты легкие, они работают всегда. Если тяжелые, только по требованию, например, на стейджинге.
Разница между ассертами и тестами в том, что тесты проверяют небольшое ограниченное количество условий, ассерты проверяют всё, что проходит через функцию.
Например, у тебя есть функция, которая работает с BigInt, принимает BigInt и возвращает некоторый результат, который должен обладать определнными свойствами. Сколько тестов ты можешь себе позволить ? Ну 10, ну 100, может даже 1000. То есть, тесты очень дискретны — на фоне всего диапазона BigInt это почти ничего.
Для ассерта нужна функция, которая проверит, скажем, инвариант цикла или пост-условие, и будет делать это всегда, для всего диапазона BigInt.
Соответсвенно такой подход позволяет обнаружить совсем другой класс ошибок, который автоматическими тестами никак не покрывается. В свою очередь ассерты так же не покрывают весь класс ошибок, который обнаруживается тестами.
Следовательно, по уму, должны быть и тесты, и ассерты, они дополняют друг друга.
Пример, допустим, у нас есть внятное логирование
"операция x в очереди"
"операция x стартовала"
"операция x перешла в состояние XYZ"
"assert: ожидаемое состояние операции ZYX"
"операция x завершилась"
Для документирования ошибок необходимо найти все девиации
1 операции которые завершились, но почему то не стартовали — потенциально, некто неизвестные шедулит операции кастомным кодом
2 операции, которые стартовали, но не завершились, — не ясно, то ли зависло, то ли есть кастомный код, который завершает, то ли операция обрывается и дохнет
..
n паттерны assert: — ищем нарушения контрактов и тд и тд
Раз в день проводим мониториг логов стейджинга, все девиации должны быть задокументированы в багтрекере. Желательно иметь внятное соглашение об именовании, что бы можно было пользоваться поиском дубликатов
Скажем, у нас на старом проекте QA научились смотреть в логи и делать первичный анализ, если обнаруживают девиацию. Смотрят трассу и говорят — логин пошел дважды, первые тридцать-сорок секунд юзер как бы залогинен дважды, после перезапуска приложения, восстанавливается состояние второй сессии.
Теперь девелопер уже изначально знает чего искать — повторый логин.
Далее, QA уже сознательно пытаются найти эти кейсы, которые дают двойной логин, и обнаруживается, что "изредка" на самом деле совсем не "изредка", а зависит окружения пользователя. У некоторых будет не только "изредка", но и "частенько", и даже "постоянно".
Если всего этого нет, то баг выглядит совершенно иначе: "при перезапуске изредка приложение теряет данные пользователя". Типичная реакция девелопера — потыкать там-сям, от пяти минут до часа и закрыть "не воспроизводится". В лучшем случае отдать QA, что бы те уточнили последовательность, чего большей частью ждать приходится слишком долго — поиск ведется фактически в слепую.
И, скажем, если на проекте, как это модно, только авто-тесты или, что еще хуже, только авто-тесы-писаные-девелоперами, целая куча багов ждет свою жертву.