Процесс программирования псевдокодов против разработки, управляемой тестами - PullRequest
16 голосов
/ 04 октября 2008

Для тех, кто не читал Code Complete 2, процесс программирования псевдокода - это в основном способ разработки подпрограммы, сначала описав ее на простом английском языке, а затем постепенно пересматривая ее до более подробного псевдокода и, наконец, кодируя. Основное преимущество этого состоит в том, чтобы помочь вам оставаться на правильном уровне абстракции, создавая системы сверху вниз, а не снизу вверх, тем самым развивая чистый API на разных уровнях. Я считаю, что TDD менее эффективен в этом, потому что он слишком сосредоточен на выполнении минимума, чтобы пройти тест, и поощряет небольшую предварительную разработку. Я также считаю, что поддерживать набор модульных тестов для нестабильного кода (код, который постоянно подвергается рефакторингу) довольно сложно, потому что обычно у вас есть дюжина модульных тестов для процедуры, которая требуется только один или два раза. Когда вы выполняете рефакторинг - например, меняете сигнатуру метода - большая часть работы, которую вы выполняете, заключается в обновлении тестов, а не кода продукта. Я предпочитаю добавлять модульные тесты после того, как код компонента немного стабилизировался.

Мой вопрос - тех, кто пробовал оба подхода, что вы предпочитаете?

Ответы [ 6 ]

6 голосов
/ 02 апреля 2010

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

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

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

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

4 голосов
/ 04 октября 2008

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

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

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

3 голосов
/ 04 октября 2008

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

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

1 голос
/ 04 октября 2008

То, что тест пройден, не означает, что вы закончили.

TDD лучше всего характеризуется Красный - Зеленый - Рефакторинг .

Проведение теста дает одну (две) линии ворот. Это только первый, минимальный набор требований. Настоящая цель - это та же цель, что и в процессе программирования псевдокодов или любой дисциплине проектирования.

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

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

Настоящая цель - хорошее программное обеспечение. TDD не может исключать "добро".

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

1 голос
/ 04 октября 2008

Я использовал оба вместе с Big Upfront Development, все три имеют свои места в зависимости от таких вопросов, как язык, динамика команды и размер / сложность программы.

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

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

Если вы работаете в одиночку над чем-то небольшим на языке со статической типизацией, подход с использованием списков является разумным и сэкономит вам много времени по сравнению с TDD (обслуживание тестов НЕ БЕСПЛАТНО, хотя написание тестов прежде всего не так уж и плохо) - Когда в системе, над которой вы работаете, нет никаких тестов, добавление в тесты не всегда вызывает восхищение, и вы можете даже привлечь какое-то нежелательное внимание.

0 голосов
/ 05 января 2009

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

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

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

(пожалуйста, не сердитесь на меня, я только наполовину серьезен: P)

...