Как правильно писать тесты?(Часть 1)

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

Обсудим три базовых подхода к тестированию чего-либо в программе:

1. Тестирование наблюдаемого поведения (по принципу чёрного ящика).

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

79f3f23d0f232028c974d9a0bf2ff896.gif

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

2. Тестирование состояния

Бывает и такое, что вызываемый нами объект мутирует состояние внепроцессной зависимости, например, базы данных. В таком случае тестируемый объект не вернёт нам достаточно данных для оценки его работы, так как его наблюдаемое поведение скрыто от клиента.

d8bc7e2587a5bb98bcbb036daf879be2.gif

Это приводит к тому, что мы начинаем использовать детали реализации (тесты становятся более хрупкими) БД в тесте. В данном случае это знания о диалекте базы данных, названиях таблиц, столбцов их типов и т. п. Эти данные могут претерпеть изменения со временем.

Что делать, чтобы улучшить положение? Во многих случаях можно отдать предпочтение другим методам тестируемого объекта (как один из вариантов), и тогда детали реализации в тесте снова станут неизвестны.

514e88278b11c055eadcb2bc29d25eb5.gif

3. Проверка поведения

Самыми хрупкими тестами являются тесты, которые проверяют:

  • Сколько раз был вызван метод?

  • Какие параметры были переданы в то или иное место?

  • В какой последовательности были произведены вызовы?

  • и т. п.

4eaf99cbcf5949d5e97a1effa0c23986.gif

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

  • Протестировать класс Client, что мы отправили корректные данные в «сеть»

  • «Высечь в камне» сложный алгоритм/бизнес-процесс, который не должен меняться

  • Зафиксировать контракт с внепроцессной зависимостью

  • В большинстве других случаев стоит избегать таких тестов

Во второй части мы более подробно разберём юнит-тесты, и в миллионный раз сравним две школы юнит-тестирования.

© Habrahabr.ru