Чи реально використовуються одиничні тести як документація?


22

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

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

Отже, питання: коли в якості документації використовуються одиничні тести? Коли коментарі не охоплюють усе? За розробниками, що розширюють джерело? І що вони викривають, що може бути корисним та актуальним, що сама документація не може викрити?


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

10
Коментарі можуть бути неправильними.

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

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

4
Тести блоку @Ant викликають реальний код і документують очікувану відповідь і порівнюють його з фактичною відповіддю. Правильний чи ні посилається код - не сенс - тестує документи, як його викликати.

Відповіді:


17

Вони НЕ АБСОЛЮТНІ довідкові документи

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

Отже, зрештою, найкращий спосіб зрозуміти код - це читати робочий код .

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

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

АЛЕ вони ВІДПОВІДАЮТЬ ДОПОМОГУ Доповнення документації

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

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

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

Регресії та помилки потребують занадто тестів

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

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


Чи можу я запитати, чому мене зняли з посади? Які тики ти там чи з чим ти не згоден?
haylem

2
Найкраща частина вашого аргументу (IMO) написана найменшим шрифтом - найкращий спосіб зрозуміти код - це мати в першу чергу читабельний код. Я змінив би це на "читабельний та робочий код", але я згоден. Тоді якщо ви ще раз подивитесь на одиничні тести - запущені тести працюють кодом (і, як і весь код, слід читати), тож це насправді досить гарна (якщо часто занадто локальна) документація, коли вона зроблена добре.
Joris Timmermans

@MadKeithV: спасибі Я оновив для "читабельного та робочого коду" і підштовхнув це трохи вище.
хайлем

11

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

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


5

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

Вони замінюють документацію? Ні.

Чи є вони корисним доповненням до документації? Так.


4

Я бачу одиничні тести як:

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

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


3

Я відповім на ваше запитання, запитуючи вас у іншого.

Як часто під час роботи з новим API / рутином ви запускаєте допомогу шукати приклад коду того, що ви намагаєтеся використовувати? Якщо вам не вдалося перейти на Google для пошуку в Інтернеті зразків коду?

Саме тоді ви б використовували одиничні тести як документацію.

  • Насправді одиничні тести можуть бути трохи більш жорсткими, ніж звичайні приклади коду, оскільки у вас повинно бути кілька тестів (прикладів).
  • Сподіваємось, ваші тестові одиниці ілюструють правильне використання. Наприклад, вони чітко показують усі основні залежності, як через звичайні об'єкти, так і знущаються над об'єктами. (Інакше вони не особливо хороші одиничні тести.)
  • ПРИМІТКА. Якщо ваші коментарі або "звичайна документація" містять приклади коду, ви фактично порушуєте принципи DRY. І ці приклади коду можуть з часом легко стати неправильними , тоді як при регулярно виконаних одиничних тестах шанси на це значно менші.
  • Якщо одиничні тести є ретельними (зазвичай великими, якщо ), то вони повинні надати додаткову інформацію:
    • Усі відомі крайові випадки чітко проілюстровані.
    • Усі очікувані винятки, які можна кинути.
    • Усі помилки, які раніше були знайдені (це, мабуть, корисніше при розширенні тестового блоку, ніж при написанні нового клієнта для пристрою).
    • Усі основні бізнес-правила, пов'язані з підрозділом. (якщо хто-небудь)

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

  • Я б ризикну припустити, що часто самі тести недостатньо добре написані для цієї мети. Інші відповіді вже натякали на тести, які є:
    • Неповний.
    • Заплутаний. (Я бачив тестові випадки, які не викликають безпосередньо тестований метод - ви заглиблюєтесь на 3/4 рівня вглиб стека викликів, перш ніж він викликається, і передумови виклику методу розкидані в різних місцях складної ієрархії класів. )
    • Застаріла. (зазвичай тести повинні виходити з ладу, коли вони застаріли, але це не завжди так).
  • Зазвичай існує безліч прикладів використання, які вже є у виробничому коді, коли виникає потреба у прикладі.
  • Тестова одиниця настільки добре написана (самодокументування), що методи не потребують прикладів. Бажаю!
  • З мого досвіду як програміста, ми, як правило, дуже прагнемо стрибнути в глибокий кінець і RTFM наступного вівторка ...
  • Документація та коментарі, що порушують принцип DRY.

2

Тести TL; DR Unit та коментарі API є додатковими - деякі речі найкраще описані в коді, а інші - у прозовій формі.

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

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

Приклад: у вас є метод m, (a, b)який виконує певний обчислення. Зважаючи на вимоги щодо сумісності з зворотною стороною, вона повинна вводити спеціальні регістри a=0та a=-1, але тільки якщо bNULL. Помітити це в коментар є складним, багатослівним і, ймовірно, може стати несвіжим, якщо вимога пізніше буде знята.

Якщо ви зробите кілька тестів, які перевіряють поведінку m(0, NULL), m(-1, x)ви отримуєте кілька переваг:

  • Опис правильної поведінки зрозумілий, непорозуміння зменшуються
  • Люди не можуть оминути вимогу під час зміни коду, на відміну від коментаря

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

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