Чи реально виграла розробка тестових проектів (TDD)?


36

Я не новачок у кодуванні. Я кодую (серйозно) вже понад 15 років. У мене завжди було тестування свого коду. Однак протягом останніх кількох місяців я вивчав тестування та розробку проектів (TDD), використовуючи Ruby on Rails . Поки що користі я не бачу.

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

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

Читаючи наявну літературу, я зауважую, що TDD, здається, є величезним часом занурення вперед, але в кінцевому підсумку окупається. Мені просто цікаво, чи є приклади реального світу? Чи справді це масове розчарування окупається в реальному світі?

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

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


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


3
butunclebob.com/ArticleS.UncleBob.JustTenMinutesWithoutAtest Ось історія дядька Боба про реальну ситуацію в світі.
Хакан Деріал

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

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

Відповіді:


26

Цей документ демонструє, що TDD додає 15-35% часу розробки взамін зменшення щільності дефектів на 40-90% для проектів, подібних до подібних.

У статті йдеться про повний документ (pdf) - Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat та Laurie Williams. «Усвідомлення покращення якості завдяки тестовій розробці: результати та досвід чотирьох промислових команд». ESE 2008 .

АнотаціяТестова розробка (TDD) - це практика розробки програмного забезпечення, що використовується епізодично десятиліттями. З цією практикою інженер-програміст цикла хвилину за хвилиною між написанням невдалих тестових одиниць і написанням коду впровадження для проходження цих тестів. Нещодавно розробка Testdriven постала як важлива уможливлення практичних методологій розробки програмного забезпечення. Однак мало емпіричних доказів підтверджує або спростовує корисність цієї практики в промисловому контексті. Тематичні дослідження проводилися з трьома командами розробників у Microsoft та однією в IBM, які прийняли TDD. Результати тематичних досліджень показують, що щільність дефектів перед випуском чотирьох продуктів знизилася між 40% і 90% щодо аналогічних проектів, які не застосовували практику TDD. Суб'єктивно,

Повний документ також коротко підсумовує відповідні емпіричні дослідження щодо TDD та їх результатів на високому рівні (розділ 3 Суміжні праці ), включаючи Джорджа та Вільямса 2003, Мюллера та Хагнера (2002), Ердогмуса та ін. (2005), Мюллер і Тічі (2001), Янцен і Сейдіан (2006).


2
На дискусію про Meta.StackOverflow ви можете додати додаткову інформацію з паперу, яка може бути актуальною для запитувача , а також майбутніх людей, які знайдуть це питання?
Томас Оуенс

2
@ThomasOwens, я вважав, що висновок ("TDD додає 15-35% часу розробки натомість зменшення щільності дефектів на 40-90%") був додатковою інформацією, яка відповідає на початкове запитання <_ <

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

99% всієї статистики є вигаданими. : P Але насправді мова йде про контекст. Про яку команду? Велика зграя посередніх Java-розробників? Так, я вважаю, що TDD допоможе їм підвищити продуктивність. Але це не означає, що архітектурні навички проектувати та цінувати надійний код в першу чергу не допоможуть їм ще більше, і IMO, тестовий перший TDD може дуже легко завадити їм коли-небудь навчитися робити це правильно. І так, я чув, що це допомагає в дизайні. Певною мірою це, мабуть, правда, але це все ще невпізнання та смуга допомоги для кореневої проблеми ІМО.
Ерік Реппен

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

16

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

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

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

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

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

Але моя поточна ефективність роботи TDD походить від поєднання як оволодіння способом написання одиничних тестів, так і оволодіння технологією, в якій реалізована система (у цьому випадку C #).

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

Але наскільки добре він працює на реальних проектах?

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

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

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

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


9

Ми отримали велику користь.

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

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

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

Більшість нашої системи шлюзу платежів було написано за допомогою TDD. Деякі аспекти були досить важкими для перевірки, тому ми вирішили вирізати кути, пожертвувавши деяким покриттям коду. Ми повернемося і вирішимо ці питання врешті-решт.

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

Довідка Visa PCI: http://usa.visa.com/merchants/risk_management/cisp_merchants.html


3
"Ми повернемося і вирішимо ці питання врешті-решт." - Мабуть, ні ... хіба що, якщо вони суки ляпнуть вас якось жахливим клопом. Ці області стануть основою для всього іншого і будуть спрямовувати весь дизайн рухатися вперед, тому що ніхто не захоче вкладати ресурси, щоб переробити їх, і ніхто не захоче примушувати будь-які зміни, які можуть зробити щось погане. Відбувається щоразу: P
Едвард Странд

Ви здогадуєтесь, коли я розповідаю, що відбувається в компанії. Коли ми здійснюємо, ми можемо ввести код з покриттям коду на 70%. Це постійно збільшується за рахунок СІ. Протягом місяців мінімальний поріг покриття коду буде збільшений на невеликий відсоток. Після цього вибору не залишиться, але ввести ще тести.
CodeART

7

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

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

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

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

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


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

6

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

Іншими словами, TDD допомагає в розробці вашого API.

На мій досвід, це призводить до кращих API, що в свою чергу дає кращий код.


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

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

Тестові приклади - це запущені версії специфікації і дозволяють вам дуже, дуже легко бачити, як викликати API. Це, мабуть, єдина найбільш корисна форма "ЯК" -документації, яку я бачив досі (порівняйте з "ЧОМУ" -документацією, як JavaDoc), наскільки ви впевнені, що це правильно (інакше тест не вдасться).

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


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

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

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

@delnan "Я смію знищити" - цікавий вибір слів. Чи впала редакція на ваш смак?

Так, я зняв свій потік зараз, коли помітив це.

5

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

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

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

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

У своєму запитанні ви сказали наступне:

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

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

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

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

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

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

TL: DR - Так, вони є реальною допомогою у світі, але вони є інвестицією. Переваги стають очевидними лише пізніше.


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

На жаль, ні, тому що ніхто інший, здається, не будує одиничні тести, принаймні, не на будь-якому коді, який я успадкував від попередніх розробників. Моє життя було б набагато простішим, якби вони були. Я б запропонував вам переглянути книгу за посиланням, де є приклади реального світу, хоча це для PHP, а не Rails. amazon.com/…
GordonM

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

4

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

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

  • QA повідомляє про набагато менше помилок, тому ми економимо кошти на ремонт нашого коду після випуску. Це тому, що TDD не дозволяє писати код без тесту, тому покриття коду набагато краще.

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

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

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

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


Якість безкоштовна!
MathAttack

2
Погана якість дорога!
Вольфганг

3

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


2

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

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

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

Прикладом цього пізнього біта є проект, над яким я зараз працюю, де ведучий раптом вирішив ВСІМО переписати протокол зв’язку, який він використовував з майже 0 причин. Я зміг відповісти на цю зміну за 2 години, оскільки я відключив цю проблему від усього іншого і міг працювати над нею повністю незалежно до останнього зв'язку та інтегрувати крок тестування. Більшість моїх колег, напевно, були б на цьому день і більше, тому що їх код не був би відокремлений, і вони змінювали б тут, там, скрізь ... компілювали все це ... інтеграційне тестування ... повторити, повторити ... Це займає набагато довше цього шляху і ніде не є таким стабільним.


2

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

Більше того, цілий модуль був завершений від початку до кінця, пройшовши виробництво, не демонструючи жодної помилки (і це теж критичний модуль). Її розробка тим самим була швидшою, ніж зазвичай, тому що зазвичай інакше буде те, що модуль буде "завершений", лише повернувшись 4-5 разів з бета-тестування на виправлення помилок. Це було суттєвим поліпшенням, і розробники були задоволені також новим процесом.

Я не робив багато Rails TDD, але я багато зробив у C ++, C #, Java та Python. Я можу вам сказати, що це безумовно працює. Я гадаю, що ви витрачаєте багато часу на роздуми над іменами тестів, тому що ви недостатньо впевнені. Спершу напишіть свій тест, але нехай ваша творчість протікає ...

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

Час для чайових

Порада №1

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

Порада №2

Почніть нові тести класу простим тестом "canCreate", просто налаштуйте свій розум у правильному напрямку, як у "Добре, я зараз працюю над цим класом ... правильно".

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

І пам’ятайте

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

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


1

Нетривіальний приклад реального світу:

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


-1

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

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

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

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

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

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

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

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

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


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

1
Він відповідає, але оскільки ви не поділяєте мою думку, ви даєте -1 до нього :) В основному той, хто не намагатиметься показати значення TDD, збирається дати небажану відповідь з вашої точки зору;) Дозвольте мені здогадатися . Ти євангелізатор TDD, правда? :) До речі, справжнє питання автора - чи окупається TDD чи ні. Щоб відповісти на це, вам не потрібно практикувати TDD. Чи окупається Fortran за написання веб-додатків? Ви пробували, перш ніж відповісти?
rosenfeld

Я не маю думки щодо TDD, і я не використовую голоси як подобається / не подобається (це сайт запитань і відповідей, а не Facebook). На мій прочитання ця "відповідь" просто не стосується заданого питання ні позитивно, ні негативно
gnat

З моєї точки зору, це не технічне питання, наприклад "як мені зробити X з nginx?". Є правильні відповіді на подібні запитання, але не на якісні та суб’єктивні питання, як це, коли автор насправді хоче знати думки інших щодо TDD та чи варто це. Це була моя спроба показати свою точку зору. Я поняття не маю, як відповідь могла бути правильною, оскільки всі вони мені здаються особистою думкою. Ви не можете ефективно виміряти, чи вартує TDD чи ні. Будь-які статті, які намагаються зробити це, принципово неправильні.
rosenfeld

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