Сталкивались с тестами, которые толком ничего не тестируют? А тесты, которые что-то тестируют, но при этом всё равно постоянно возникают баги? Может быть, тесты, которые приходится каждый раз исправлять? Несложно построить тест, обеспечивающий 100% покрытие, но при этом ничего не проверяющий и не гарантирующий. (См., например). Проблемы юнит-тестов уже затрагивались на Хабре ранее: В заметке рассматривается несколько разновидностей бестолковых тестов, а также некоторые ограничения самой идеи тестирования. А затем (в следующих частях) предлагаются разумные, на взгляд автора, меры обеспечения качества программ, включающие как уменьшение количества малополезных тестов, так и применение тестов там, где они уместны. Тесты бывают разными. Часто предполагается, что чем больше теста, тем вкуснее, тестов, тем качественнее ПО. Следующие примеры заставляют задуматься, так ли это. Наблюдал в одном проекте вот такой код: Коллеги убеждали меня, что такой тест полезен. И помогает увеличить покрытие кода. Иногда встречаются тесты, вызывающие код, но игнорирующие результат (есть даже видео, где Андрей Иванов рассказывает, как писать такие тесты). Покрытие, очевидно, будет на высоте... Похожее явление может возникнуть при тестировании веб-сервисов. Если даже тест упадёт, то, несмотря на наличие assert'а, разработчику потребуется изрядная сноровка, чтобы понять, что на самом деле ожидалось и что пошло не так. Иногда в программе встречаются флаги и конструкции ветвления if-then-else. В особенно запущенных случаях, например, может получиться такой код: (Не говоря даже о вложенных if-ах...) Как же тестируется такой код? Это же очевидно: Естественно, в реальном проекте это многократно растягивается. Как оказалось, довольно популярная технология. (На Хабре есть заметки — Когда использовать mocks в юнит-тестировании, Моки и стабы, Я сомневался в юнит-тестах, но…, Юнит-тестирование для чайников ) Как же протестировать? Апологеты мок-технологии предлагают что-то наподобие следующего кода: Внимательный читатель может заметить подозрительные параллели между кодом и тестом. Когда создаются мок-объекты, предполагается, что есть некоторая логика помимо собственно мок-объекта, которую и требуется протестировать. Но встречается и такой код: Вроде как и тест имеется, и модные моки используются... (Аналогичное наблюдение сделано здесь.) Если в веб-сервисе есть несколько отдельных путей, мы же можем их посчитать? А то вдруг кто-то добавит новый? Пусть тогда пофиксит упавший тест... В некоторых тестах просматривается недоверие разработчикам баз данных и тестируется логика работы собственно базы данных. Например, И это не опечатка, а так и задумано. Ну действительно, надо же проверить, а то вдруг БД не работает?.. (Справедливости ради стоит отметить, что при использовании нестабильных версий библиотек такие защитные тесты могут иметь право на существование, чтобы, например, предотвратить случайный апгрейд на сломанную версию библиотеки.) Тесты являются кодом и могут быть реализованы многими способами. Если разработчик склонен писать раздутый код, то и тесты будут соответствовать. Невинная функция, которая делает сразу два дела. Представители бизнеса и менеджеры ожидают от тестов некоторых полезных свойств: Вышеприведённые примеры тоже называются тестами. Но имеют ли они эти полезные свойства? В настоящей заметке приведены несколько примеров тестов, которые не настолько полезны, как могли бы быть. Одной из причин проблемы является принципиальная ограниченность табличных функций, которыми, по-сути, являются тесты. Из-за этой принципиальной ограниченности надежды на то, что написание бо́льшего количества тестов как-то улучшит качество программы, по-видимому, тщетны. Также не всегда понятны цели и потенциальная польза написания тестов до их написания. Во второй части мы попробуем разобраться, как качество ПО связано с тестами и какие тесты имеют смысл с точки зрения обеспечения качества. Вся серия заметок: Scala архитектор