Як кардинально покращити охоплення коду?


21

Мені доручено отримати застарілу заявку під тест одиниці. Спочатку кілька відомостей про програму: це 600-кодова база LOC Java RCP з цими основними проблемами

  • масове дублювання коду
  • немає інкапсуляції, більшість приватних даних доступні ззовні, деякі бізнес-дані також робляться одинаковими, тому вони не тільки змінюються ззовні, але і звідусіль.
  • немає абстракцій (наприклад, немає бізнес-моделі, бізнес-дані зберігаються в Object [] та подвійні [] []), так що немає OO.

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

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


Чому б не створити тести регресії автоматично та не перевірити кожен окремо? Має бути швидше, ніж писати їх уручну.
Роберт Харві

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

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

1
@dodgy_coder Майкл С. Пір'я, автор роботи "Ефективно працює з кодом Legacy", визначає код Legacy як "код без тестів". Він служить корисним визначенням.
StuperUser

Відповіді:


10

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

  1. Код, який легко перевірити і крихкий
  2. Код, який легко перевірити і стабільний
  3. Код, який важко перевірити і крихкий
  4. Код, який важко перевірити і стабільний

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


Відмінно. У мене є ідея, як визначити, чи легко це перевірити статичним аналізом, наприклад, кількість залежностей / Провідник заповідальності. Але як я міг визначити, чи є код крихким? Я не можу зіставити дефекти з конкретними одиницями (наприклад, класами), і якщо це число 3, звичайно (богові класи / синглтони). То, може, кількість реєстрацій (гарячих точок)?
Пітер Кофлер

1
@ Петер Кофлер: введення гарячих точок - хороша ідея, але найціннішим джерелом такого роду знань були б розробники, які працювали з кодом.
Майкл Боргвардт

1
@Peter - як сказав Майкл, розробники, які працювали з кодом. Кожен, хто працював з великою базою кодів протягом досить тривалого часу, буде знати, які частини його запаху. Або, якщо вся справа пахне, які її частини справді хизуються .
Carson63000

15

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

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

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

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

Реалістичною метою є "Оскільки ми реалізували UT, дефекти вставлення в тестовані модулі впали до x% тих, що не знаходяться під UT" (в ідеалі x - число <100).


+1, ви не можете випробувати тестувати щось ефективно без більш міцного стандарту, ніж код.
dan_waterworth

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

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

2

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

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

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

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

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


1

Один із способів поліпшити охоплення - написати більше тестів.

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

Уявіть, що у вас є 3 кодові блоки, a, b і b ', де b' - це дублікат (точна або майже пропущена копія) B, і ви маєте покриття на a і b, але не b 'з тестом T.

Якщо рефакторинг бази коду для усунення b 'шляхом вилучення спільності з b і b' як B, база коду тепер виглядає як a, b0, B, b'0, при цьому b0 містить нерозподілений код з b'0 і vice- навпаки, і b0, і b'0 значно менші за B, і викликають / використовують B.

Тепер функціональність програми не змінилася, і тест T не має, тому ми можемо знову запустити T і очікувати, що він пройде. Зараз охоплений код - a, b0 та B, але не b'0. База коду стала меншою (b'0 менше b '!), І ми все ще охоплюємо те, що ми спочатку охоплювали. Наш коефіцієнт покриття збільшився.

Для цього вам потрібно знайти b, b 'та ​​в ідеалі B, щоб увімкнути рефакторинг. Наш інструмент CloneDR може це зробити для багатьох мов, особливо включаючи Java. Ви кажете, що у вашій кодовій базі багато дублюється коду; це може бути хорошим способом вирішити це на вашу користь.

Як не дивно, акт знаходження b і b 'часто збільшує ваш словниковий запас про абстрактні ідеї, які реалізує програма. Хоча інструмент не має уявлення про те, що роблять b і b ', сам акт їх ізоляції від коду, що дозволяє просто зосередитись на вмісті b і b', часто дає програмістам дуже гарне уявлення про те, що абстракція B_ab Абстрагує клонований код . Тож це також покращує ваше розуміння коду. Переконайтесь, що ви даєте хороше ім’я B, коли ви відмовляєтесь від нього, і ви отримаєте кращі тестові покриття та більш рентабельну програму.

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