Автор оригинала: FreeCodeCamp Community Member.
Андреа Куутифарис
Развитие на протяжении тестирования стало популярным за последние несколько лет. Многие программисты пробовали эту технику, не удалось и пришли к выводу, что TDD не стоит усилий, которые требуют.
Некоторые программисты думают, что, по теории, это хорошая практика, но что никогда не бывает достаточно времени, чтобы действительно использовать TDD. И другие думают, что это в основном пустая трата времени.
Если вы чувствуете так, я думаю, что вы можете не понять, что такое TDD действительно. (ОК, предыдущее предложение должно было привлечь ваше внимание). На TDD очень хорошая книга, Тестовое развитие: на примере, Кент Бек Если вы хотите проверить это и узнать больше.
В этой статье я пройду основные основы развития тестирования, обращаясь в общие заблуждения о технике TDD. Эта статья также является первой из ряда статей, которые я собираюсь опубликовать, все о тестированном развитии.
Зачем использовать TDD?
Есть исследования, документы и обсуждения о том, насколько эффективным TDD. Несмотря на то, что определенно полезно иметь некоторые числа, я не думаю, что они отвечают на вопрос, почему мы должны использовать TDD в первую очередь.
Скажите, что вы веб-разработчик. Вы только что закончили небольшую особенность. Считаете ли вы достаточно, чтобы проверить эту функцию, просто взаимодействуя вручную с браузером? Я не думаю, что это достаточно, чтобы полагаться только на тесты, сделанные разработчиками вручную. К сожалению, это означает, что часть кода не достаточно хороша.
Но рассмотрение выше связано с тестированием, а не сам TDD. Так почему же TDD? Краткий ответ: «Потому что это самый простой способ достичь кода хорошего качества и хорошего тестового покрытия».
Чем дольшенный ответ поступает из того, что TDD действительно … Давайте начнем с правил.
Правила игры
Дядя Боб Описывает TDD с тремя правилами:
Я также люблю более короткую версию, которую я нашел здесь :
Эти правила просты, но люди, приближающиеся к TDD, часто нарушают один или несколько из них. Я бросаю вызов вам: можете ли вы написать небольшой проект после Строго Эти правила? Небольшом проектом я имею в виду что-то реальное, не просто пример, который требует 50 строк кода.
Эти правила определяют механику TDD, но они определенно не все, что вам нужно знать. Фактически процесс использования TDD часто описывается как красный/зеленый/рефтекторный цикл. Давайте посмотрим, о чем оно есть.
Красный зеленый рефтекторный цикл
Красная фаза
На красной фазе вам нужно написать тест на поведение, которое вы собираетесь реализовать. Да, я написал поведение Отказ Слово «тест» в тестовом развитии вводит в заблуждение. Мы должны назвать это «поведенческим развитием» в первую очередь. Да, я знаю, некоторые люди утверждают, что BDD отличается от TDD, но я не знаю, согласен ли я. Так что в моем упрощенном определении.
Вот одно общее заблуждение: «Сначала я пишу класс и метод (но без реализации), то я пишу тест для проверки этого метода класса». На самом деле это не работает таким образом.
Давайте сделаем шаг назад. Почему первое правило TDD требует, чтобы вы написали тест, прежде чем писать любой кусок производственного кода? Мы TDD люди маньяки?
Каждая фаза R.G.R. Цикл представляет собой фазу в жизненном цикле кода и как вы можете относиться к нему.
В красной фазе вы действуете так, как вы требующий пользователь, который хочет использовать код, который собирается быть написанным самым простым возможным способом. Вы должны написать тест, который использует кусок кода, как если бы он был уже реализован. Забудьте о реализации! Если на этом этапе вы думаете о том, как вы собираетесь написать код производства, вы делаете это неправильно!
Это на этой фазе, где вы сосредоточены на написании чистого интерфейса для будущих пользователей. Это этап, в которой вы проектируете, как ваш код будет использоваться клиентами.
Это первое правило является наиболее важным, и это правило, которое делает TDD отличаться от регулярных испытаний. Вы пишете тест, чтобы вы могли написать код производства. Вы не пишете тест для проверки вашего кода.
Давайте посмотрим на пример.
// LeapYear.spec.jsdescribe('Leap year calculator', () => { it('should consider 1996 as leap', () => { expect(LeapYear.isLeap(1996)).toBe(true); });});
Вышеуказанный код является примером того, как тест может посмотреть в JavaScript, используя структуру тестирования жасмина. Вам не нужно знать жасмин – достаточно понять, что Это (...)
это тест и Ожидайте (...). Тобе (...)
это способ сделать жасмин проверять, если что-то, как и ожидалось.
В тесте выше я проверил, что функция Lakyear.isleap (...)
Возвращает правда
За 1996 год. Вы можете подумать, что 1996 год – это волшебный номер, поэтому является плохой практикой. Нет. В тестовом коде волшебные номера хороши, тогда как в продукции их следует избегать.
Этот тест на самом деле имеет некоторые последствия:
- Название калькулятора выжимного года –
Високосный год
Isleap (...)
это статический методВисокосный год
Isleap (...)
берет номер (и не массив, например) как аргумент и возвратправда
илиложь
Отказ
Это один тест, но у него на самом деле имеет много последствий! Нужен ли нам метод, чтобы сказать, если год – это выжисный год, или нам нужен метод, который возвращает список скачковых лет между началом и концом? Название элементов значимого? Это такие виды вопросов, которые вы должны иметь в виду, во время написания тестов на красной фазе.
На этом этапе вы должны принимать решения о том, как будет использоваться код. Вы основываете это на то, что вам действительно нужно в данный момент, а не на то, что вы думаете, могут потребоваться.
Вот еще одна ошибка: не пишите кучу функций/классов, которые вы думаете, вам понадобится. Сосредоточиться на функции, которую вы реализуете, и о том, что действительно необходимо. Написание чего-то, что функция не требует, является чрезмерной техникой.
Как насчет абстракции? Увидим это позже, на этапе рефакторов.
Зеленая фаза
Обычно это самая легкая фаза, потому что в этой фазе вы пишете (производственный) код. Если вы программисты, вы делаете это все время.
Вот еще одна большая ошибка: вместо того, чтобы написать достаточно код, чтобы пройти красный тест, вы пишете все алгоритмы. При этом вы, вероятно, думаете о том, что является самым выполнением реализации. Ни за что!
На этом этапе вам нужно действовать как программист, у которого есть одна простая задача: напишите простое решение, которое делает тестовый пропуск (и делает тревожную красную на тестовом отчете становится дружественным зеленым). На этом этапе вам разрешено нарушать лучшие практики и даже дублирующий код. Дублирование кода будет удалено на этапе рефакторов.
Но почему у нас есть это правило? Почему я не могу написать весь код, который уже в моей голове? По двум причинам:
- Простая задача менее склонна к ошибкам, и вы хотите минимизировать ошибки.
- Вы определенно не хотите смешивать код, который находится на тестировании с кодом, который нет. Вы можете написать код, который не находится на тестировании (AKA Legacy), но худшее, что вы можете сделать, это смешивание проверенного и непроверенного кода.
Как насчет чистого кода? А как насчет производительности? Что если запись кода заставляет меня обнаружить проблему? Как насчет сомнений?
Производительность – это длинная история, и выходит из объема этой статьи. Давайте просто скажем, что настройка производительности на этом этапе является большую часть времени, преждевременной оптимизации.
Техническая техника разработки Test обеспечивает два других вещи: список дел и фаза рефакторов.
Фаза рефакторов используется для очистки кода. Список до «TO-DO] используется для записи шагов, необходимых для выполнения функции, которую вы реализуете. Он также содержит сомнения или проблемы, которые вы обнаружите во время процесса. Возможный список дел для калькулятора 2-го года можно:
Feature: Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400.
- divisible by 4- but not by 100- years divisible by 400 are leap anyway
What about leap years in Julian calendar? And years before Julian calendar?
Список TO-DE – это Live: он меняется, когда вы кодируете и, в идеале, в конце реализации функций будут пустыми.
Фаза рефакторов
В фазе рефакторов вам разрешено менять код, сохраняя все тесты зеленые, так что оно становится лучше. Какие «лучше» значит до вас. Но есть что-то обязательное: Вы должны удалить дублирование кода Отказ Кент Бекс предлагает в своей книге, что удаление дублирования кода – это все, что вам нужно сделать.
На этом этапе вы играете в состав разборчивой программиста, который хочет исправить/рефакторировать код, чтобы довести его на профессиональный уровень. В красной фазе вы демонстрируете свои навыки своим пользователям. Но на этапе рефакторов вы демонстрируете свои навыки для программистов, которые будут прочитать вашу реализацию.
Удаление кода дублирование часто приводит к абстракции. Типичный пример, когда вы перемещаете два подобных кода в класс помощника, который работает как для функций/классов, где код был удален.
Например следующий код:
class Hello { greet() { return new Promise((resolve) => { setTimeout(()=>resolve('Hello'), 100); }); }}class Random { toss() { return new Promise((resolve) => { setTimeout(()=>resolve(Math.random()), 200); }); }}new Hello().greet().then(result => console.log(result));new Random().toss().then(result => console.log(result));
может быть восстановлен в:
class Hello { greet() { return PromiseHelper.timeout(100).then(() => 'hello'); }}class Random { toss() { return PromiseHelper.timeout(200).then(() => Math.random()); }}class PromiseHelper { static timeout(delay) { return new Promise(resolve => setTimeout(resolve, delay)); }}const logResult = result => console.log(result);new Hello().greet().then(logResult);new Random().toss().then(logResult);
Как вы можете видеть, чтобы удалить Новое обещание
и Сетримс
Код дублирования, я создал Уважаемое. Время (задержка)
Метод, который служит как Привет
и Случайные
классы.
Просто имейте в виду, что вы не можете перейти к другому тесту, если вы не удалили все дублирование кода.
Окончательные соображения
В этом разделе я постараюсь ответить на некоторые общие вопросы и заблуждения о разработке тестового диска.
- T.D.D. требует гораздо больше времени, чем «нормальное» программирование!
Что на самом деле требует много времени – это обучение/овладение TDD, а также понимание того, как настроить и использовать среду тестирования. Когда вы знакомы с инструментами тестирования и техникой TDD, он на самом деле не требует больше времени. Напротив, он помогает сохранить проект максимально проще и, таким образом, экономит время.
- Сколько мне нужно написать теста?
Минимальная сумма, которая позволяет вам писать все производственный код. Минимальная сумма, потому что каждый тест замедляет рефакторинг (при изменении производственного кода, вы должны исправить все неудачные тесты). С другой стороны, рефакторинг намного проще и безопасен на коде под тестами.
- С помощью тестируемого развития мне не нужно проводить время на анализ и по проектированию архитектуры.
Это не может быть более ложным. Если то, что вы собираетесь реализовать, не очень хорошо спроектирован, в определенном моменте вы будете думать «Ой! Я не считал …». И это означает, что вам придется удалить производственный и тестовый код. Это правда, что TDD помогает с «достаточно просто, как раз вовремя» рекомендации Agile Techniques, но это определенно не замена для фазы анализа/дизайна.
- Должен ли тестировать покрытие 100%?
Нет. Как я уже говорил ранее, не смешивайте тестированный и непроверенный код. Но вы можете избежать использования TDD на некоторых частях проекта. Например, я не проверяю просмотров (хотя многие каркасы делают тестирование интерфейса UI), потому что они могут часто меняться. Я также убедитесь, что есть очень маленькая логика внутри видов.
- Я могу написать код с очень несколькими ошибками, мне не нужно тестирование.
Вы можете это, но это то же самое, что и для всех членов вашей команды? Они в конечном итоге будут изменять ваш код и сломать его. Было бы здорово, если вы написали тесты, так что ошибка может быть замечена немедленно и не в производстве.
- TDD хорошо работает на примерах, но в реальном применении много кода не является тестируемым.
Я написал целый тетрис (а также прогрессивные веб-приложения на работе), используя TDD. Если вы проверяете первым, код четко реализован. Более вопрос понимания того, как насмешливые зависимости и как писать простые, но эффективные тесты.
- Тесты не должны быть написаны разработчиками, которые пишут код, они должны быть написаны другими, возможно, люди.
Если вы говорите о тестировании вашего приложения, да, это хорошая идея, чтобы другие люди проверили, что сделала ваша команда. Если вы говорите о написании продукции, то это неправильный подход.
Что дальше?
Эта статья была о философии и распространенных заблуждении TDD. Я планирую написать другие статьи на TDD, где вы увидите много кода и меньше слов. Если вы заинтересованы в том, как разработать Tetris, используя TDD, оставайся настроенными!