Чому TDD працює? [зачинено]


92

Тестова розробка (TDD) в наші дні велика. Я часто вбачаю, що це рекомендується як рішення для широкого кола проблем тут, у програмістів SE та інших місцях. Цікаво, чому це працює.

З інженерної точки зору, це спантеличує мене з двох причин:

  1. Підхід "написати тест + рефактор до проходу" виглядає неймовірно антиінженерним. Якщо, наприклад, будівельні інженери використовували такий підхід для будівництва мостів, або дизайнери автомобілів для своїх автомобілів, наприклад, вони переробляли б мости чи автомобілі з дуже високою вартістю, і в результаті вийшло б заплутане безладдя без продуманої архітектури . Настанова "рефактор до проходу" часто сприймається як мандат забувати архітектурний дизайн і робити все необхідне для виконання тесту; Іншими словами, тест, а не користувач, встановлює вимогу. Як у цій ситуації ми можемо гарантувати хороші «порочності» в результатах, тобто кінцевий результат, який не тільки є правильним, але й розширюється, надійний, простий у використанні, надійний, безпечний, безпечний тощо? Це те, що зазвичай робить архітектура.
  2. Тестування не може гарантувати роботу системи; він може лише показати, що цього немає. Іншими словами, тестування може показати вам, що система містить дефекти, якщо вона не проводить тест, але система, яка проходить всі тести, не є більш безпечною, ніж система, яка їх виходить з ладу. Покриття тесту, якість тесту та інші фактори мають вирішальне значення тут. Неправдиві безпечні почуття, які "всі зелені" результати викликають у багатьох людей, були зареєстровані в цивільній та космічній галузях як вкрай небезпечні, оскільки це може бути інтерпретоване як "система в порядку", коли це справді означає "система настільки ж хороша як наша стратегія тестування ". Часто стратегія тестування не перевіряється. Або хто тестує тести?

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

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


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

9
Я дещо згоден з вашими сумнівами. Я, наприклад, зізнаюся, у мене склалося враження, що наявність тестового набору може мати як побічний ефект певне «пом'якшення» уваги при написанні коду. Звичайно, тести - це непогана річ (обов'язкова, якщо ви хочете мати можливість рефакторації), але лише якщо вони доповнюють увагу до деталей, прикордонних справ, ефективності чи розширюваності, а не якщо вони замінять її.
6502

2
@ 6502: Усіма силами! TDD не є срібною кулею і не вирішить усіх питань, що виникають під час розробки програмного забезпечення. Однак це корисний метод організації робочого процесу. Наприклад, ви можете встановити вимогу, що всі випадки кордону покриваються тестами. Ви все ще повинні знати, що це за прикордонні справи, але тепер у вас є також інструмент, щоб перевірити, чи правильно ваш код стосується їх.
Mchl

2
@CesarGon, можливо, вам буде цікаво і це запитання, яке я запитав на ТАК деякий час тому ... Не зовсім TDD, але пов'язані з цим ... Деякі дуже просвітливі відповіді там.
AviD

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

Відповіді:


66

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

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

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

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

Це все, що ви можете встановити за допомогою TDD.

І справді, тестування не є гарантією. Програми розбиваються, машини розбиваються, а будівлі починають робити смішні речі, коли дме вітер. Але ... "безпека" не є булевим питанням. Навіть коли ви ніколи не можете включити все, вміючи покривати - скажімо - 99% можливих ситуацій краще, ніж покривати лише 50%. Не випробовуючи, а потім з'ясовуючи, сталь не влаштувалась добре, і вона крихка і ламається при першому ударі молоточка, коли ви просто виставляєте свою основну структуру - це просто марна трата грошей. Що є й інші проблеми, які все-таки можуть зашкодити будівлі, не робіть це менш дурним, щоб дозволити легко усунутий недолік збити ваш дизайн.

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


7
+1 - говорити про те, де відбувається тестування у виробництві. Чудова точка.
Адам Лір

11
Ви кажете "деталі перевірені". Впевнений, але не призначений для тестування. Деталь літака розроблена не на випробувальній основі, а в архітектурному, наборовому дизайні. Подібності з TDD тут не існує.
CesarGon

3
Додаючи до цього: TDD, на мою думку, головним чином стосується способів переконатися, що ви можете перевірити деталі, а не велике "все або нічого" в кінці. Але адагіум TDD "спочатку скласти тест" не означає "зробити тест, перш ніж задуматися над тим, що ти хочеш досягти". Тому що мислення тесту є частиною проектування. Вказавши, що ви хочете зробити саме цю частину, - це дизайн. Перш ніж ви коли-небудь почнете набирати текст, ви вже зробили деякі розробки. (Таким чином, я думаю, що термін "тестова схема дизайну" вводить в оману однобічний шлях, де це дійсно цикл зворотного зв'язку).
Інка

2
+1: Програмне забезпечення - це суто дизайн. Аналогія мосту у питанні абсолютно неправильна. TDD повністю застосовується для тестування поза блоком. Тестово-керований дизайн застосовується на всіх шарах дизайну.
S.Lott

3
@CesarGon: Ні, TDD керує РОЗВИТКУ тестуванням. Це відрізняється від керування дизайном. Дизайн диктує, як би ви використовували систему, і, отже, які тести вам потрібно буде застосувати, щоб повторити таку поведінку. Впровадження цих тестів часто допомагає вдосконалити дизайн.
deworde

26

IMO, більшість історій успіху для TDD є фальшивими та просто з маркетинговою метою. Успіху в цьому може бути дуже мало, але лише для невеликих застосувань. Я працюю над великим додатком Silverlight, де використовуються принципи TDD. У програмі пройшли сотні тестів, але вона все ще не є стабільною. Деякі частини програми не перевіряються через складну взаємодію користувачів. Результати тестів з великою кількістю глузувань і важко зрозуміти код.

Спочатку, коли ми пробували TDD, все здається гарним. Мені вдалося написати багато тестів і знущатися над частинами, які є жорсткими для одиничного тесту. Після того, як у вас з'явиться достатня кількість коду і потрібна зміна інтерфейсу, ви накручуєтесь. Потрібно виправити багато тестів, і ви перепишете більше тестів, ніж фактична зміна коду.

Пітер Норвіг Пояснює свою думку щодо TDD у книзі «Кодери на роботі».

Seibel: А як щодо ідеї використання тестів для управління дизайном?

Норвіг: Тести я бачу більше як спосіб виправлення помилок, а не як спосіб конструювання. Цей крайній підхід сказати: "Ну, перше, що ти робиш - це написати тест, який говорить, що я отримаю правильну відповідь наприкінці", а потім ти запускаєш його і бачиш, що він не вдається, і тоді ти кажеш: "Що я знадобиться далі? »- це не здається правильним способом щось мені розробити. Здається, тільки якщо це було б так просто, що рішення було б заздалегідь визначене, це мало б сенс. Я думаю, що ти повинен подумати над цим спочатку. Ви повинні сказати: «Які шматки? Як я можу писати тести на твори, доки я не знаю, які з них є? "І потім, як тільки ви це зробите, тоді добре піддаватись тестуванню для кожного з цих творів і добре зрозуміти, як вони взаємодіють один з одним. і прикордонні випадки тощо. Усі вони повинні мати тести. Але я не думаю, що ви керуєте цілим дизайном, кажучи: "Цей тест не вдався".


7
Тепер, якщо ви розповісте ці факти людям та консультантам TDD, відповідь, яку ви отримаєте, буде:well, you haven't done TDD right!
Наванеєт КН,

10
І вони мали б рацію. Ми робимо BDD / TDD на дуже високій гучності, і вона працює добре. Тести є, щоб сказати вам, що ви порушили очікувану поведінку. Якщо ви збираєтесь і змінюєте це пізніше, "ламаючи" тести, ви насправді робите неправильно. Спочатку слід змінити тести, щоб закріпити НОВУ поведінку системи, а потім змінити її. І так, якщо ви робите це правильно, ви пишете свої тести, починаючи з того, "що ця річ має робити", і процес написання тесту допомагає вам думати, "що ІТ потрібно робити для своєї роботи". О, і жодних консультантів ніколи не використовували ...
Енді,

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

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

2
На мій досвід роботи TDD працює для невеликих додатків або модулів. Коли мені доводиться працювати над чимось складним TDD, уповільнює мене, тому що воно змушує мене написати детальну специфікацію (для запуску), перш ніж я зрозумів загальну картину в своєму розумі: тому я рано втрачаю деталі, і часто мені доводиться викиньте цілу купу тестів, якщо я дізнаюся, що певні заняття мені не потрібні (я все ще граю з дизайном). У таких випадках я вважаю за краще спочатку отримати розумний загальний дизайн, а потім деталізувати деталі реалізації (можливо, використовуючи TDD).
Джорджіо

25

Тест Driven Design працює для мене з наступних причин:

Це форма, яку можна виконати.

Це означає, що ви можете бачити з тестових випадків:

  1. ЩО названий код повністю заповнює специфікацію, оскільки очікувані результати є саме там у тестових випадках. Візуальний огляд (який очікує проходження тестових випадків) може негайно сказати "о, цей тест перевіряє, що виклик рахунку-фактури компанії з огляду на цю ситуацію повинен мати ТАКИЙ результат".
  2. ЯК слід викликати код. Фактичні кроки, необхідні для проведення тестів, визначаються безпосередньо без зовнішніх лісів (бази даних викреслюються тощо).

Ви пишете погляд спочатку зовні.

Часто код пишеться таким чином, щоб ви спочатку вирішили проблему, а потім ви думали, як називати код, який ви тільки що написали. Це часто дає незручний інтерфейс, оскільки "просто додати прапор" часто легше і т. Д. Думаючи, що "нам потрібно зробити ЦЕ, щоб тестові вітрини виглядали, ЩО" спереду, ви перевернете це. Це дасть кращу модульність, оскільки код буде записаний відповідно до інтерфейсу, що викликається, а не навпаки.

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

Ви швидше закінчите

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

Це означає, що ви можете сказати, коли робота потрібна чи ні (чи допомагає це пройти тест), вам потрібно зробити менше.

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

Недавнє дослідження

"Результати тематичних досліджень свідчать про те, що щільність дефектів перед випуском чотирьох продуктів знизилася між 40% і 90% щодо аналогічних проектів, які не використовували практику TDD. початковий час розробки після прийняття TDD. " ~ Результати та досвід 4 промислових команд


5
До цього я додам, що ви насправді маєте дещо розумне та чітке керівництво щодо того, коли закінчите. Без якоїсь чіткої процедури об'єктивно перевірити, чи виконали ви завдання, його важко знати. Мій власний досвід включає багато годин і днів, витрачених на "переговори", чи було виконано завдання, і тривалий постійний рух лінії. Це впливає на всі рівні управління проектами, включаючи планування, адже як ви можете запланувати таке завдання? Чіткіші цілі із швидшим поворотом збільшують пропускну здатність та зв’язок.
Edward Strange

Це має бути прийнятою відповіддю.
Нінг

19

Процес створення програмного забезпечення - це не процес написання коду. Жоден програмний проект не повинен починатися спочатку без плану «широкого кола». Подібно до того, як проект спорудження двох берегів річки потребує спочатку такого плану.

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

У конструкторському будівництві це виглядає приблизно так:

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

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

Дивіться V-модель: http://en.wikipedia.org/wiki/V-Model_%28software_development%29

Давайте подивимось, як це буде працювати для мосту:

  1. Місцева влада каже компанії, що займається будівництвом мостів: "Нам потрібен міст для з'єднання цих двох точок. Міст повинен бути в змозі дозволити n кількість руху в годину і бути готовим до 21 грудня 2012 року" - це визначення Компанія не отримає повної суми (або будь-яких) грошей, якщо вони не зможуть пройти тест.

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

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


Якщо я вас правильно зрозумів, ви говорите, що TDD гаразд, поки (а) він використовується лише для тестування одиниць, і (b) він супроводжується також іншими підходами тестування. Якщо це так, він може звернутися до точки № 2 в ОП. Як би ви зверталися до точки №1?
CesarGon

@CesarGon: TDD також чудово підходить для інтеграційних тестів.
sevenseacat

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

@Karpie: І для приймальних тестів теж! Ви повинні заздалегідь знати, що потрібно, щоб ваша робота була прийнята клієнтом.
Mchl

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

18

На мій погляд, TDD працює тому

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

Конкретно щодо балів, які ви набираєте

  • Код більш ковкий, ніж цегла або сталь, тому його дешевше модифікувати. Ще дешевше, якщо у вас є тести, щоб переконатися, що поведінка не змінюється
  • TDD не є приводом для того, щоб не робити дизайн - архітектура високого рівня, як правило, все-таки радиться, тільки не надто багато деталей. Дизайн переднього плану Big Up не відлякує, але рекомендується робити достатньо дизайн
  • TDD не може гарантувати роботу системи, але запобігає промахуванню безлічі дрібних помилок, через які інакше було б пропущено. Крім того, тому що він, як правило, заохочує краще впорядкований код, його часто легше зрозуміти, тому менше шансів на помилку

3
Також слід додати, що після виявлення дефектів ви можете переконатися, що вони не повторяться, оскільки ви додасте ще один тест.
Енді

16

TL; DR

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

Код - це дизайн

У главі 7 ДПП «Дядько Боб» безпосередньо йдеться про це питання. Дуже на початку розділу він посилається на чудову статтю Джека Ривза, в якій він пропонує, що код - це дизайн (посилання переходить на сторінку, що збирає всі три його статті з цієї теми).

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

TDD як специфікація

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

Напишіть тести на функціональність

Поширена помилка при тестуванні одиниць трапляється, коли ви пишете тести після коду, ви закінчуєте тестування, що код робить те, що він робить. Іншими словами, ви побачите подібні тести

public class PersonTest:Test
{
   [Test]
   TestNameProperty()
   {
      var person=new Person();
      person.Name="John Doe";
      Assert.AreEqual("John Doe", person.Name);
   }
}

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

Хоча зелений - це добре, значення лежить у червоному, у мене був перший справжній «ага» момент у TDD, коли я отримав несподіваний тест з ладу. У мене був набір тестів, які я склав для основи, яку я будував. Додавши нову функцію, я написав на неї тест. Потім написав код, щоб зробити тестовий пропуск. Склади, тестуй ... отримав зелений колір на новому тесті. Але також отримав червоний на іншому тесті, який я не очікував перейти червоний.

Дивлячись на невдачу, я зітхнув з полегшенням, бо сумніваюся, що я впіймав би цю помилку досить довго, якби у мене не було цього тесту на місці. І це був ДУЖЕ неприємний помилок. На щастя, у мене був тест, і він мені точно сказав, що мені потрібно зробити, щоб виправити помилку. Без тесту я б продовжував будувати свою систему (з помилкою, що заражає інші модулі, які залежали від цього коду), і до моменту виявлення помилки було б головним завданням правильно її виправити.

Справжня перевага TDD полягає в тому, що вона дозволяє нам внести зміни з необдуманим відмовою. Це як мережа безпеки для програмування. Подумайте, що було б, якщо артист трапеції помилиться і впаде. З мережею це невтішна помилка. Без цього це трагедія. У цьому ж плані TDD рятує вас від того, щоб перетворити помилки на голову в катастрофи, що вбивають проект.


4
Значення червоних тестів на виявлення помилок є атрибутом Unit Testing в цілому, а не TDD.
Роберт Харві

2
Ти прав у цьому питанні. Але ймовірність того, що я мав би, що конкретна помилка покрита пост-спеціальним тестуванням, нижче.
Майкл Браун

1
Чи можете ви підтримати цю заяву деякими доказами, даними чи ґрунтовним аналізом?
CesarGon

1
@CesarGon це дослідження , хоча програмісти, що працюють над малим проектом, припускають, що розробники, які використовують TDD, виробляють код з кращим тестовим покриттям, ніж ті, що перевіряються після факту (92% -98% проти 80% -90%) і, отже, отримують більше дефекти під час розробки (на 18% менше дефектів, виявлених у коді, створеному за допомогою TDD).
Жуль

11

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

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

З урахуванням цих двох речей, жодна із сторін не робить нічого іншого, що стосується фактичного виконання тестів на програмне забезпечення. Обидва роблять тестування. Обидва НАДАЄТЬСЯ на тестуванні, щоб знайти якомога більше помилок, і обидва використовують тести, щоб перевірити, чи працює програмне забезпечення, а також може бути виявлено на час. Ніхто з половиною підказки не продає програмне забезпечення без тестування, і ніхто з половиною підказки не очікує, що тестування виведе код, який вони продають повністю без проблем.

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

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

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

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

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

На моєму досвіді, TDD - це дуже складна річ для успішної реалізації. Важко скласти тести, написані перед тим, як з'явиться продукт, тому що для автоматичного тестування для того, щоб програмне забезпечення для автоматизації працювало правильно, для багатьох автоматизованих тестувань потрібно щось грати. Також важко завести розробників, які не звикли проводити тестування. Знову і знову я казав людям своєї команди писати тести ПЕРШИЙ. Я ніколи насправді не отримував цього. Зрештою, часові обмеження та політика знищили всі зусилля, щоб ми навіть взагалі не робили одиничні тести. Це, звичайно, призводить до того, що конструкція випадково і сильно з'єднана, так що навіть якби ми цього хотіли, реалізувати це було б надмірно дорого. Уникнення ТО - це те, що TDD в кінцевому підсумку надає розробникам.


+1 Дякую за вичерпну відповідь, Ное. Я погоджуюся, що основна різниця між TDD і не-TDD полягає в тому, коли пишуться тести. Тим НЕ менше, я також вважаю , що перший «D» в TDD означає «ведений», а це означає , що в TDD, в цілому розвиток наводиться тестуванням. Саме це мені здається дивним. У мене немає проблем із написанням тестів, перш ніж будувати те, що буде протестовано. Але дозволяти тестам керувати? Чим відрізняється від зеленого світла щось робити до тих пір, поки поверховий (тобто результат) чудовий?
CesarGon

Ну, Сезаре, що б ви запропонували як кращі, об’єктивніші критерії для вирішення, коли завдання щодо розвитку буде закінчено? Якщо, як і в TDD, тест - це специфікація, на яку спрямований розробник, то розробник зробив свою роботу, коли тест пройде, ні? Так, у тесті можуть бути недоліки, як і у будь-яких специфікаціях. Це не завдання розробників вирішити, хоча. Якщо тест є помилковим, то він виправляється, тоді розробка націлює на нову ціль, і коли все буде зеленим, вони закінчені. Це працює тому, що ЗАВЖДИ є тест, який потрібно пройти ... немає зайвих, недокументованих пуху.
Edward Strange

3
Можливо, я не висловився чітко. Тести можуть бути хорошим способом визначити, коли ви закінчите. Але я не думаю, що вони є гарним способом вирішити, що потрібно будувати. І в TDD я вважаю, що люди використовують тести, щоб вирішити, що вони повинні будувати. Це теж ваш досвід?
CesarGon

Ні. Наші побудови автоматизовані. Вони викликані змінами. Як я вже говорив, TDD - це лише частина рішення.
Едвард Странд

9

Дизайн спочатку

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

Але тестуйте рано

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

Тест та дизайн ... одне і те ж

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

Тоді хто веде шоу?

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

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

твердий до тих пір, поки випробування тверді

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

так, але якщо я зроблю це зі своїм мостом ...

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

Якщо його так добре, як це не завжди працює?

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

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

Для цих команд TDD може бути не дорогою.


7

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

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


2
Мені це подобається - він підкреслює, що його не стільки TDD, що створює переваги (хоча наявність одиничних тестів, очевидно, має величезну кількість цінності), скільки вид коду, який він виробляє в тому сенсі, що його можна перевірити (ізольовано) і з цього випливають усілякі добрі речі (розділення проблем, ін'єкцій ІО та залежностей, тощо, тощо)
Мерф

1
@Murph так TDD допомагає вам бути чесним :)
Альб

1
Якщо чесно, насправді я не переконаний аргументом "легше встати на швидкість" - тести можуть бути корисними, але код (в цілому, не обов'язково ізольовано) дешифрувати дещо складніше, оскільки деякі речі будуть здається, що за допомогою магії, наприклад, ви не знаєте, яку реалізацію IInjectedThing використовуєте.
Мерф

@Murph Теорія полягає в тому, що реалізація IInjectedThing також добре розроблена і охоплена хорошими тестами, тому вам не потрібно знати, що це для того, щоб зрозуміти клас, в який він введений.
Адам Лір

@Anna - так, до певного моменту ... якщо ви намагаєтеся розібратися, де щось порушено (я завжди відчуваю, що полювання на помилок - це хороший спосіб знайти тих, хто стоїть в проекті) або де щось потрібно змінити / додали, що потрібно знати, де. Навіть якщо це добре інкапсульовано, вам все одно потрібно знайти його ... і якщо це означає щось замінити (нова реалізація IWhatsit), то вам потрібно знати, як використовувати альтернативну реалізацію. Знову ж таки, я не заперечую, що конструкція погана - занадто багато доказів протилежного - скоріше припускаючи, що деякі речі можуть бути менш очевидними.
Мерф

5

Я багато про це думав, хоча сам не дуже практикую TDD. Здається, існує (сильна?) Позитивна кореляція між якістю коду та наступним TDD.

1) Моє перше враження полягає в тому, що це (в першу чергу) не через те, що TDD додає "кращу якість" в код (як такий), це більше схоже на те, що TDD допомагає вилучити найгірші частини та звички, і так побічно підвищує якість.

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

2) Ще одна точка зору (це набуває філософського характеру) - це слідування психічним звичкам господаря. Ви не навчитесь бути господарем, дотримуючись його "зовнішніх звичок" (наприклад, довга борода - це добре), ви повинні навчитися його внутрішнім способам мислення, і це важко. І якимось чином змушуючи (початківців) програмістів слідувати TDD, вирівнювати свій спосіб мислення ближче до принципів майстра.


+1 Я думаю, ти це прибив, Маглоб. Мені особливо подобається ваше пояснення, що "TDD допомагає вилучити найгірші частини та звички, [...] опосередковано підвищуючи якість". І аналогія довгої бороди теж дуже хороша.
CesarGon

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

Маглоб, для любові до більш практичної сторони речей ти це найкраще висвітлюєш. @ Thorbjørn, я думаю, що Maglob більше рухався по лінії, що якщо ваш прогнозований дизайн смокче, ваші тести, безсумнівно, доведеться безпосередньо підтягувати до рівня примхливості, яку ви намагаєтеся здійснити, і гнилий запах її повинен переглядати ваші тести, перш ніж Ви навіть переходите до написання будь-якого фактичного коду.
Філіп Дупанович

3

Підхід "написати тест + рефактор до проходу" виглядає неймовірно антиінженерним.

Ви, мабуть, помилково уявляєте як рефакторинг, так і TDD.

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

Таким чином, ви не можете рефакторний код, поки він не пройде.

І TDD, зокрема тестування модулів (що я вважаю вдосконаленням ядра, оскільки інший тест здається мені досить правдоподібним), не стосується перепроектування компонента, поки він не працює. Йдеться про розробку компонента та роботу над реалізацією, поки компонент не працює так, як було задумано.

Також важливо дійсно зрозуміти, що тестування блоку стосується тестування одиниць . Через тенденцію завжди писати багато речей з нуля, важливо протестувати такі одиниці. Будівельний інженер вже знає характеристики підрозділів, які він використовує (різні матеріали), і може очікувати, що вони працюватимуть. Це дві речі, які часто не стосуються інженерів програмного забезпечення, і це дуже інженерно тестування блоків перед їх використанням, оскільки це означає використання перевірених високоякісних компонентів.
Якщо у будівельного інженера виникла ідея використати нову волоконну тканину для виготовлення даху для покриття стадіону, ви очікуєте, що він перевірить її як одиницю, тобто визначить необхідні характеристики (наприклад, вага, прохідність, стійкість тощо) і після цього випробуйте і вдосконаліть його, поки він не відповідає.

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

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

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

На відміну від цивільного будівництва, в інженерії програмного забезпечення проект зазвичай постійно розвивається. У цивільному будівництві у вас є вимога побудувати міст у положенні A, який може перевозити х тонн і досить широкий для n транспортних засобів на годину.
В інженерії програмного забезпечення клієнт може в основному вирішити в будь-який момент (можливо, після його завершення), що він хоче двоповерховий міст, і що він хоче, щоб він був пов'язаний з найближчою автострадою, і що він хотів би, щоб це був підйомний міст, тому що його компанія нещодавно почали використовувати вітрильні кораблі.
Інженерам програмного забезпечення доручено змінити дизайн. Не тому, що їх конструкції є недоліками, а тому, що це modus operandi. Якщо програмне забезпечення добре розроблене, воно може бути перероблено на високому рівні, не потребуючи перезапису всіх компонентів низького рівня.

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

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

TDD також включає тести, окрім одиничних тестів, які виконуються на системному рівні. Мені це легко пояснити, але важко виконати і важко виміряти. Також вони досить правдоподібні. Хоча я абсолютно бачу їхню необхідність, я не дуже ціную їх як ідеї.

Зрештою, жоден інструмент насправді не вирішує проблему. Інструменти лише полегшують вирішення проблеми. Ви можете запитати: Як долото допоможе мені чудовою архітектурою? Добре, якщо ви плануєте робити прямі стіни, прямі цегли допоможуть. І так, якщо ви дасте цей інструмент ідіоту, він, мабуть, зрештою його проступить через ногу, але це не вина долота, оскільки це не вада TDD, що вона дає помилкову безпеку новачкам, які не пишуть хороших тестів.
Таким чином, у нижньому рядку можна сказати, що TDD працює набагато краще, ніж жодна TDD.


Я не думаю, що маю помилкове уявлення; Я погоджуюся з визначенням рефакторингу коду, яке ви опублікували, але я також вважаю, що вам потрібно переглянути детальність змін у коді. Коли ви говорите "процес зміни вихідного коду комп'ютерної програми", вам потрібно усвідомити, що з точки зору певного цілого поведінка не змінюється, але поведінка частин дійсно змінюється. Так відбуваються зміни. Крім цього, я чую вас про те, чому працює TDD (і я їм ділюсь), але як архітектура вирішується відповідно до моєї оригінальної публікації?
CesarGon

@CesarGon: Публікація оновлена.
back2dos

2

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

Крім тестування бібліотек, які складають основу програмного забезпечення, пишіть тести, які охоплюють взаємодію ваших користувачів із програмним забезпеченням / веб-сайтом / будь-яким іншим. Вони надходять безпосередньо від користувачів, і такі бібліотеки, як огірок (http://cukes.info), можуть навіть дозволити вашим користувачам самостійно писати тести, природною мовою.

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

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


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

@CesarGon: Я думаю, що ваші конкретні питання стосуються будь-якого типу тестування, а не тільки TDD. Тому я просто зосередився на особливостях TDD, які «працюють».
sevenseacat

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

2

Я думаю, ви підходите до першої точки з неправильного кута.

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

На практиці це просто відверто означає: ми можемо перейти до наступного (після того, як ми успішно застосуємо TDD, щоб задовольнити всі предикати). Якщо ви підходите до TDD з цієї точки зору, то справа не в тому, щоб "писати тести + рефактор до здачі", а більше про те, щоб виконати це, я тепер повністю зосереджуюсь на наступній функції як найважливішому .

Подумайте, як це стосується цивільного будівництва. Ми будуємо стадіон, який може вмістити публічну аудиторію з 150000 людей. Після того, як ми довели, що структурна цілісність стадіону є надійною, ми спочатку задовольнили безпеку . Зараз ми можемо зосередитись на інших питаннях, які набувають негайно важливого значення, таких як туалети, тумби для їжі, крісла тощо ..., що робить досвід слухачів більш приємним. Це надмірне спрощення, оскільки TDD набагато більше, але суть полягає в тому, що ви не робите найкращого проклятого можливого користувальницького досвіду, якщо зосередитесь як на нових, так і на захоплюючих функціях та збереженні цілісності одночасно. Ви отримуєте це наполовину в обох випадках. Я маю на увазі, як ти можеш точно знати, якбагато туалетів і де вам розмістити 150000 людей? Я рідко бачив, як стадіони руйнуються в моєму житті, але мені довелося стільки разів чекати в черзі під час тайму. Це говорить про те, що проблема туалету, мабуть, є складнішою, і якщо інженери зможуть витратити менше часу на безпеку, вони, нарешті, зможуть вирішити питання туалету.

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


+1 за гарне пояснення мого першого пункту та посилання на Хенка Муді. Славний.
CesarGon

2
Дякую, я ціную це. Я розглядаю TDD більше як психологічні явища, а не технічний підхід / процес. Але це лише мій світогляд з цього приводу.
Філіп Дупанович

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

1

TDD в інженерії програмного забезпечення є хорошою практикою, так само, як обробка помилок у додатках є хорошою практикою, а також ведення журналів та діагностики (хоча це є частиною обробки помилок).

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

TDD - це лише спосіб формалізувати та автоматизувати ці кроки, щоб зробити вас як розробника більш продуктивним.

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

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

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


Я не згоден з вашим наслідком, що у фізичних (тобто непрограмних) системах легко відтворити збої. Подивіться на надзвичайно складну, важку роботу, яка необхідна для визначення першопричин механічних збоїв у авіакатастрофі, наприклад.
CesarGon

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

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

1

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


1
Чи є у вас якісь докази того, що помилки виявляються раніше в налаштуваннях TDD? А як щодо побічних ефектів TDD, таких як вплив на архітектуру?
CesarGon

0

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

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


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

@Bart van Ingen Schenau, ти зробив TDD? Я цим займаюся вже близько 4 років, і я точно бачив, що "чарівництво" відбувається.
Марсі

0

Я дам вам коротку відповідь. Зазвичай TDD дивиться не так, як тестування одиниць. Я ніколи не розумів одиничне тестування до недавнього часу після перегляду хорошого технічного відео. По суті TDD - це лише те, що ви хочете РОБОТИ наступні речі. ЇМ ОБОВ'ЯЗКОВО бути реалізованими. Тоді ви рештуєте програмне забезпечення так, як зазвичай.

Такого роду, як письмовий випадок використання бібліотеки перед розробкою бібліотеки. За винятком того, що ви можете змінити регістр використання в бібліотеці, а ви можете не для TDD (я використовую TDD для дизайну API). Вам також рекомендується додавати більше тесту і думати про дикі введення / використання тесту, який може отримати. Мені здається корисним при написанні бібліотек чи API, де, якщо щось змінити, ти повинен знати, що ти щось зламав. У більшості програмного забезпечення щодня я не турбуюсь, бо чому мені потрібен тестовий випадок для користувача, який натискає кнопку, або якщо я хочу прийняти список CSV або список з одним записом у рядку ... Це насправді не має значення, я дозволяю щоб змінити це, таким чином я не повинен / не можу використовувати TDD.


0

Програмне забезпечення є органічним, коли конструкція конструкцій конкретна.

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

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

Більшість проектів, які я бачив, використовують обмежені рамки (RhinoMocks, NSubstitute, Moq). Під час тестування з цими рамками ви повинні розробити додаток таким чином, щоб ви могли вводити та замінювати залежності під час виконання. Це означає, що ви повинні мати зв'язаний дизайн. Мало зв'язаний дизайн (якщо зроблено правильно) передбачає кращу роз'єднаність проблем, що є хорошою справою.

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

Зі сторони, я бачив програми, які справді перевірялися, але погано написані з точки зору об'єктно-орієнтованого дизайну.


0

Чому TDD працює?

Це не так.

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.