Автостопом по разработке через тестирование (TDD)

Разработка через тестирование (также известная как TDD) - одна из самых интригующих функций семейства eXtreme Programming (XP). У него есть своя доля критиков и последователей.

Однако существует общее мнение, что TDD, если следовать ему, дает коды с лучшими модульными тестами с (возможно) меньшим количеством ошибок.

Несмотря на популярность и всеобщее мнение о преимуществах TDD, его по-прежнему считают дополнительным занятием по программированию, а не основным. Для того же могут быть разные причины, но как разработчик я обнаружил, что наиболее очевидной причиной является неправильное представление об основных принципах TDD и о том, как их использовать.

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

Как начать с TDD

Вот четыре шага, необходимых для выполнения TDD, которые следует запомнить наизусть.

  1. Напишите «достаточно» тестов с ошибками перед написанием рабочего кода
  2. Напишите рабочий код, чтобы пройти эти неудачные тесты
  3. При необходимости измените коэффициент кода.
  4. GoTo Step - 1

Шаг → 1. Напишите «достаточно» неудачных тестов перед написанием рабочего кода

Слово «достаточно» субъективно и зависит от отдельных программистов. Никто не может и не должен пытаться определить это как нечто ограниченное функцией, классом и т. Д.

Если вы умеете писать неудачные тесты для полного модуля или компонентов без какого-либо производственного кода, сделайте это.

Также слово «сбой» включает все типы сбоев, включая, помимо прочего, время компиляции, время выполнения, доступ к машине, а также сбои инфраструктуры.

Вот небольшой пример типовых тестов, которые вы можете написать как часть шага → 1.

Шаг → 2. Напишите рабочий код, чтобы пройти эти неудачные тесты

Как только у вас будет «достаточно» неудачных тестов, напишите код, чтобы пройти эти тесты. Например

Распространенное заблуждение состоит в том, что вы не можете изменить ни один из тестовых примеров, написанных на Шаге → 1, пока вы выполняете Шаг → 2. К счастью, такой привязки нет. Не стесняйтесь переключаться между производственным и тестовым кодом.

Например, когда вы меняете имя функции или класса для лучшего понимания, или, если на то пошло, вы можете написать дополнительную функциональность или разбить функцию на две части, вам придется изменить соответствующие тесты.

Например, если мы изменим приведенный выше производственный код как

Затем нам нужно будет изменить тестовый код, поскольку существующий тестовый код будет вызывать функцию с именем init_0, которой больше не существует.

Однако это также отражает причину написания только ограниченного или небольшого количества тестовых примеров перед переходом к шагу → 2, и причина в следующем.

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

Шаг → 3. При необходимости измените коэффициент кода

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

Например, если вы удалите класс или функцию в рамках рефакторинга, вы удалите и соответствующие тесты.

Например, в качестве рефакторинга, если мы изменим следующее в приведенном выше коде

  1. Измените имя класса на MyLinearAlgo
  2. Удалить init_two функцию
  3. Измените функцию init_four, чтобы она могла принимать как два, так и четыре параметра.

Вы можете представить существующие тесты, которые можно провести здесь? Нет, совсем нет, вам тоже нужно изменить тесты, чтобы они соответствовали рефакторингу.

Когда вы закончите с Шагом → 3, , можете повторить все заново.

Как написать Test First?

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

Что всего нужно для написания тестов в первую очередь?

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

Вполне нормально написать скелетный код перед написанием тестов.

Что за черт? Разве TDD не означает «сначала тест»?

Да, но мы не можем писать тесты на пустом месте. Для написания теста нам понадобится как минимум две вещи. Они есть

  1. Контекст
  2. Ограничения

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

Идея и душа TDD состоит в том, чтобы писать модульные тесты для всего производственного кода, и писать скелетные производственные коды для него - не преступление. Например, вполне нормально сначала указать имя класса и / или функции как

По крайней мере, теперь вы знаете имя тестируемого класса и функции. У вас есть «Контекст», а также «Ограничения» для написания тестовых примеров.

Однако в качестве рекомендации воздержитесь от написания реализации того же самого перед написанием тестов. Как только вы начнете писать реализацию перед тестами, вся цель будет побеждена.

Когда у вас есть скелет, вы можете написать тесты как

А затем напишите реализацию как

Затем запустите его с тестом, а затем повторите цикл шагов → 1,2,3 и 4.

Вот что такое TDD

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

Спасибо за прочтение…!!!

Дакша