Должны ли модульные тесты быть написаны до написания кода? - PullRequest
22 голосов
/ 29 октября 2008

Я знаю, что одним из определяющих принципов разработки, управляемой тестами, является то, что вы сначала пишете свои модульные тесты, а затем пишете код для прохождения этих модульных тестов, но нужно ли это делать таким образом?

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

Я уже пытался написать свои модульные тесты, и это может быть полезно, но мне это не кажется естественным.

Ответы [ 20 ]

35 голосов
/ 29 октября 2008

Несколько хороших комментариев, но я думаю, что одна вещь игнорируется.

написание тестов в первую очередь стимулирует ваш дизайн. Это важный шаг. Если вы пишете тесты «в одно и то же время» или «вскоре после», вы можете упустить некоторые конструктивные преимущества, связанные с выполнением TDD за несколько шагов.

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

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

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

7 голосов
/ 29 октября 2008

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

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

Я склонен находить, что я делаю смесь. Чем больше я понимаю требования, тем больше тестов я могу написать заранее. Когда требования - или мое понимание проблемы - слабые, я склонен писать тесты потом.

6 голосов
/ 29 октября 2008

TDD не о тестах, а о том, как тесты управляют вашим кодом. Итак, в основном вы пишете тесты, чтобы позволить архитектуре развиваться естественным образом (и не забывайте проводить рефакторинг !!! в противном случае вы не получите от этого большой пользы). Наличие у вас арсенала регрессионных тестов и исполняемой документации впоследствии является хорошим побочным эффектом, но не основной причиной TDD.

Итак, мой голос: Тест первый

PS: И нет, это не значит, что вам не нужно планировать свою архитектуру раньше, но вы можете переосмыслить ее, если тесты скажут вам об этом !!!!

5 голосов
/ 29 октября 2008

Я возглавлял команды разработчиков в течение последних 6-7 лет. Что я могу сказать наверняка, так это то, что как разработчик и разработчики, с которыми я работал, это делает феноменальную разницу в качестве кода, если мы знаем, где наш код вписывается в общую картину.

Test Driven Development (TDD) помогает нам ответить «Что?» прежде чем мы ответим "Как?" и это имеет большое значение.

Я понимаю, почему могут возникнуть опасения по поводу того, что он не будет следовать в PoC-типе разработки / работы архитектора. И вы правы, возможно, нет смысла следовать этому процессу. В то же время, я хотел бы подчеркнуть, что TDD - это процесс, который входит в фазу разработки (я знаю, что это звучит устарело, но вы понимаете :), когда спецификация низкого уровня ясна.

2 голосов
/ 29 октября 2008

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

2 голосов
/ 29 октября 2008

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

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

Обычно труднее всего разобраться в требованиях, а сразу за ними - в удобстве использования вашего класса, API, пакета ... Тогда фактическая реализация.

  1. Напишите ваши интерфейсы (они изменятся, но будут знать, что ЧТО нужно сделать)
  2. Напишите простую программу для использования интерфейсов (они тупые главные). Это имеет большое значение при определении КАК , которое будет использоваться (возвращайтесь к 1 столько раз, сколько необходимо)
  3. Запись тестов на интерфейсе (бит, который я интегрировал с TDD, снова возвращаюсь к 1 столько раз, сколько необходимо)
  4. написать фактический код за интерфейсами
  5. написать тесты для классов и фактической реализации, использовать инструмент покрытия, чтобы убедиться, что вы не забыли пути выполнения weid

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

Затем я напишу кучу тестов (модульных тестов) для реализации, стоящей за ней, они будут гораздо более подробными и будут часто меняться по мере развития реализации по мере ее оптимизации и расширения.

Это строго говоря, TDD? Экстрим? Проворный ...? без разницы... ? Я не знаю, и, честно говоря, мне все равно. Это работает для меня . Я настраиваю его по мере необходимости и по мере развития моего понимания практики разработки программного обеспечения.

мои 2 цента

2 голосов
/ 29 октября 2008

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

picker = Pick.new
item=picker.pick('a')
assert item

тогда я создаю

class Pick
 def pick(something)
 return nil
 end
end

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

Итак, вкратце. Да. Соотношение при выполнении теста намного выше, чем при отсутствии.

2 голосов
/ 29 октября 2008

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

Часто, если нет тестовой среды, я просто пишу main () в каждый класс, который я пишу. Это добавляет немного в вашу программу, но кто-то всегда может удалить его (или закомментировать), если он захочет. Мне бы очень хотелось, чтобы в вашем классе был только метод test (), который автоматически компилировался бы для сборок релиза - мне нравится, что мой метод test находится в том же файле, что и мой код ...

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

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

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

Кстати, когда я работал над довольно крупным проектом Ruby / Rails, у нас был очень высокий процент охвата тестированием. Мы реорганизовали основной, центральный модельный класс на два класса. Это заняло бы у нас два дня, но со всеми тестами, которые нам пришлось провести рефакторинг, все закончилось ближе к двум неделям. Тесты не являются полностью бесплатными.

2 голосов
/ 29 октября 2008

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

Я не планирую достаточно подробно, чтобы написать тест раньше, чем код, который он собирается тестировать.

Я не знаю, является ли это недостатком моего мышления или метода или просто TIMTOWTDI.

2 голосов
/ 29 октября 2008

Не всегда, но я считаю, что это действительно помогает, когда я делаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...