Якість коду в одиничних тестах?


23

Чи пишуть одиничні тести, чи варто витрачати додатковий час, щоб код мав хорошу якість та читабельність?

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


5
Читання та ремонтопридатність повинні бути основним напрямком тестування одиниць.
Е.Л. Юсубов

2
Тести теж кодові!
Грант Пейлін

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

Відповіді:


11

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

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

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

  • Якщо ваші тести порушують закон Demeter у розділах Assert (тобто ви перевіряєте значення чогось, що глибоко вкладено в графіку залежностей досліджуваного об'єкта), можливо, це справді інтеграційні тести, а не одиничні тести. Іншими словами, якщо в TestA ви стверджуєте, що ABCD щось дорівнює, можливо, ви насправді намагаєтеся перевірити D і A, а не просто A.

До речі, коли ти кажеш

Я дуже часто порушую Закон Деметера, щоб швидше писати та не використовувати стільки змінних.

ви повинні знати, що писати

var grab = myDependency.Grab;
var something = grab.Something;
var very = something.Very;

very.Deep();

насправді не краща Деметра, ніж розумна

myDependency.Grab.Something.Very.Deep();

якщо це ви мали на увазі.


47

Зовсім варто витрачати час на написання якісного коду для одиничних тестів:

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

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


22

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

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

  • Одиничні тести теж можуть бути помилковими. І помилки видніші, коли код добре записаний.

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

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


12

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

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


1

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

Це означає:

  • Витяг побудови тестових даних у класи будівельників.
  • Витягнути множинні твердження в окремі методи твердження.
  • Будьте дуже точні у своїй назві. Assert.That(x4, Is.EqualTo(y16*2*SOME_VALUE), ASS_ERR_TXT_56)робить дуже мало сенсу для більшості читачів.

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


1

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

Зробіть будь-яке з цих дій у своїх тестах:

  • Дублікат коду
  • Зниження читабельності
  • Щільна муфта
  • Тимчасове сполучення
  • Висока цикломатична складність (велика кількість залежностей)

А ви вже багато роботи, коли потрібні зміни.

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


0

Це залежить від того, є ці одиничні тести "тимчасовими" чи ні. Якщо

  1. Тест буде часто використовуватися;

  2. Розробники повинні працювати з одиничними тестами, написаними іншими розробниками;

  3. Більшість тестувань проводиться одиничними тестами

то тести повинні бути написані належним чином. У випадку, якщо в самому тесті є помилка, буде важко знайти помилку та виправити її, особливо якщо минуло певний час з моменту написання тесту.

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


(1) одиничні тести ніколи не є тимчасовими (2) навіть якщо вони є вашими власними силами, за один місяць (або більше) ви не запам’ятаєте всі деталі, тому важливо зробити це правильно - навіть для себе
BЈовић
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.