Я понимаю разработку, основанную на тестировании, что вам разрешено писать продуктивный код только при неудачном (красном) модульном тесте. Исходя из этого, у меня возникает вопрос, можно ли применять подход, основанный на тестировании, к другим формам тестов.
41
Ответы:
Все, что от вас требует TDD, - это написать неудачный тест, а затем изменить свой код, чтобы он прошел.
Обычно «модульные тесты» являются небольшими и быстрыми и тестируют некоторую часть вашего кода изолированно. Поскольку они быстрые, это также ускоряет цикл красный / зеленый / рефакторинг. Тем не менее, они страдают только от тестирования частей в изоляции. Поэтому вам нужны и другие тесты (интеграция, приемка и т. Д.). По-прежнему рекомендуется следовать тем же принципам: написать неудачный тест, а затем изменить код, чтобы он работал. Просто имейте в виду, что они обычно медленнее, что может повлиять на время цикла красный / зеленый / рефакторинг.
источник
Красный зеленый цикл рефакторинга построен по одному очень здравому принципу:
Только тесты доверия, которые вы видели, проходят и не проходят.
Да, это работает и с автоматизированными интеграционными тестами. Также ручные тесты. Черт возьми, он работает на тестерах автомобильных аккумуляторов. Вот как вы тестируете тест.
Некоторые считают, что юнит-тесты охватывают самые маленькие вещи, которые можно протестировать. Некоторые думают обо всем, что можно быстро проверить. TDD - это больше, чем просто красно-зеленый цикл рефакторинга, но эта часть имеет очень специфический набор тестов: это не те тесты, которые вы в идеале должны выполнить один раз перед отправкой набора изменений. Это тесты, которые вы будете запускать каждый раз, когда вносите какие-либо изменения. Для меня это ваши юнит-тесты.
источник
Да, и хорошо известный подход, который делает это, является поведенческим развитием . Тесты, которые генерируются из формальной спецификации в BDD, могут называться «модульными тестами», но они, как правило, будут не такими низкоуровневыми, как в реальном TDD, они, вероятно, будут лучше соответствовать термину «приемочные тесты».
источник
Нет. Вы можете написать только самый простой код, чтобы изменить сообщение теста. Это ничего не говорит о том, что за тест.
Фактически, вы, вероятно, начнете с того, что напишите неуспешный (красный) приемочный тест для критерия приемки, точнее, вы напишете простейший приемочный тест, который может оказаться неудачным; после этого вы запускаете тест, наблюдаете, как он проваливается, и проверяете, что он не прошел по правильной причине. Затем вы пишете ошибочный функциональный тест для части функциональности этого критерия приемлемости, опять же, вы пишете простейший функциональный тест, который может быть неудачным, запускаете его, наблюдаете, как он отказывает, и проверяете, что он выходит из строя по правильной причине. Затем вы пишете провальный модульный тест, самый простой модульный тест, который может быть неудачным, запускаете его, смотрите, как он проваливается, проверяете, что он проваливается по правильной причине.
Теперь вы пишете простейший производственный код, который может изменить сообщение об ошибке. Запустите тест снова, убедитесь, что сообщение об ошибке изменилось, что оно изменилось в правильном направлении, и что код изменил сообщение по правильной причине. (В идеале, сообщение об ошибке должно исчезнуть, и тест должен пройти, но чаще всего лучше сделать небольшие изменения, изменяя сообщение, а не пытаться заставить тест пройти тест за один раз - вот причина почему разработчики тестовых сред тратят столько усилий на сообщения об ошибках!)
После прохождения модульного теста вы реорганизуете производственный код под защитой ваших тестов. (Обратите внимание, что в настоящее время приемочный тест и функциональный тест по-прежнему не проходят, но это нормально, поскольку вы выполняете рефакторинг только отдельных модулей, которые охватываются модульными тестами.)
Теперь вы создаете следующий модульный тест и повторяете вышеизложенное, пока функциональный тест также не пройдет. Под защитой функционального теста вы можете выполнять рефакторинг для нескольких устройств.
Этот средний цикл теперь повторяется до тех пор, пока не пройдет приемочный тест, и теперь вы можете выполнять рефакторинг по всей системе.
Теперь вы выбираете следующий критерий принятия, и внешний цикл начинается снова.
Кент Бек, «первооткрыватель» TDD (ему не нравится термин «изобретатель», он говорит, что люди этим занимались все время, он просто дал ему имя и написал об этом книгу) использует аналогию из фотографии и называет это "увеличение и уменьшение".
Примечание: вам не всегда нужны три уровня тестов. Может быть, иногда тебе нужно больше. Чаще вам нужно меньше. Если ваши функциональные возможности невелики, а функциональные тесты выполняются быстро, вы можете обойтись без (или с меньшим количеством юнит-тестов). Часто вам нужны только приемочные испытания и юнит-тесты. Или ваши критерии приемки настолько детализированы, что приемочные тесты - это функциональные тесты.
Кент Бек говорит, что если у него есть быстрый, маленький и сфокусированный функциональный тест, он сначала напишет модульные тесты, позволит модульным тестам управлять кодом, а затем снова удалит (некоторые из) модульных тестов, которые охватывают код, который также покрыты быстрым функциональным тестом. Помните: тестовый код также является кодом, который необходимо поддерживать и реорганизовывать, чем меньше его, тем лучше!
Вы действительно не применяете TDD к тестам. Вы применяете это ко всему процессу разработки. Вот что означает «управляемая» часть Test- Driven -Development: вся ваша разработка основана на тестах. Тесты не только управляют кодом, который вы пишете, они также определяют, какой код писать, какой код писать дальше. Они управляют вашим дизайном. Они скажут вам, когда вы закончите. Они говорят вам, над чем работать дальше. Они рассказывают вам о недостатках дизайна в вашем коде (когда тесты трудно писать).
Кейт Брейтуэйт создал упражнение, которое он называет TDD, как будто вы это имели в виду . Он состоит из набора правил (основанных на Трех правилах TDD дяди Боба Мартина , но гораздо более строгих), которым вы должны строго следовать и которые направлены на то, чтобы более строго применять TDD. Лучше всего работает с парным программированием (чтобы ваша пара могла убедиться, что вы не нарушаете правила) и с инструктором.
Правила таковы:
Эти правила предназначены для осуществления TDD. Они не предназначены для фактического использования TDD на производстве (хотя ничто не мешает вам опробовать его). Они могут чувствовать разочарование, потому что иногда кажется, что вы делаете тысячи маленьких маленьких шагов, не добиваясь реального прогресса.
источник
TDD вовсе не ограничивается тем, что традиционное сообщество Software Testing называет «модульным тестированием». Это очень распространенное недоразумение является результатом неудачной перегрузки Кентом Беком термина «единица» при описании его практики TDD. Под модульным тестом он имел в виду тест, который проводится изолированно. Это не зависит от других тестов. Каждый тест должен устанавливать необходимое ему состояние и выполнять очистку после его завершения. Именно в этом смысле юнит-тест в смысле TDD является юнитом. Это автономно. Он может запускаться сам по себе или запускаться вместе с любым другим модульным тестом в любом порядке.
Ссылка : "Разработка через тестирование на примере", Кент Бек
Кент Бек описывает, что он подразумевает под «модульным тестом» в главе 32 - «Освоение TDD».
источник
Я не читал об этом книги, и при этом я не следую все время «стандартным» методам TDD, но, на мой взгляд, основной смысл философии TDD, с которым я полностью согласен, заключается в том, что сначала нужно определить успех , Это важно на каждом уровне дизайна, от "Какова цель этого проекта?" на "Какими должны быть входы и выходы этого маленького метода?"
Есть много способов сделать это определение успеха. Полезным, особенно для тех низкоуровневых методов с потенциально большим количеством крайних случаев, является написание тестов в коде. Для некоторых уровней абстракции может быть полезно просто записать краткую заметку о цели модуля или чего-либо еще, или даже просто мысленно проверить себя (или спросить коллегу), чтобы убедиться, что все имеет смысл и находится в логичное место. Иногда полезно описать интеграционный тест в коде (и, конечно, это помогает автоматизировать его), а иногда полезно просто определить разумный план быстрого тестирования, который вы можете использовать, чтобы убедиться, что все системы работают так, как вам нужно. ожидаю.
Но независимо от конкретных методов или инструментов, которые вы используете, на мой взгляд, ключевой момент, который нужно отойти от философии TDD, заключается в том, что определение успеха происходит первым. В противном случае, вы бросаете дротик, а затем рисуете яблочко, где бы оно ни случилось.
источник
В докладе «Разработка через тестирование»: это не то, что мы имели в виду. Стив Фриман показывает следующий слайд общей картины TDD (см. Ответ ниже на рисунке). Это включает в себя этап «Написать неудачный сквозной тест», за которым следует «Написать неудачный юнит-тест». (Нажмите, чтобы увеличить, в правом верхнем углу)
Так что нет в TDD тесты не всегда юнит-тесты.
И да, вы можете (и, возможно, должны) начать с высокоуровневого сквозного теста, который завершается неудачей, прежде чем вы напишите свой первый модульный тест. Этот тест описывает поведение, которого вы хотите достичь. Это создает покрытие на нескольких уровнях тест-пирамиды . Адриан Саттон объясняет опыт LMAX, который показывает, что сквозные тесты могут сыграть большую и ценную роль .
источник
Нет, его нельзя применять к другим типам тестов по простой практической причине: другие типы тестов выполняются слишком долго.
Типичным циклом TDD является: запись неудачного теста, реализация, рефакторинг кода. Промежуточные шаги - это построение и выполнение тестов, и они должны быть молниеносными. Если это не так, то люди начнут пропускать шаги, и тогда вы больше не будете заниматься TDD.
источник