Когда вы пишете «реальный» код в TDD?

johnny 08/19/2017. 11 answers, 20.464 views
tdd

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

Если у меня довольно сложный объект со сложным методом, и я пишу свой тест и минимальный минимум, чтобы он прошел (после первого сбоя, красный). Когда я вернусь и напишу реальный код? И сколько реального кода я пишу перед повторным тестированием? Я предполагаю, что последний - более интуиция.

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

В моем дизайне у меня есть архитектура, с которой я хочу начать, User Stories и т. Д. И т. Д. Отсюда я беру эти Истории пользователей, и я создаю тест для тестирования Истории пользователей. Пользователь говорит: «У нас есть люди, которые зачисляются в школу и платят регистрационные сборы. Итак, я думаю о том, как это сделать. При этом я создаю тестовый класс для класса X (возможно, Student), который не удастся. Затем я создаю класс «Студент». Может быть, «Школа» я не знаю.

Но, во всяком случае, TD Design заставляет меня задуматься над этой историей. Если я могу сделать сбой теста, я знаю, почему он терпит неудачу, но это предполагает, что я могу пройти. Речь идет о проектировании.

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

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

На мой взгляд, я не знаю, основывается на отсутствии опыта. Я не знаю, как не подписать нового ученика. Я не знаю, как не дать кому-то ввести фамилию и сохранить ее в базе данных. Я знаю, как сделать + 1 для простой математики, но с сущностями, подобными человеку, я не знаю, тестирую ли я только, хочу ли я получить уникальный идентификатор базы данных или что-то еще, когда кто-то вводит имя в Базы данных или и того, и другого.

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

5 Comments
187 hobbs 07/25/2017
После того, как люди TDD вернутся домой на ночь.
14 Goyo 07/25/2017
Как вы думаете, почему код, который вы написали, не реален?
2 johnny 07/26/2017
@RubberDuck Больше, чем другие ответы. Я уверен, что скоро буду говорить об этом. Это по-прежнему чужой, но я не собираюсь сдаваться. То, что вы сказали, имело смысл. Я просто пытаюсь сделать это имеющим смысл в моем контексте или обычном деловом приложении. Может быть, система инвентаря или тому подобное. Я должен это рассмотреть. Я благодарен за ваше время. Благодарю.
1 Edmund Reed 07/26/2017
Ответы уже попали в гвоздь на голове, но до тех пор, пока все ваши тесты проходят, и вам не нужны новые тесты / функциональные возможности, можно предположить, что код, который у вас есть, закончен, штрих-линт.
3 Borjab 07/26/2017
В вопросе, который может быть проблематичным, возникает вопрос: «У меня довольно сложный объект со сложным методом». В TDD вы сначала пишете свои тесты, чтобы начать с довольно простого кода. Это заставит вас закодировать дружественную к тестированию структуру, которая должна быть модульной. Такое сложное поведение будет создано путем объединения более простых объектов. Если вы закончите с довольно сложным объектом или методом, то это когда вы реорганизуете

11 Answers


RubberDuck 07/27/2017.

Если у меня довольно сложный объект со сложным методом, и я пишу свой тест и минимальный минимум, чтобы он прошел (после первого сбоя, красный). Когда я вернусь и напишу реальный код? И сколько реального кода я пишу перед повторным тестированием? Я предполагаю, что последний - более интуиция.

Вы не «возвращаетесь» и пишите «реальный код». Это настоящий код. Что вы делаете, вернитесь назад и добавьте еще один тест, который forces вас change свой код, чтобы сделать новый тест.

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

Обратите внимание на шаблон?

Давайте рассмотрим (другой) простой пример в надежде, что это поможет.

 Assert.Equal("1", FizzBuzz(1)); 

Легкий peazy.

 public String FizzBuzz(int n) {
    return 1.ToString();
} 

Не то, что вы бы назвали реальным кодом, не так ли? Давайте добавим тест, который приведет к изменению.

 Assert.Equal("2", FizzBuzz(2)); 

Мы могли бы сделать что-то глупое, как if n == 1 , но мы перейдем к разумному решению.

 public String FizzBuzz(int n) {
    return n.ToString();
} 

Круто. Это будет работать для всех номеров без FizzBuzz. Каков следующий вход, который заставит производственный код изменить?

 Assert.Equal("Fizz", FizzBuzz(3));

public String FizzBuzz(int n) {
    if (n == 3)
        return "Fizz";
    return n.ToString();
} 

И опять. Напишите тест, который еще не пройдет.

 Assert.Equal("Fizz", FizzBuzz(6));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    return n.ToString();
} 

И теперь мы рассмотрели все кратные из трех (которые также не кратно пяти, отметим это и вернемся).

Мы еще не написали тест на «Buzz», так что давайте напишем это.

 Assert.Equal("Buzz", FizzBuzz(5));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n == 5)
        return "Buzz"
    return n.ToString();
} 

И снова мы знаем, что нам нужен другой случай.

 Assert.Equal("Buzz", FizzBuzz(10));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n % 5 == 0)
        return "Buzz"
    return n.ToString();
} 

И теперь мы можем обрабатывать все кратные 5, которые также не кратно 3.

До этого момента мы игнорировали шаг рефакторинга, но я вижу некоторое дублирование. Давай убираем это сейчас.

 private bool isDivisibleBy(int divisor, int input) {
    return (input % divisor == 0);
}

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

Круто. Теперь мы удалили дублирование и создали хорошо названную функцию. Какой следующий тест мы можем написать, что заставит нас изменить код? Ну, мы избегаем случая, когда число делится на 3 и 5. Давайте напишем его сейчас.

 Assert.Equal("FizzBuzz", FizzBuzz(15));

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n) && isDivisibleBy(5, n))
        return "FizzBuzz";
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

Тест проходит, но у нас больше дублирования. У нас есть варианты, но я собираюсь применить «Извлечь локальную переменную» несколько раз, чтобы мы рефакторинг вместо переписывания.

 public String FizzBuzz(int n) {

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

И мы рассмотрели все разумные данные, но как насчет unreasonable ввода? Что произойдет, если мы пройдем 0 или отрицательно? Напишите эти тестовые примеры.

 public String FizzBuzz(int n) {

    if (n < 1)
        throw new InvalidArgException("n must be >= 1);

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

Начинает ли он выглядеть как «настоящий код»? Что еще более важно, в какой момент он переставал быть «нереальным кодом» и переход к «реальному»? Это то, о чем нужно подумать ...

Таким образом, я смог сделать это просто, ища тест, который, как я знал, не прошел бы на каждом шагу, но у меня было много практики. Когда я нахожусь на работе, все не так просто, и я не всегда знаю, какой тест заставит изменить. Иногда я напишу тест и буду удивлен, увидев, что он уже проходит! Я настоятельно рекомендую вам привыкнуть создавать «Список тестов» перед началом работы. Этот тестовый список должен содержать все «интересные» входы, о которых вы можете думать. Вы не можете использовать их все, и вы, вероятно, добавите случаи, когда идете, но этот список служит дорожной картой. Мой тестовый список для FizzBuzz будет выглядеть примерно так.

  • отрицательный
  • Нуль
  • Один
  • Два
  • Три
  • 4
  • 5
  • Шесть (нетривиальное кратное 3)
  • Девять (3 квадрата)
  • Десять (нетривиальное кратное 5)
  • 15 (кратное 3 и 5)
  • 30 (нетривиальное кратное 3 и 5)
5 comments
3 maple_shaft♦ 07/27/2017
Комментарии не предназначены для расширенного обсуждения; Этот разговор был перемещен в чат .
40 GManNickG 07/27/2017
Если я полностью не понимаю этот ответ: «Мы могли бы сделать что-то глупое, как если бы n == 1, но мы перейдем к разумному решению». - все было глупо. Если вы знаете фронт, вам нужна функция, которая выполняет <spec>, записывает тесты для <spec> и пропускает часть, где вы пишете версии, которые явно не соответствуют <spec>. Если вы обнаружите ошибку в <spec>, то обязательно: сначала напишите тест, чтобы убедиться, что вы можете использовать его до исправления и наблюдать за тестовыми проходами после исправления. Но нет необходимости подделывать все эти промежуточные шаги.
15 user3791372 07/28/2017
Комментарии, указывающие на основные недостатки этого ответа, и TDD в целом были перемещены в чат. Если вы планируете использовать TDD, прочитайте «чат». К сожалению, «качественные» комментарии теперь скрыты среди загрузок чата для будущих учеников для чтения.
nbro 07/28/2017
Я бы уточнил содержание этого «тестового списка», если вы хотите улучшить этот ответ. Я бы прямо говорил о «граничных значениях» и «разбиении классов».
2 hvd 07/30/2017
@GManNickG Я считаю, что дело в том, чтобы получить правильное количество тестов. Написание тестов заблаговременно позволяет легко пропустить, какие специальные случаи следует тестировать, приводя либо к ситуациям, которые не были надлежащим образом охвачены в тестах, или по существу в той же ситуации, что и в тестах, которые были бесцельно покрыты нагрузками. Если вы можете сделать это без этих промежуточных шагов, отлично! Не все могут это сделать, хотя, это то, что требует практики.

GenericJon 07/24/2017.

«Настоящий» код - это код, который вы пишете, чтобы пройти тест. Really . Это так просто.

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

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

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

5 comments
44 Derek Elkins 07/24/2017
Единичные тесты не могут действительно соответствовать вашим требованиям к продукции даже для относительно простых требований. В лучшем случае они выбирают пространство ввода-вывода, и идея состоит в том, что вы (правильно) обобщаете на полное пространство ввода-вывода. Конечно, ваш код может быть просто большим switch с корпусом для каждого модульного теста, который будет проходить все тесты и не работать для любых других входов.
8 Taemyr 07/25/2017
@DerekElkins TDD требует сдачи тестов. Невыполнение единичных тестов.
6 jonrsharpe 07/25/2017
@DerekElkins, поэтому вы не просто пишете модульные тесты, а также почему есть общее предположение, что вы пытаетесь сделать что-то не просто поддельное!
35 Derek Elkins 07/25/2017
@jonrsharpe По этой логике я бы никогда не писал тривиальные реализации. Например, в примере FizzBuzz в ответе RubberDuck (который использует только модульные тесты) первая реализация явно «просто подделывает». Мое понимание вопроса - это именно эта дихотомия между написанным кодом, который, как вы знаете, является неполным, и код, который, как вы искренне верите, выполнит требование «реальный код». Мой «большой switch » был предназначен как логическая крайность «написания минимального минимума, чтобы сделать тесты зелеными». Я рассматриваю вопрос OP как: где в TDD есть принцип, который позволяет избежать этого большого switch ?
2 Luaan 07/25/2017
@GenericJon Это слишком оптимистично в моем опыте :) Во-первых, есть люди, которые наслаждаются бессмысленной повторяющейся работой. Они будут счастливее с заявлением о гигантском переключении, чем с «сложным процессом принятия решений». И чтобы потерять работу, им нужен был кто-то, кто называет их техникой (и у них есть хорошие доказательства того, что они фактически теряют возможности компании / деньги!), Или делают это исключительно плохо. Получив поддержку многих таких проектов, я могу сказать, что очень легко получить наивный код на протяжении десятилетий, если он делает клиента счастливым (и оплачивает).

Carl Raymond 07/24/2017.

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

Я согласен с тем, что множество учебников по TDD упрощены. Это действует против них. Слишком простой тест для метода, который, скажем, вычисляет 3 + 8, действительно не имеет выбора, кроме как вычислять 3 + 8 и сравнивать результат. Это делает его похожим на то, что вы просто дублируете код на всем протяжении, и это тестирование бессмысленно, подвергает ошибкам дополнительную работу.

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

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

4 comments
6 Steve Jessop 07/26/2017
Лично, тест, который я бы написал, будет assertEqual(plus(3,8), 11) , а не assertEqual(plus(3,8), my_test_implementation_of_addition(3,8)) . Для более сложных случаев вы всегда ищете способ доказательства правильности результата, other than динамического вычисления правильного результата теста и проверки равенства.
Steve Jessop 07/26/2017
Итак, для действительно глупых способов сделать это для этого примера, вы можете доказать, что plus(3,8) вернул правильный результат, вычитая из него 3, вычитая из него 8 и проверив результат на 0. Это так очевидно Эквивалентно assertEqual(plus(3,8), 3+8) чтобы быть немного абсурдным, но если тестируемый код создает нечто более сложное, чем просто целое число, то получение результата и проверка каждой части на правильность часто Правильный подход. В качестве альтернативы, что-то вроде for (i=0, j=10; i < 10; ++i, ++j) assertEqual(plus(i, 10), j)
Steve Jessop 07/26/2017
... так как это позволяет избежать большого страха, который заключается в том, что при написании теста мы сделаем ту же ошибку на тему «как добавить 10», что мы сделали в реальном коде. Таким образом, тест тщательно избегает написания кода, который добавляет 10 к чему-либо, в тесте, который plus() может добавить 10 к вещам. Разумеется, мы все равно полагаемся на проверенные программистом значения цикла.
3 Warbo 07/28/2017
Просто хочу отметить, что даже если вы пишете тесты после этого факта, все же неплохо смотреть, как они терпят неудачу; Найдите часть кода, которая кажется решающей для всего, над чем вы работаете, немного измените ее (например, замените a + на - или что-то еще), запустите тесты и посмотрите, как они сбой, отмените изменение и посмотрите, как они проходят. Много раз я делал это, тест на самом деле не терпел неудачу, делая его хуже, чем бесполезно: не только это ничего не тестирует, это дает мне ложную уверенность в том, что что-то тестируется!

Victor Cejudo 07/25/2017.

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

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

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

Боб Мартин прекрасно объясняет это.


CandiedOrange 07/25/2017.

Часть рефакторинга очищается, когда вы устали и хотите вернуться домой.

Когда вы собираетесь добавить функцию, часть рефактория - это то, что вы меняете до следующего теста. Вы реорганизуете код, чтобы освободить место для новой функции. Вы делаете это, когда know какова будет эта новая функция. Не тогда, когда вы просто представляете это.

Это может быть так же просто, как переименование GreetImpl в GreetWorld прежде чем вы создадите класс GreetMom (после добавления теста), чтобы добавить функцию, которая будет печатать «Hi Mom».


graeme 07/27/2017.

Но реальный код появится на этапе рефакторинга фазы TDD. То есть код, который должен быть частью окончательной версии.

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

Девизом жизненного цикла TDD будет: RED GREEN REFACTOR

RED : Напишите тесты

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

REFACTOR : очистите код, правильно назовите переменные. Высушите код.

5 comments
5 mcottle 07/25/2017
Я знаю, что вы говорите о «зеленой» фазе, но это означает, что приемлемые значения обратной связи для проводки могут быть уместными. По моему опыту «Зеленый» должен быть честной попыткой сделать рабочий код соответствующим требованию, он может быть не идеальным, но он должен быть таким же полным и «отгружаемым», как разработчик может справиться с первого прохода. Рефакторинг, вероятно, лучше всего сделать через некоторое время после того, как вы сделаете больше развития, и проблемы с первым проходом станут более очевидными и появятся возможности для СУХОЙ.
graeme 07/25/2017
@mcottle я рассматриваю все эти части одной задачи. Сделайте это, затем очистите его. Дальнейшие рефакторинги должны проходить с течением времени как часть других задач.
1 Bryan Boettcher 07/25/2017
@mcottle: вы можете быть удивлены, сколько реализаций репозитория get-only может быть жестко закодированным значением в базе кода. :)
6 Kaz 07/25/2017
Почему я когда-либо пишу дерьмовый код и очищаю его, когда я могу найти хороший качественный код качества почти так же быстро, как я могу напечатать? :)
1 Kaz 07/27/2017
@TimothyTruckle Что это, если требуется 50 минут, чтобы найти самое простое изменение, но только 5, чтобы найти второе простейшее возможное изменение? Пойдем ли мы со вторым простейшим или продолжаем искать простейшие?

Timothy Truckle 07/27/2017.

Когда вы пишете «реальный» код в TDD?

red фаза - это место, где вы write код.

На этапе refactoring основной целью является delete кода.

В red фазе вы делаете все, чтобы пройти тест as quick as possible и at any cost . Вы полностью игнорируете то, что вы когда-либо слышали о хороших методах кодирования или шаблоне проектирования. Создание тестового зеленого - все, что имеет значение.

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

Наконец, вы улучшаете читаемость, переименовывая идентификаторы и извлекаете magic numbers и / или литеральные строки в константы.


Это не red-refactor, это красный-зеленый-рефактор. - Роб Киньон

Спасибо, что указали на это.

Итак, это green фаза, где вы пишете real code

На red фазе вы записываете executable specification ...

2 comments
Rob Kinyon 07/27/2017
Это не red-refactor, это красный-зеленый-рефактор. «Красный» - вы берете свой тестовый набор от зеленого (все тесты проходят) до красного (один тест не удается). «Зеленый» - это то, где вы небрежно снимаете свой тестовый пакет с красного (один тест не проходит) до зеленого (все тесты проходят). «Рефактор» - это то место, где вы берете свой код и делаете его довольно, сохраняя при этом все тесты.
Timothy Truckle 07/27/2017
@RobKinyon Спасибо, обновил ответ.

Robert Andrzejuk 07/27/2017.

Вы пишете Real Code все время.

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

Вы думаете, что не пишете полезный ( real ) код, потому что через мгновение вы можете его реорганизовать.

Code-Refactoring - это процесс реструктуризации существующего компьютерного кода, изменяющий факторинг, без изменения его внешнего поведения.

Это означает, что даже если вы меняете код, условия, в которых выполняется код, остаются неизменными. И проверки ( tests ), которые вы внедрили для проверки своего кода, уже существуют, чтобы проверить, не изменились ли ваши изменения. Таким образом, код, который вы написали все время, находится там, совсем по-другому.

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

Когда я читал «Книгу» (*) в TDD, для меня самой важной особенностью, которая выделялась, был: список TODO. Это показало мне, что TDD также является методом, помогающим разработчикам сосредоточиться на одной вещи за раз. Так что это также ответ на ваш вопрос aboout How much Real code to write ? Я бы сказал, что достаточно кода, чтобы сосредоточиться на 1 штуке за раз.

(*) «Испытательное развитие: по примеру» Кента Бек

1 comments
2 Robert Andrzejuk 07/27/2017
«Испытательное развитие: по примеру» Кента Бек

Zenilogix 07/31/2017.

Вы не пишете код, чтобы ваши тесты терпели неудачу.

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

Все дело в написании первоначально неудачных тестов - это сделать две вещи:

  1. Закройте все случаи - все номинальные случаи, все крайние случаи и т. Д.
  2. Подтвердите свои тесты. Если вы только когда-нибудь увидите, как они проходят, как вы можете быть уверены, что они будут достоверно сообщать о сбое, если это произойдет?

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

В моем собственном опыте (C # /. NET) чистый тест-тест - это немного недостижимый идеал, потому что вы не можете скомпилировать вызов метода, который еще не существует. Таким образом, «тест первым» - это действительно о кодировании интерфейсов и реализации stubbing вначале, а затем написание тестов против заглушек (которые изначально будут терпеть неудачу) до тех пор, пока заглушки не будут правильно сформированы. Я никогда не пишу «неудачный код», просто строя из заглушек.


Zan Lynx 07/27/2017.

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

После того как вы проверили все маленькие «единицы», вы проверите их все собранные или «интегрированные». Обычно это целая программа или библиотека.

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

Все это ТАКЖЕ тестирование, но у меня нет довольно красного / зеленого дисплея для результатов. Это либо преуспевает, либо я выкапываю несколько тысяч строк кода ошибки, чтобы узнать, почему.

Здесь вы проверяете «реальный код».

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

1 comments
Peter Mortensen 07/27/2017
(Его = притяжательное, это = «это» или «оно есть». См. Например, How to Use Its and It's .)

user3791372 07/27/2017.

В ответ на заголовок вопроса: «Когда вы пишете« реальный »код в TDD?», Ответ таков: «вряд ли когда-либо» или «очень медленно».

Вы говорите, как студент, поэтому я отвечу, как бы советуя студенту.

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

Работа кодера заключается исключительно в создании кода. Код, который работает очень хорошо. Вот почему вы, кодер, планируете код в своем уме, на бумаге, в подходящем приложении и т. Д., И вы планируете заранее обойти возможные недостатки / дыры, думая логически и латерально перед кодированием.

Но вам нужно знать, как разорвать ваше приложение, чтобы иметь возможность разрабатывать достойный код. Например, если вы не знали о Little Bobby Table (xkcd 327), то, вероятно, вы не будете дезинфицировать свои входы до работы с базой данных, так что вы не сможете защитить свои данные вокруг этой концепции.

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

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

Пожалуйста, не падайте эту ловушку и не смотрите на свою роль кодирования на то, что она есть - работа кодера - исключительно для создания кода. Код, который работает очень хорошо. Теперь, помните, что вы будете на часах в качестве профессионального кодера, и вашему клиенту все равно, если вы написали 100 000 утверждений, или 0. Они просто хотят, чтобы код работал. На самом деле хорошо.

5 comments
3 johnny 07/25/2017
Я даже не очень близкий к ученику, но я читаю и стараюсь применять хорошие методы и быть профессионалом. Поэтому в этом смысле я «студент». Я просто задаю очень простые вопросы, потому что так я. Мне нравится точно знать, почему я делаю то, что делаю. Суть дела. Если я этого не сделаю, мне это не нравится и начните задавать вопросы. Мне нужно знать, почему, если я собираюсь использовать его. TDD кажется интуитивно хорошим в некотором роде, как знать, что вам нужно для создания и мышления, но реализация была трудно понять. Думаю, теперь я лучше понимаю.
4 Sean Burton 07/27/2017
Это правила TDD. Вы можете писать код, как хотите, но если вы не следуете этим трем правилам, вы не делаете TDD.
2 user3791372 07/27/2017
«Правила» одного человека? TDD - это предложение помочь вам закодировать, а не религию. Грустно видеть, что так много людей придерживаются такой идеи. Даже происхождение TDD противоречиво.
2 Alex 07/28/2017
@ User3791372 TDD - очень строгий и четко определенный процесс. Даже если многие думают, что это просто означает «Проведите некоторое тестирование, когда вы программируете», это не так. Давайте попробуем не смешивать здесь термины, этот вопрос касается процесса TDD, а не общего тестирования.

Related questions

Hot questions

Language

Popular Tags