Как далеко идти с юнит-тестами

11

Вопрос задавался много раз прежде, но с определенным уклоном развития MVC.

Я был очень хорошим мальчиком и кодировал все свои действия контроллера с соответствующими юнит-тестами, что было здорово (если немного [читай много раз) время от времени). Честно говоря, я на самом деле создал небольшой шаблон T4, чтобы написать большую часть начальных юнит-тестов, а затем настроил его в соответствии с потребностями. Я признаю, что не совсем уверен, как обращаться с тестами в представлениях, которые содержат частичные представления - но это история для другого вопроса.

Теперь мне сложно определиться с тем, насколько глубоким должно быть покрытие на моем уровне обслуживания. Причина в том, что некоторые из моих методов обслуживания (в лучшую или в худшую сторону) на самом деле выполняют множество запросов linq, которые затем предоставляют скрытую информацию для последующей логики внутри метода. Я знаю, что могу (должен ??) разбить эти методы, чтобы вызвать только необходимую логику для каждого оператора linq, а затем применить их в методе. Однако во многих случаях никогда не происходит повторного использования 'функций' linq, и поэтому кажется, что это приведет к рефакторингу кода слишком далеко.

То, что я спрашиваю, со сложной логикой, возникающей внутри метода, это «достаточно хорошо», чтобы иметь метод теста, который просто утверждает требуемый результат и / или ожидаемую ошибку, или если каждая логическая строка тоже симулируется и тестируется. как я понимаю, чтобы правильно провести тестирование, тогда логика метода (строка за строкой) тоже должна получить какое-то освещение. Однако это (по моему наивному мнению) может привести к бесконечному циклу попыток держать тест и внедренный метод настолько тесно выровненными (что, я знаю, они должны быть), чтобы создать коттеджную индустрию в самих тестах.

Я знаю, что мой вопрос может оскорбить некоторых из преданных TDD, которые воспримут это как легкую задачу. Находясь не в лагере TDD, для меня это «ежу понятно», отсюда и вопрос.

кстати - проверил это на идеи:

http://dotnetslackers.com/articles/aspnet/Built-in-Unit-Test-for-ASP-NET-MVC-3-in-Visual-Studio-2010-Part-1.aspx

глядя сейчас на устойчивые отрицательные голоса :)

[править] - в пользу единственного (ну на данный момент одиночного !!) «близкого» избирателя. этот вопрос не субъективен. Я ищу консенсус на очень сфокусированную тему. Я не пытаюсь разжечь негативные страсти, я не собираюсь раскрывать недостатки в технологии - я ОГРОМНЫЙ фанат. Поэтому, пожалуйста, оставьте вежливый комментарий в мою пользу, если голосование будет закрыто, поскольку это может помочь мне реструктурировать вопрос в случае двусмысленности или дезинформации. Этот вопрос может принести пользу большой части населения MVC.

Спасибо!!

Джим

Джим
источник
(Первый) голос за закрытие принадлежит мне, но не как «субъективный и аргументированный» (а это не так), а как «переход на programmers.stackexchange.com», потому что это не конкретный вопрос программирования с одним четкий ответ.
аакашм, оценили и поняли. не копал, просто хотел знать :)
Джим

Ответы:

4

Во-первых, то, о чем вы говорите, не совсем похоже на TDD. TDD подразумевает тестовый первый подход, который заключается в управлении дизайном вашей системы, следуя шаблону Test-> Code-> Refactor . Так что, возможно, ваша первая проблема - цель ваших тестов, пишете ли вы их как код? Если это так, я ожидаю, что почти вся логика в вашем тесте связана с каким-то модульным тестом. Поэтому высокий охват кода является косвенным результатом применения TDD.

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

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

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

Однако ни один из этих бессмысленных ответов не дает прямого ответа на ваш вопрос, поэтому я просто скажу, что вы должны стремиться к довольно высокому коду покрытия кода службы (не-пользовательского интерфейса), особенно там, где присутствует нетривиальная логика, и даже лучше, если тесты написано первым ;-). Дело в том (хотя некоторые могут не согласиться), что больше тестов, как правило, лучше. Многие высококачественные проекты с открытым исходным кодом имеют гораздо больше тестового кода, чем исполняемый код.

Кроме того, тесты должны быть написаны всякий раз, когда:

  1. Вы пишете новый код, тесты должны управлять и документировать ваш дизайн и объяснять ваши предположения о том, что должен делать код. Должно быть написано, прежде чем код.

  2. Вы нашли ошибку, неудачный тест должен продемонстрировать ошибку. Когда ошибка устранена, тест должен пройти.

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

Лично я обнаружил, что изучение TDD - интересная задача, и для того, чтобы развить в ней хорошее «внутреннее чувство», требуется время. Практика, практика, практика была лучшим способом учиться для меня. Это и чтение тестового кода из проектов с открытым исходным кодом, а также внесение вклада в них при написании новых тестов с моими изменениями.

Крис Никола
источник
+1 Крис - мне нравится срез вашей стрелы :-), но, что более важно, вы указываете (хотя я понял разницу) на разделение между модульным тестированием и TDD. моя модель несколько гибридная (yikes !!)
Джим
Да, я подумал, что, возможно, это было что-то, с чем ты знаком, но, тем не менее, стоит упомянуть. Я также думаю, что у всех нас, вероятно, есть гибридная модель. Хотя в последнее время я обнаружил, что сначала делаю гораздо больше тестов. Я чувствую, что переход на MSpec и спецификации стиля тестов помогли. Хотя я все еще пишу некоторый код, я просто не могу потрудиться проверить его первым.
Крис Никола
... я стыдливо киваю головой в согласии с твоим последним предложением :)
Джим
0

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

С другой стороны, у вас может не хватить времени или терпения проверить все.

Что вы можете сделать, это решить, какую часть кода вы хотите покрыть тестами (80-90% или что-то еще), и применить это с помощью автоматизированных инструментов, которые проверяют это.
«Бесконечный цикл» написания тестов произойдет только в том случае, если цикл написания кода также никогда не заканчивается :)

Космин
источник
cosmin - ты, очевидно, не видел мой код. вернуться на беговую дорожку ... :-)
Джим
0

Насколько вы уверены, что ваш код работает правильно? Модульное тестирование - это всего лишь один инструмент в сумке программиста, который помогает убедиться, что ваша реализация выполняет то, что, по словам спецификаций, она должна делать. Возможно, вам не нужно 100% покрытие, но вы должны написать модульные тесты, чтобы охватить более важные части вашего кода. Всегда хорошо убедиться, что ваши методы работают хорошо вместе, а не только в одиночку, и поэтому вам следует попытаться написать несколько тестов, которые охватывают некоторые из ваших более важных «логических линий».

FreeAsInBeer
источник
0

Выполнение модульных тестов с включенным покрытием кода в Visual Studio должно дать вам хорошее (и графическое) представление о том, насколько хорошо покрыт ваш код.

Если вы не используете встроенную платформу MSTest, вам может понадобиться обратиться к стороннему продукту покрытия кода для работы с NUnit или следовать инструкциям здесь: /programming/2665799/does-vs2010-code -coverage-поддержка-NUnit

DaveRead
источник