Чи корисно написати всі можливі тестові випадки після перетворення команди на TDD для досягнення повного покриття?


17

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

Тепер, коли всі терміни минули і все спокійно, всі погодилися перетворити нас на продуктивну команду, засновану на TDD / BDD ... Так!

Тепер питання щодо коду, який у нас уже є: (1) Чи все-таки добре, чи гарна ідея зупинити більшу частину розробки та почати писати цілі можливі тестові випадки з самого початку, хоча все працює повністю ОКЕЙ (поки!) ? Або (2) краще дочекатися, коли трапиться щось погане, а потім під час виправлення написати нові тести одиниці, або (3) навіть забути про попередні коди та просто написати одиничні тести лише для нових кодів і відкласти все на наступний великий рефактор.

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

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



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

1
@gnat Я думаю, що це не повторне питання. Згадана команда не має жодних тестів (навіть інтеграційних тестів)
Мішель Гокан,

1
@gnat питання: що буде з нашими новими тестовими одиницями? Вони можуть здатися неповними або навіть марними без написання всіх одиниць тестів для раніше написаних кодів. Питання, яке ви згадуєте, не охоплює цієї конкретної проблеми.
Мішель Гокан

1
Неможливо написати всі можливі тестові випадки. Це тільки корисно , щоб написати все тест випадки ви дбаєте о. Наприклад, якщо вам потрібна функція, яка приймає intзначення і повертає щось конкретне, неможливо написати одиничний тест для кожного можливого intзначення, але, мабуть, має сенс перевірити кілька корисних значень, які можуть збільшити значення код, наприклад, від'ємні числа (включаючи minint), нуль maxintтощо, щоб переконатися, що деякі крайові регістри охоплені.
Крістофер Шульц

Відповіді:


36

Не було жодного тестового процесу розробки під час розробки через дуже жорсткі терміни

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

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

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

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

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

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

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

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

Чи є гарною ідеєю написати всі можливі тестові випадки після перетворення команди на TDD?

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

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

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

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

(2) краще почекати, коли трапиться щось погане, а потім під час виправлення написати нові тести одиниці, або

(3) навіть забути про попередні коди та просто написати одиничні тести лише для нових кодів і відкласти все на наступний великий рефактор.

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

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

Майкл Пірс подарував нам книгу про це: Ефективна робота зі спадковим кодексом . Прочитайте, і ви побачите, що вам не потрібно спалювати все старе, щоб зробити щось нове.


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

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

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

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

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

22

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

Враховуючи застарілий 1 код, пишіть одиничні тести в таких ситуаціях:

  • при виправленні помилок
  • при рефакторингу
  • при додаванні нової функціональності до наявного коду

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

1 Спадковий код - це код без одиничних тестів. Це визначення TDD застарілого коду. Він застосовується, навіть якщо застарілий код щойно доставлений [навіть якщо чорнило ще не висохло].


Але тоді наші нові тестові одиниці на нові функції можуть здатися неповними або навіть марними без пропущених одиничних тестів. Чи не так?
Мішель Гокан

7
(1) Не варті? Звичайно, ні. Як мінімум, вони тестують нову функцію. Наступного разу, коли хтось захоче змінити цю функцію, вони повторно використовуватимуть більшість існуючих тестів. (2) Неповний? Можливо, може й ні. Якщо ви також створите одиничні тести, які перевіряють застарілу функціональність, від якої залежить нова функція, тести можуть бути достатньо повною для практичних цілей. Іншими словами, створюйте додаткові тестові одиниці, які проникають у застарілі функції. Проникнути на яку глибину? Це залежить від архітектури програми, наявних ресурсів, інституційної підтримки.
Нік Алексєєв

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

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

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

12

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

  • більш ніж 30% покриття (він же пару тестів на інтеграцію): якщо ваші тести виходять з ладу, щось надзвичайно зламане (або ваші тести лускаті). На щастя, тести вас оповістили швидко! Але випуски все ж потребуватимуть широкого ручного тестування.
  • понад 90% покриття (інакше більшість компонентів мають поверхневі тестові одиниці): якщо ваші тести пройдуть, програмне забезпечення, швидше за все, добре. Неперевірені частини - це крайні справи, що добре для некритичного програмного забезпечення. Але випуски все ж потребуватимуть певного ручного тестування.
  • дуже високе охоплення функцій / заяв / гілок / вимог: ви живете мрією TDD / BDD , а ваші тести - це точне відображення функціональності вашого програмного забезпечення. Ви можете рефакторировать з високою впевненістю, включаючи масштабні архітектурні зміни. Якщо тести пройдуть, ваше програмне забезпечення майже готове до випуску; потрібні лише деякі ручні тестування диму.

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

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

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

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

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


"покриття більш ніж на 90% (інакше більшість компонентів мають поверхневі тестові одиниці): якщо ваші тести пройдуть, програмне забезпечення, ймовірно, здебільшого добре. Неперевірені частини - це крайні випадки, що добре для некритичного програмного забезпечення ." Мені це звучить трохи, FWIW, я вважаю за краще мати 30% покриття, що складається з переважно крайових випадків, ніж 90% покриття, що складається повністю з очікуваної поведінки шляху (що легко зробити тестувальникам вручну); Я рекомендую думати "поза коробкою", коли пишуть тести і грунтують їх на (незвичних) тестових випадках, виявлених вручну, коли це можливо.
jrh

5

Не пишіть тести на існуючий код. Це не варто.

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

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

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

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

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

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

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


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

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

2

Тест - це засіб для взаєморозуміння.

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

Ви можете зрозуміти, що має бути правдою лише тоді, коли працюєте з ним.

Тому пишіть лише тести на код, з яким ви працюєте.

Працюючи з кодом, ви дізнаєтесь.

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

Промийте і повторіть.

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

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

Два варіанти:

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

0

(1) Чи все-таки добре, чи гарна ідея зупинити більшу частину розробки та почати писати цілі можливі тестові приклади з самого початку, хоча все працює повністю ОКАЙ (поки що!)?
(2) краще дочекатися, коли трапиться щось погане, а потім під час виправлення написати нові тестові одиниці

Однією з головних цілей тестів є гарантувати, що зміна нічого не порушила. Це триетапний процес:

  1. Підтвердьте, що тести успішні
  2. Внесіть зміни
  3. Підтвердьте, що тести все-таки успішні

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

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

незважаючи на те, що все працює повністю ОКЕЙ (поки!)?

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

(3) навіть забути про попередні коди і просто написати одиничні тести лише для нових кодів і відкласти все на наступний великий рефактор

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

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

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

і відкласти все на наступний великий рефактор

Якщо наступним головним рефактором є заданий, то вам справді потрібно написати тести.

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


0

Мої два центи:

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

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

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

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

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