Первая часть - это короткая статья без привязки к языку программирования, которая подойдёт всем у кого возникаю вопросы как улучшить качество своих тестов.
Обсудим три базовых подхода к тестированию чего-либо в программе:
1. Тестирование наблюдаемого поведения(по принципу чёрного ящика).
Конечно, как разработчики мы знаем, какой код мы пишем, даже если пишем тесты по TDD. Идея тут в том, что бы не использовать эту информацию в тесте.

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

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

3. Проверка поведения
Самыми хрупкими тестами являются тесты, которые проверяют:
Сколько раз был вызван метод?
Какие параметры были переданы в то или иное место?
В какой последовательности были произведены вызовы?
и т. п.

Несмотря на то, что такие тесты являются самыми хрупкими, потому что почти при любых изменениях деталей тест будет ломаться, даже если конечный результат верен(ложные срабатывания) они тоже иногда спасают нас:
Протестировать класс Client, что мы отправили корректные данные в "сеть"
"Высечь в камне" сложный алгоритм/бизнес-процесс, который не должен меняться
Зафиксировать контракт с внепроцессной зависимостью
В большинстве других случаев стоит избегать таких тестов
Во второй части мы более подробно разберём юнит-тесты, и в миллионный раз сравним две школы юнит-тестирования.
