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

1. Убедитесь, что ваш код работает должным образом.

2. Избегайте регрессионных ошибок.

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

  • я должен попытаться достичь 100% покрытия кода?
  • Должен ли я написать тест для этой конкретной функциональности или нет?
  • Должен ли я издеваться над какой-то конкретной зависимостью или нет?
  • что мне нужно утверждать, а что нет?

Причина 1. Убедитесь, что ваш код работает должным образом

Хороший тест помогает убедиться, что ваш код работает должным образом, если это не очевидно из вашего кода. Не пишите тесты для того, что очевидно из кода.

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

Совершенно нормально написать тест для такого кода.

Но если это не так, если код, который вы пытаетесь протестировать, тривиален, то проверьте, подходит ли этот тест для причины 2.

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

Причина 2. Как избежать ошибок регрессии

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

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

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

Возможно, ваш тестовый код действительно связан с реализацией, и у вас есть причина имитировать внешние зависимости, но тестируемый код настолько сложен, что нет возможности посмотреть на него и сказать, что он правильный. Хорошим примером является реализация сложного алгоритма. Тогда ваш тест может соответствовать причине 1.

Конечно, самые полезные тесты — это те, которые удовлетворяют как причине 1, так и причине 2.