«Команда Android пошла ещё дальше — телефоны основной команды разработки почти постоянно работают на ежедневной сборке. Идея в том, что разработчики будут писать меньше кода с ошибками, если от этого зависит их возможность позвонить домой.»
(«Как тестируют в Google» Джеймс Уиттакер, Джейсон Арбон, Джефф Кароло)
Хоть однозначного ответа на этот вопрос нет, можно рассмотреть конкретные случаи, когда тестирование кода влияет в той или иной мере на написание самого кода. Если не считать, что важным аспектом при тестировании является проверка работоспособности, которая впрочем не обязательно должна создавать условия для написания кода, само вмешательство однозначно не несет ничего хорошего. На архитектуру приложения и так накладывается множество требований, но что лучше: хороший код или хороший код измененённый ещё по нескольким условиям, но делающий абсолютно то-же самое? Да, оптимальнее и производительнее во втором случае он от этого не становится. Это не только про тестирование, любое дополнительное условие ухудшает код. Он всё более и более отдаляется от отсутствия условий - идеального кода (т.е. его отсутствия).
В данном случае условие немножко другое, чем, например, правила безопасности для обработки пользовательского запроса. От них нельзя отказаться безболезненно для работы web-приложения. От тестирования можно, оно не связано напрямую с функционированием сайта. Первоначальная задача тестирования "обмануть" тестируемые модули сайта и создать видимость запроса, неотличимого от других реальных действий пользователя, если говорить про Веб, откуда взят пример с запросом. Модуль не должен знать, что его тестируют, в этом и будет чистота проводимых экспериментов над ним.
Некоторые антипаттерны и также правила для архитектуры кода сложились из условия, что это должно быть тестируемым. А к чему ведёт введение дополнительных условий - смотрите выше. Многие программисты не пишут тестов, но следуют этим правилам, видимо потому что кто-то и когда-то захочет к этому коду написать тесты. При этом можно протестировать что угодно, если это имеет минимум один публичный метод.
Если представить, что к отделу разработки приставлен другой секретный отдел, где по ночам скрытно пишут тесты к их коду в отдельном репозитории, то именно так и должно применяться тестирование. Да, придётся идти на многие хитрости, тестировать нетестируемое, но в итоге окажется, если это каким-либо образом работает, это можно протестировать. А код приложения останется оптимальным для того, для чего предназначен. Получается, для тестов нужно будет прилагать больше усилий, чем обычно. Но ведь работать приложение будет лучше. Стоит ли это затраченных человекочасов - решать надо в каждом конкретном случае.
Предположим, что в класс жестко вставлен вызов стороннего сервиса или базы данных. Как это тестировать не используя реальное обращение? Но ведь в идеальном проекте - это подключение все равно надо покрывать тестами. И обращение к БД где-то будет в классе, правда отдельном и с соответствующей конфигурацией. Хотя оно и должно быть в таком виде, но не для удобств тестирования, а для удобства работы с кодом, самой разработки. Так что это предположение одно из примеров утрирования предложенной концепции, совсем не значит, что всё держится на тестировании и если отменить его существование, всё сразу превратится в легаси. Примерно так предположил бы один мой знакомый, сторонник тестирования, возможно, что ему удалось бы специально написать нетестируемый код, а также использовать идею "тайного тестирования" в ущерб любому начинанию.
Если у вас на проекте совсем не используются тесты, то могу предположить, что код пишется медленно и осторожно, а между его частями минимальная связанность. Но вместе с тем присутствует добавочная гибкость - при переделке кода не нужно переделывать его тесты. Даже не "добавочная", а "изначальная", потому что код появился раньше тестов. Сторонники разработки через тестирование могут в этом месте поспорить.
Если более 80-90% покрытия тестами, то код пишется тоже медленнее, из-за дополнительного кода тестов, но все же быстрее, так как приходится реже перепроверять кодовые зависимости.
В случае, если тесты покрывают 50% или около того, сомнительно их присутсвие вообще. Вы не можете быть уверены, что они покрывают сопутствующие изменения при добавлении нового кода и приходится заниматься их поиском. То есть все замедляющие работу условия из двух предыдущих примеров здесь складываются воедино. Вы запускаете тесты и затем все равно перепроверяете вручную, потому как покрытие тестами небольшое.
Исходя из этих соображений, а также упомянутой предпосылки, что разработчик пишет код под тестирование, там, где тесты не используются, можно заключить, что этот код никогда не будет тестируемым. По крайней мере в подавляющем количестве случаев, ведь в большом проекте добавлять внезапно 90% тестов на весь код - практически невыполнимая задача.
В самом начале этой заметки было утверждение, что "любое дополнительное условие ухудшает код", в силу усложнения и большей вероятности ошибок, дополнительной нагрузки на производительность, конечно же это так. Речь здесь больше не про первостепенные задачи, которые этот код решает, а относится к побочным условиям его функционирования, хотя и в целом имеет смысл.
В итоге можно заключить, что покрытие тестами не из обязательных условий, а больше из раздела отладки, влияние которой на рабочем сервере стараются всегда минимизировать. В случае с Web, когда каждая доля секунды важна, не рекомендовал бы усложнять код так, как нужно для его тестирования. Напротив, тесты должны адаптироваться под тестируемый код.