Коли ви пишете "реальний" код в TDD?


147

Усі приклади, які я читав і бачив у навчальних відео, мають спрощені приклади. Але те, що я не бачу, як зробити "справжній" код після того, як я позеленію. Це частина "Refactor"?

Якщо у мене досить складний об'єкт зі складним методом, і я пишу свій тест і мінімальний мінімум, щоб він пройшов (після того, як він вперше виходить з ладу, Червоний). Коли я повернусь назад і напишу реальний код? І скільки реального коду я пишу перед тим, як повторно перевірити? Я здогадуюсь, що останній - це більше інтуїція.

Редагувати: Дякую всім, хто відповів. Усі ваші відповіді надзвичайно допомогли мені. Здається, є різні ідеї щодо того, про що я питав чи плутав, і, можливо, є, але те, що я запитував, - сказати, у мене є заявка на будівництво школи.

У своєму дизайні у мене є архітектура, з якої я хочу розпочати, Історії користувачів тощо. Звідси я беру ці Історії користувачів і створюю тест, щоб перевірити Історію користувачів. Користувач каже: У нас люди вступають до школи та сплачують реєстраційні внески. Отже, я думаю про спосіб зробити це невдалим. Роблячи це, я проектую тестовий клас для X класу (можливо, студента), який не зможе. Потім я створюю клас "Учень". Можливо, "Шкільну" я не знаю.

Але, в будь-якому випадку, TD Design змушує мене продумати історію. Якщо я можу зробити тест невдалим, я знаю, чому він виходить з ладу, але це передбачає, що я можу змусити його пройти. Йдеться про проектування.

Я порівнював це з думкою про рекурсію. Рекурсія не є важким поняттям. Це може бути важче насправді відстежувати це в голові, але насправді найскладніше - це знати, коли рекурсія «ламається», коли зупинятись (моя думка, звичайно.). Тому я повинен думати про те, що зупиняється рекурсія першою. Це лише недосконала аналогія, і вона передбачає, що кожна рекурсивна ітерація - це "пропуск". Знову лише думка.

У впровадженні Школи важче бачити. Числові та банківські книги є "простими" в тому сенсі, що ви можете використовувати просту арифметику. Я можу побачити + b і повернути 0 і т. Д. У випадку з системою людей мені доводиться більше думати над тим, як це здійснити . У мене є концепція провалу, проходу, рефактора (здебільшого через навчання та це питання.)

Те, що я не знаю, засноване на браку досвіду, на мою думку. Я не знаю, як не вдалося підписати нового студента. Я не знаю, як не вдалося, щоб хтось набрав прізвище, і це було збережено до бази даних. Я знаю, як зробити +1 для простої математики, але з такими особами, як людина, я не знаю, чи я лише тестую, чи не отримую я унікальний ідентифікатор бази даних або щось інше, коли хтось вводить ім’я в база даних або обидва, або ні.

Або, можливо, це показує, що я все ще плутаюся.


193
Після TDD люди йдуть додому на ніч.
варення

14
Чому ви вважаєте, що написаний вами код не справжній?
Гойо

2
@RubberDuck Більше, ніж інші відповіді. Я впевнений, що скоро звернусь до цього. Це все-таки іноземне, але я не збираюся відмовлятися від цього. Те, що ви сказали, мало сенс. Я просто намагаюся зробити це сенсом у моєму контексті чи звичайній діловій програмі. Можливо, система інвентаризації тощо. Я маю це врахувати. Я вдячний за ваш час. Дякую.
Джоні

1
Відповіді вже забиті цвяхом на голові, але поки всі ваші тести пройдуть, і вам не потрібні нові тести / функціональні можливості, можна вважати, що у вас закінчений код, обв'язка смугою.
ESR

3
У питанні є припущення, яке може бути проблематичним у "У мене досить складний об'єкт зі складним методом". У TDD ви спочатку пишете свої тести, щоб почати з досить простого коду. Це змусить вас кодувати зручну для тесту структуру, яка повинна бути модульною. Так складна поведінка буде створена шляхом комбінування більш простих об'єктів. Якщо ви закінчите досить складний об'єкт або метод, тоді це рефактор
Borjab

Відповіді:


243

Якщо у мене досить складний об'єкт зі складним методом, і я пишу свій тест і мінімальний мінімум, щоб він пройшов (після того, як він вперше виходить з ладу, Червоний). Коли я повернусь назад і напишу реальний код? І скільки реального коду я пишу перед тим, як повторно перевірити? Я здогадуюсь, що останній - це більше інтуїція.

Ви не «повертаєтесь назад» і не пишете «реальний код». Це все реальний код. Що ви робите, - це повернутися назад і додати ще один тест, який змушує вас змінити код, щоб зробити новий тест-пропуск.

Що стосується того, скільки коду ви пишете перед повторним тестуванням? Немає. Ви пишете нульовий код без провального тесту, що змушує вас писати більше коду.

Помітили шаблон?

Давайте пройдемося (ще) простий приклад у надії, що це допоможе.

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

Легкий горох.

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();
}

І ми висвітлювали кожен розумний внесок, а як бути з необґрунтованим внеском? Що станеться, якщо ми пройдемо 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 виглядав би приблизно так.

  • Негативний
  • Нуль
  • Один
  • Два
  • Три
  • Четверо
  • П’ять
  • Шість (нетривіальне кратне 3)
  • Дев'ять (3 квадрата)
  • Десять (нетривіальне кратне 5)
  • 15 (кратні 3 і 5)
  • 30 (нетривіальне кратне 3 і 5)

3
Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
maple_shaft

47
Якщо я повністю не розумію цієї відповіді: "Ми могли б зробити щось нерозумно, якби n == 1, але ми перейдемо до розумного рішення". - вся справа була дурною. Якщо ви знаєте спереду, ви хочете функцію, яка виконує <spec>, пишіть тести для <spec> і пропускайте ту частину, де ви пишете версії, які явно не виконують <spec>. Якщо ви знайшли помилку в <spec>, тоді обов'язково: спочатку напишіть тест, щоб переконатися, що ви можете його виконати до виправлення, і спостерігайте за тестовими пропусками після виправлення. Але не потрібно підробляти всі ці проміжні кроки.
GManNickG

16
Зауваження, які вказують на основні недоліки у цій відповіді та TDD загалом, були переміщені до чату. Якщо ви плануєте використовувати TDD, будь ласка, прочитайте "чат". На жаль, коментарі "якості" зараз приховані серед набору чатів, які читають майбутні студенти.
користувач3791372

2
@GManNickG Я вважаю, що справа в тому, щоб отримати потрібну кількість тестів. Заздалегідь склавши тести, можна легко пропустити те, які спеціальні випадки слід перевірити, що призводить до того, що в тестах ситуація не буде належним чином висвітлена, або, по суті, до тієї самої ситуації безглуздо покривається безліч разів тестів. Якщо ви можете зробити це без цих проміжних кроків, чудово! Не кожен може це зробити, хоча це є потребою.
hvd

1
І ось цитата Кента Бека про рефакторинг: "Тепер, коли тест запускається, ми можемо зрозуміти (як у" реальному ") впровадження резюме ()". Потім він переходить до зміни константи на змінну. Я вважав, що ця цитата цілком відповідає питанню.
Кріс Волетрт

46

"Реальний" код - це код, який ви пишете, щоб зробити свій тестовий пропуск. Дійсно . Це так просто.

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

Ідея кроку рефактора - це просто очистити те, що ви написали, як тільки ви щасливі, що це відповідає вимогам.

Поки фактично написані вами тести охоплюють ваші вимоги до продукту, коли вони проходять, тоді код буде завершений. Подумайте над тим, якщо всі ваші бізнес-вимоги мають тест, а всі ці тести зелені, що ще можна написати? (Гаразд, у реальному житті ми, як правило, не маємо повного висвітлення тесту, але теорія є здоровою.)


45
Тести одиничних виробів насправді не можуть охопити ваші вимоги до продукту навіть щодо тривіальних вимог. У кращому випадку вони вибирають простір вводу-виводу, і ідея полягає в тому, що ви (правильно) узагальнюєте повний простір вводу-виводу. Звичайно, ваш код може просто бути великим, switchу випадку з кожним тестом одиниці, який би пройшов усі тести і не вдався до будь-яких інших входів.
Дерек Елкінс

8
@DerekElkins TDD наказує не виконати тести. Не пройшли одиничні тести.
Taemyr

6
@DerekElkins, тому ви не просто пишете одиничні тести, а також чому є загальне припущення, що ви намагаєтеся зробити щось не просто підробляти!
jonrsharpe

36
@jonrsharpe За цією логікою я ніколи не писав би тривіальних реалізацій. Наприклад, у прикладі FizzBuzz у відповіді RubberDuck (який використовує лише одиничні тести), перша реалізація чітко "просто підробляє це". Моє розуміння питання саме в цій дихотомії між написанням коду, який ви знаєте, є неповним, і кодом, який, по-справжньому, вважаєте, реалізує вимогу, "реальний код". Моя «велика switch» була задумана як логічна крайність «написання голого мінімуму, щоб зробити тести зеленими». Я розглядаю питання ОП як: де в TDD є принцип, який дозволяє уникнути такого великого switch?
Дерек Елкінс

2
@GenericJon Це занадто оптимістично в моєму досвіді :) Для одного, є люди, які насолоджуються бездумною повторюваною роботою. Вони будуть щасливішими з гігантською заявою про перемикання, ніж зі «складним прийняттям рішень». А щоб втратити роботу, їм або потрібен хтось, хто викликає їх на техніку (і краще мати хороші докази, що це насправді втрачає можливості / гроші компанії!), Або роблять виключно погано. Після перегляду технічного обслуговування багатьох подібних проектів я можу сказати, що дуже наївний код може тривати десятиліттями, якщо це робить клієнта щасливим (і платить).
Луань

14

Коротка відповідь полягає в тому, що "реальний код" - це код, який робить тестовий прохід. Якщо ви можете зробити тестовий пропуск за допомогою іншого, крім реального коду, додайте більше тестів!

Я погоджуюся, що багато навчальних посібників щодо TDD спрощені. Це працює проти них. Занадто простий тест для методу, який, скажімо, обчислює 3 + 8, дійсно не має іншого вибору, крім того, щоб також обчислити 3 + 8 та порівняти результат. Це робить вигляд, що ви просто дублюєте код у всьому, і тестування безглуздо, додаткова робота, схильна до помилок.

Коли ви добре пройдете тестування, це повідомить про те, як ви структуруєте свою програму та як пишете свій код. Якщо у вас виникли проблеми з розсудливими, корисними тестами, вам, мабуть, варто трохи подумати над своїм дизайном. Добре розроблену систему легко перевірити - значущі розумні тести легко думати і реалізовувати.

Коли ви спочатку пишете свої тести, спостерігаєте за тим, як вони виходять з ладу, а потім записуєте код, який змушує їх пройти, це дисципліна для того, щоб усі ваші коди мали відповідні тести. Я не рабсько дотримуюся цього правила, коли кодую; часто пишу тести після факту. Але спочатку тести допомагають вам бути чесними. Маючи певний досвід, ви почнете помічати, коли кодуєте себе в кутку, навіть коли спочатку не пишете тести.


6
Особисто я б написав тест assertEqual(plus(3,8), 11), ні assertEqual(plus(3,8), my_test_implementation_of_addition(3,8)). У більш складних випадках ви завжди шукаєте засоби доведення результату правильними, крім динамічного обчислення правильного результату в тесті та перевірки рівності.
Стів Джессоп

Отже, для дійсно нерозумного способу зробити це в цьому прикладі, ви можете довести, що 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)
Стів Джессоп,

... оскільки це дозволяє уникнути великого страху, який полягає в тому, що під час написання тесту ми зробимо ту саму помилку на тему "як додати 10", яку ми зробили в живому коді. Тож тест ретельно уникає написання будь-якого коду, який додає 10 до чого-небудь, у тесті, який plus()може додати 10 до речей. Ми, звичайно, покладаємось на перевірені програмістом значення вхідних циклів, звичайно.
Стів Джессоп

4
Просто хочу зазначити, що навіть якщо ви пишете тести після факту, все-таки хороша ідея спостерігати за тим, як вони виходять з ладу; знайдіть частину коду, яка здається вирішальною для того, над чим ви працюєте, трохи змініть його (наприклад, замініть + на -, або будь-що інше), запустіть тести і спостерігайте за тим, як вони виходять з ладу, скасуйте зміни та спостерігайте, як вони пройдуть. Я багато разів робив це, тест насправді не провалюється, що робить його гіршим, ніж марним: це не тільки те, що нічого не тестують, це дає мені помилкову впевненість, що щось тестують!
Варбо

6

Іноді деякі приклади щодо TDD можуть вводити в оману. Як зазначали інші люди раніше, код, який ви пишете для проходження тестів, є справжнім кодом.

Але не думайте, що справжній код виглядає як магія - це неправильно. Вам потрібно краще зрозуміти, чого ви хочете досягти, і тоді вам потрібно підібрати тест відповідно, починаючи з найпростіших і кутових справ.

Наприклад, якщо вам потрібно написати лексему, ви починаєте з порожнього рядка, потім з купою пробілів, потім числом, потім числом, оточеним пробілами, потім неправильним числом і т. Д. Ці невеликі перетворення призведуть до того, що ви правильний алгоритм, але ви не переходите з найпростішого випадку до дуже складного випадку, вибраного тупо, щоб зробити реальний код.

Боб Мартін це чудово пояснює тут .


5

Частина рефактора очищується, коли ви втомилися і хочете їхати додому.

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

Це може бути таким же простим, як перейменування GreetImplдо GreetWorldстворення GreetMomкласу (після додавання тесту), щоб додати функцію, яка надрукує "Привіт мамо".


1

Але справжній код з'явиться на етапі рефактора фази TDD. Тобто код, який повинен бути частиною остаточного випуску.

Тести потрібно проводити щоразу, коли ви вносите зміни.

Девізом життєвого циклу TDD було б: ЧЕРВЕНИЙ ЗЕЛЕНИЙ РЕФАКТОР

ЧЕРВОН : Напишіть тести

ЗЕЛЕНИЙ : Зробіть чесну спробу отримати функціональний код, який проходить тести якнайшвидше: дублікат коду, незрозуміло названі змінні хаки вищого порядку тощо.

РЕФАКТОР : Очистіть код, належним чином назвіть змінні. НАДУВАЙТЕ код.


6
Я знаю, що ви говорите про "зелену" фазу, але це означає, що значення, що повертаються до проводів, можуть бути доречними. На мій досвід, "Зелений" повинен бути чесною спробою зробити робочий код для задоволення вимоги, він може бути не ідеальним, але він повинен бути настільки ж повним і "розвантажуваним", як розробник може керувати за перший прохід. Рефакторинг, мабуть, найкраще робити через деякий час після того, як ви зробили більше розвитку, і проблеми з першим проходом стануть більш очевидними, і з'являться можливості для DRY.
mcottle

2
@mcottle: ви можете бути здивовані, скільки реалізацій сховища лише для отримання можуть бути твердо кодованими значеннями в кодовій базі. :)
Брайан Ботчер

6
Навіщо мені коли-небудь писати лайний код і очищати його, коли я можу вивернути хороший, якісний код якості майже так само швидко, як я можу набрати? :)
Каз

1
@Kaz Тому що ви ризикуєте додати неперевірену поведінку . Єдиний спосіб забезпечити тестування на кожну бажану поведінку - це зробити можливі зміни симплетів незалежно від того, наскільки це хитро. Іноді наступний рефакторинг викликає новий підхід, про який ви не думали заздалегідь ...
Тімоті Вікторле

1
@TimothyTruckle Що знадобиться 50 хвилин, щоб знайти найпростішу можливу зміну, але лише 5, щоб знайти другу найпростішу можливу зміну? Ми йдемо з другим найпростішим чи продовжуємо шукати найпростіший?
Каз

1

Коли ви пишете "реальний" код в TDD?

Червона фаза , де писати код.

На етапі рефакторингу головна мета - видалення коду.

У червоній фазі ви робите все, щоб тест пройшов якнайшвидше і за будь-яку ціну . Ви повністю нехтуєте тим, що ви коли-небудь чули про добрі практики кодування або модель дизайну. Зробити тест зеленим - це все, що має значення.

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

Нарешті, ви покращуєте читабельність шляхом перейменування ідентифікаторів та витягування магічних чисел та / або буквальних рядків до констант.


Це не червоно-рефактор, це червоно-зелений-рефактор. - Роб Кіньйон

Дякуємо, що вказали на це.

Отже, це зелена фаза, коли ви пишете реальний код

У червоній фазі ви пишете специфікацію виконуваного файлу ...


Це не червоно-рефактор, це червоно-зелений-рефактор. "Червоний" - це те, що ви приймаєте свій тестовий набір із зеленого (всі тести проходять) до червоного (один тест не вдається). "Зелений" - це те, коли ви неохайно приймаєте тестовий набір від червоного (один тест не вдається) до зеленого (всі тести пройдено). "Рефактор" - це те, де ви берете свій код і зробите його гарним, зберігаючи всі тести.
Роб Кіньйон

1

Ви постійно пишете Реальний код .

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

Ви думаєте, що ви не пишете корисного ( справжнього ) коду, тому що за мить ви можете переробити його.

Редакторинг коду - це процес реструктуризації існуючого комп'ютерного коду - зміна факторингу - без зміни зовнішньої поведінки.

Це означає, що незважаючи на те, що Ви змінюєте код, умови, які виконував код, залишаються незмінними. І чеки ( тести ), які ви здійснили для підтвердження свого коду, вже є, щоб перевірити, чи змінили ваші зміни. Тож код, про який ви писали весь час, є там, просто по-іншому.

Ще одна причина Ви можете подумати, що це не справжній код, це те, що ви робите приклади, коли кінцева програма вже може бути передбачена Вами. Це дуже добре, так як він показує вас є знання про домені Ви програмуєте в.
Але багато разів програмістів в області , яка є новою , невідомою їм. Вони не знають, яким буде кінцевий результат, і TDD - це техніка запису програм поетапно, документуючи наші знання про те, як повинна працювати ця система, і підтверджуючи, що наш код працює таким чином.

Коли я читав Книгу (*) на TDD, для мене найважливішою особливістю був: список TODO. Це показало мені, що TDD - це також техніка, яка допомагає розробникам зосередитися на одній справі. Тож це також відповідь на Ваше запитання перед тим, скільки реального коду потрібно написати ? Я б сказав достатньо коду, щоб зосередити увагу на одній речі одночасно.

(*) «Розробка тестових процесів: за прикладом» Кента Бека


2
"Розробка тестових моделей: за прикладом" Кент Бек
Роберт Анджежук

1

Ви не пишете код, щоб зробити тести невдалими.

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

Вся справа в написанні початково невдалих тестів полягає в тому, щоб зробити дві речі:

  1. Покрийте всі справи - усі іменні регістри, усі крайові справи тощо.
  2. Підтвердьте свої тести. Якщо ви коли-небудь бачите, як вони проходять, як ви можете бути впевнені, що вони надійно повідомлять про помилку, коли це станеться?

Справа в червоно-зеленому-рефакторі полягає в тому, що написання правильних тестів спочатку дає вам впевненість у тому, що ви знаєте, що код, який ви написали для проходження тестів, є правильним, і дозволяє вам рефактор з впевненістю, що ваші тести повідомить вас, як тільки щось ламається, тож ви можете негайно повернутися назад і виправити це.

На мій власний досвід (C # /. NET), чистий тест-перше - це трохи недосяжний ідеал, тому що ви не можете скласти виклик до методу, який ще не існує. Отже, "тест спочатку" - це дійсно спочатку кодування інтерфейсів та реалізація заглушки, а потім написання тестів проти заглушок (які спочатку будуть відмовлені), поки заглушки не будуть належним чином сформовані. Я ніколи не пишу "провальний код", просто будую із заглушок.


0

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

Після того, як ви протестували всі маленькі "одиниці", ви протестуєте їх усі зібрані або "інтегровані". Зазвичай це ціла програма чи бібліотека.

У коді, який я написав, інтеграційні тести бібліотеки з різними тестовими програмами, які читають дані та передають їх у бібліотеку, а потім перевіряють результати. Потім я це роблю нитками. Потім я це роблю з нитками та виделкою () посередині. Потім я запускаю його і вбиваю -9 через 2 секунди, потім запускаю його і перевіряю його режим відновлення. Я це розмиваю. Я катую це всілякими способами.

ВСЕ ТЕБЕ ТАКОЖ тестування, але у мене немає досить червоного / зеленого дисплея для результатів. Це або вдається, або я перекопаю кілька тисяч рядків коду помилки, щоб з’ясувати, чому.

Ось де ви перевіряєте "реальний код".

І я просто подумав про це, але, можливо, ти не знаєш, коли тебе повинні зробити написання одиничних тестів. Ви закінчуєте писати одиничні тести, коли ваші тести виконують все, що ви вказали. Іноді ви можете втратити це серед усіх помилок та проблем, тому ви можете створити приємну тестову групу тестів щасливого шляху, які просто проходять через специфікації.


(його = присвійний, це = "є" або "є". Див., наприклад, як його використовувати і це .)
Peter Mortensen

-6

У відповідь на назву питання: "Коли ви пишете" справжній "код в TDD?", Відповідь: "навряд чи колись" або "дуже повільно".

Ти звучиш як студент, тому я відповім так, ніби радив студенту.

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

Завдання кодера полягає виключно у створенні коду. Код, який працює дуже добре. Ось чому ви, кодер, плануєте код у своєму розумі, на папері, у відповідній програмі тощо, і плануєте заздалегідь обходити можливі недоліки / дірки, думаючи логічно та збоку перед кодуванням.

Але вам потрібно знати, як зламати свою програму, щоб мати можливість створити гідний код. Наприклад, якби ви не знали про Таблицю Little Bobby (xkcd 327), ви, ймовірно, не санітували б свої дані, перш ніж працювати з базою даних, тому ви б не змогли захистити свої дані навколо цієї концепції.

TDD - це лише робочий процес, розроблений для мінімізації помилок у вашому коді, створюючи тести того, що може піти не так, перш ніж кодувати свою програму, оскільки кодування може стати складним в експоненціальному рівні, тим більше введеного коду, і ви забудете про помилки, про які ви колись думали. Як тільки ви думаєте, що ви закінчили свою заявку, ви запускаєте тести та бум, сподіваємось, вади виявляють помилки.

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

Будь ласка, не потрапляйте в цю пастку і перегляньте свою роль кодування того, що це таке - завдання кодера полягає виключно у створенні коду. Код, який працює дуже добре. Тепер пам’ятайте, що ви будете на годиннику як професійний кодер, і вашому клієнту буде байдуже, чи ви написали 100 000 тверджень, або 0. Вони просто хочуть, щоб код працював. Насправді добре, насправді.


3
Я навіть не близький до студента, але я читаю і намагаюся застосовувати хороші прийоми та бути професійним. Тож у цьому сенсі я "студент". Я просто задаю дуже основні питання, тому що таким я є. Мені подобається точно знати, чому я роблю те, що роблю. Серце справи. Якщо я цього не розумію, мені це не подобається і починаю задавати питання. Мені потрібно знати, чому я збираюся його використовувати. TDD здається інтуїтивно хорошим в чомусь на зразок того, щоб знати, що потрібно для створення та продумувати речі, але реалізацію було важко зрозуміти. Я думаю, я зараз краще розумію.
Johnny


4
Це правила TDD. Ви можете безкоштовно писати код, але хочете, але якщо ви не дотримуєтесь цих трьох правил, ви не робите TDD.
Шон Бертон

2
"Правила" однієї людини? TDD - це пропозиція допомогти вам ввести код, а не релігію. Сумно бачити, що так багато людей так анально дотримуються ідеї. Навіть походження TDD суперечливе.
користувач3791372

2
@ user3791372 TDD - дуже суворий і чітко визначений процес. Навіть якщо багато хто думає, що це просто означає "Зробіть тестування під час програмування", це не так. Спробуємо тут не змішувати терміни, це питання стосується процесу TDD, а не загального тестування.
Алекс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.