Насколько ценен конкретный подход к тестированию, зависит от того, насколько критически важна разрабатываемая система, и насколько от нее зависит какая-то другая критически важная система. Простой скрипт гостевой книги для вашего веб-сайта вряд ли можно считать критически важным, но если веб-сайт, на котором он работает, потенциально может быть скомпрометирован ошибкой, которая допускает нефильтрованный ввод в базу данных, и этот сайт предлагает некоторые жизненно важные услуги, то он внезапно становится намного более важно, чтобы скрипт гостевой книги был тщательно протестирован. То же самое относится и к фреймворку / коду библиотеки. Если вы разрабатываете фреймворк с ошибкой, то каждое приложение, использующее эту фреймворк, также имеет такую же ошибку.
Разработка через тестирование дает вам дополнительный уровень безопасности, когда дело доходит до тестов. Если вы пишете тесты рядом или даже после кода, который хотите протестировать, то существует реальный риск того, что вы ошибетесь в тестах. Если вы сначала напишите все тесты, то то, как код работает внутренне, не может повлиять на то, для чего вы пишете тесты, и, следовательно, существует меньшая вероятность того, что вы непреднамеренно напишите тесты, которые считают, что определенный ошибочный вывод является правильным.
Разработка, основанная на тестировании, также побуждает ваших разработчиков писать код, который легко тестировать, потому что они не хотят давать себе еще больше работы! Код, который легко тестировать, обычно является кодом, который легко понять, использовать повторно и поддерживать.
А обслуживание - это то, где вы действительно пожнете плоды TDD. Подавляющее большинство программных усилий, затрачиваемых на программное обеспечение, связано с техническим обслуживанием. Это означает внесение изменений в живой код, чтобы придать ему новые функции, исправить ошибки или адаптировать его к новым ситуациям. При внесении таких изменений вы хотите быть уверены, что сделанные вами изменения имеют желаемый эффект, и, что более важно, они не имеют неожиданного удара по эффектам. Если у вас есть полный набор тестов для вашего кода, то легко проверить, что внесенные вами изменения не нарушают что-то другое, и если сделанные вами изменения действительно нарушают что-то еще, вы можете быстро найти причину. Преимущества долгосрочные.
Вы сказали следующее в своем вопросе:
Я вижу некоторую пользу в написании тестов для некоторых вещей, но очень мало. И хотя мне нравится идея сначала написать тест, я обнаружил, что трачу значительно больше времени на отладку своих тестов, чтобы они сказали, что я на самом деле имею в виду, чем на отладке реального кода. Вероятно, это связано с тем, что тестовый код часто значительно сложнее, чем код, который он тестирует. Я надеюсь, что это просто неопытность с доступными инструментами (rspec в этом случае).
Мне кажется, это говорит о том, что вы не совсем проходите тестирование. Предполагается, что модульный тест должен быть чрезвычайно простым, просто последовательность вызовов методов, за которой следует утверждение для сравнения ожидаемого результата с фактическим результатом. Они должны быть простыми, потому что ошибки в ваших тестах будут катастрофическими, и если вы добавите в тест управление циклами, ветвлениями или другими программами, то становится более вероятным, что в тест будет включена ошибка. Если вы тратите много времени на отладку тестов, это означает, что ваши тесты слишком сложны, и вам следует упростить их.
Если тесты не могут быть упрощены, то один этот факт говорит о том, что с тестируемым кодом что-то не так. Например, если в вашем классе есть длинные методы, методы с большим количеством операторов if / elseif / else или switch или большое количество методов, которые имеют сложные взаимодействия, определяемые текущим состоянием класса, тогда тесты по необходимости должны быть чрезвычайно сложными. обеспечить полное покрытие кода и проверить все возможности. Если ваш класс имеет жестко запрограммированные зависимости от других классов, это снова увеличит количество обручей, к которым вам нужно будет перейти, чтобы эффективно протестировать ваш код.
Если вы сохраняете свои классы небольшими и высоко сфокусированными, с короткими методами с небольшим количеством путей выполнения и пытаетесь устранить внутреннее состояние, тогда тесты можно упростить. И в этом вся суть. Хороший код легко тестировать. Если код нелегко проверить, значит, с ним что-то не так.
Написание юнит-тестов - это то, что приносит вам пользу в долгосрочной перспективе, и избегать их - просто накапливать проблемы на потом. Возможно, вы не знакомы с понятием технического долга, но он очень похож на финансовый долг. Не писать тесты, не комментировать код, писать в жестко закодированных зависимостях и т. Д. - это способы влезть в долги. Вы «одалживаете» время, срезая углы на ранней стадии, и это может помочь вам уложиться в сжатые сроки, но время, которое вы ранее сэкономили в проекте, предоставлено взаймы. Каждый день без очистки кода, правильного комментирования или создания набора тестов будет вам интересен. Чем дольше это продолжается, тем больше интереса накапливается. В конце концов, вы обнаружите, что ваш код стал запутанным беспорядком, в который вы не можете вносить изменения, не вызывая непреднамеренных последствий.
Можно подумать о написании модульных тестов на ранних этапах и их обновлении как о форме «технического кредита». Вы вкладываете время в банк, тратя его на ранних этапах проекта, следуя хорошей практике. Вы начнете интересоваться этим предвидением позже, когда перейдете к этапу обслуживания проекта. Если вы хотите внести изменение, вы можете легко проверить правильность изменения и то, что оно не имеет никаких нежелательных побочных эффектов, и вы можете получать обновления быстро и без суеты. Если обнаруживаются ошибки, вы можете добавить новый модульный тест, который выполняет эту ошибку, а затем исправить ошибку в коде. Когда вы в следующий раз запустите модульный тест, вы сможете убедиться, что ошибка была исправлена и что она не вызывала других проблем. Более того, вы избежите «регрессий»,
TL: DR. Да, они помогают в реальном мире, но это инвестиции. Преимущества становятся очевидными позже.