DevUA

Meta


Про юніттести і функціональні тести

Evgen KovalEvgen Koval

Цей пост – вирізаний фрагмент дискусії зі Скайп-чату, що стосується дизайну софта. Всі учасники – люди з чималим досвідом.

Є таке питання. Є джанго-аплікейшн, який являє собою… РЕСТ-апішку.  Для чого потрібні юніттести на моделі, якщо можна зробити наскрізний функціональний тест?

Аргументація:
1. Для нас важливо чи працює АРІ, а не якісь внутрішні речі типу моделей.
2. Моделі в нас не реюзаються (поки).

Хочеться вашої думки за якийсь (або свій) варіант з аргументацією.
[11:20:38] Kostya: в моделях зовсім нема логіки?
[11:21:17] Wanderer: є повно логіки. Вся логіка там.

приклад:

є модель  User, в неї метод регістер, який “реєструє” юзера ще в 1 моделі (наприклад).  Можна тестувати це так: POST /users/, далі все перевірити.  Можна писати тести на модель і метод.
[11:22:42] Yuriy S.: окремі тести на апі і модель будуть менші, значить їх буде легше ментейнити. Також окремі тести на апішку будуть швидше працювати, бо все замокано. Для таких тестів не треба фікстур ніяких.
[11:23:25] Wanderer:
аргумент №1 – швидкість
аргумент №2 – розділення (інкапсуляція?)
?
[11:23:40] Yuriy S.: Десь так. Краще покриття тестами. Бо чи меньшу частину функціоналу охоплює тест, тим легше його написати правильно. Спробуй кількома великими тестами покрити апішку і модель зразу. Швидше за все ти протестуєш кілька основних випадків і все.
[11:25:23] Andrew Ko: http://henrikwarne.com/2014/09/04/a-response-to-why-most-unit-testing-is-waste/. Півроку тому був нехілий хайп в інтернеті про юзлесс юніт тестс.
[11:26:14] Wanderer: до чого прийшла організована програмістична спільнота?
[11:26:45] Andrew Ko:

почитай цю статтю: http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html
А оце сама перша стаття (автор – автор рубі он рейлс)

[11:29:12] Wanderer: на перший погляд перша стаття згідна з Юрою (і мною):

Well-tested parts.
Decoupled design.
Rapid feedback.
[11:29:21] Wanderer: але не дочитав ще
[11:29:22] Andrew Ko: Вона більше про тдд але суть в тому шо юніттестити треба тілки дуже специфічні штуки. Алгоритми тощо. А все решта – функціональними.
[11:29:49] Wanderer: Ти згідний?
[11:30:08] Andrew Ko: По великому рахунку – так. Але це відправляє в смітник тдд. І хрєн з ним
[11:32:10] Wanderer: тдд і тести різні речі.
І це лише думка 🙂 Як на мене то тдд це цікава практика
[11:33:33] Andrew Ko: А я хіба сказав шо це одні і ті самі речі? я сказав шо тдд це написання юніттестів в першу чергу. якшо не писати юніттести на все то тдд іде лєсом.
[11:33:34] Wanderer: Слухайте, може це кьюа-лоббі? 🙂
[11:33:47] Wanderer: їх почали заміняти тестами і тут змова 🙂
[11:34:32] Andrew Ko: > І це лише думка

це думка мартіна фавлєра, дхх. Тобто крутих пєрців проти думки яких моя думка ніщо.
[11:34:59] Wanderer: Я розумію, але 10 років тому його думка була та ж сама? А якою вона буде завтра? Доктрина міняється з часом.
[11:35:28] Andrew Ko: якби думка не мінялася ми б досі писали на асемблері або в машинних кодах.
[11:35:47] Wanderer: думка щодо корисності оод не міняється вже давно. Кити стоять принаймні. Тести прийшли досить недавно, і цю галузь поки штормить.
[11:36:47] Andrew Ko: what?
[11:37:38] Wanderer: В мене є думка, якої я не можу позбутись. Чи не порушує такий принцип стандартний підхід знизу вгору – побудови з блоків? Користуючись цією логікою можна не писати ніяких класів (не в тестах) і забити на всі принципи типу солід. На бізнес вимоги це не впливає жодним чином. Ні? Тобто заперечення юніттестів легко апроксимувати на сам код.
[11:39:11] Andrew Ko: Бізнесу пофіг шо там в тебе в середині солід не солід.
[11:39:26] Wanderer: Ось. тоді не лише юніттести, але і все ООП в топку. З усіма дизайнами.
[11:40:06] Andrew Ko: Бізнесу по барабану ооп в тебе там всередині чи код на бейсіку. Головне щоб система хавала інпут і випльовувала аутпут весь час коректно.
[11:40:23] Wanderer: і люди придумали оод щоб…
[11:41:06] Andrew Ko: ООП придумали не люди, а програмісти. Щоб їм легше було програмити. Щоб не путатися в пейдждаунах іф елсе.
[11:41:42] Wanderer: А юніттести вони придумали щоб… знати чи правильно попрограмили? Принцип інкапсуляції. Я пишу клас за спекою, віддаю. Хто і як його юзає – побоку. Хіба відсутність юніттестів це не порушує?
[11:42:21] Andrew Ko: а юніт тести вони придумали шоб було потім легше шашкою в коді махати
[11:42:40] Wanderer: Вот. І тоді Мартін Фаулер що… неправий? Або його не так зрозуміли?
[11:42:55] Andrew Ko: А, ну якшо зводити софтвер девелопмент до написання класів… Тобто якшо вважати класи кінцевим продуктом, а не побічним артефактом.
[11:45:24] Wanderer: Класи – засіб боротьби зі складністю. Суть їх – розбиття на незалежні блоки і побудова продукту знизу вгору (канон програмування).
Тести на класи – боротьба за помилками в цих незалежних блоках і інструмент для підтримки їх правильності і відповідності вимогам.
Мені здається, що вищезгадана анафема юніттестам це порушує.
[11:46:09] Andrew Ko: Бізнес не цікавить складні в тебе класи, солід вони чи ні. Якшо в тебе є анлім грошей і часу – пиши юніт тести на кожен чіх.
[11:46:48] Wanderer: мене як користувача не цікавить що в тв є транзистори. І що це означає, що їх не має там бути?
[11:47:00] Andrew Ko: Якшо в тебе бюджет розумний то (бізнесу) достатньо коли затестована зовнішня поведінка. Компроміс.
[11:47:09] Wanderer: Це означає що будувати ТВ інженери можуть як їм краще. Цікаво щоб високошановні присутні висловились, дві точки зору ніби є. Навіть три. А з Мартином – чотири.
[11:48:52] Andrew Ko: On 1/14/15, at 11:46 AM, Wanderer wrote:

мене як користувача не цікавить що в тв є транзистори. І що це означає, що їх не має там бути?

так. там можуть бути лампи, транзистори, мікросхеми, волшебний мох. Споживачам телевізорів байдуже.
[11:49:07] Wanderer: ключове слово можуть
[11:49:26] Andrew Ko: Ні, ключове – споживачам байдуже.
[11:49:38] Wanderer: Я не заперечую транзистори. Мені просто байдуже. Ми говоримо про те як інженерам краще робити ТВ (писати код рест арі). Ми ж інженери, тобто думаємо про побудову.
[11:55:19] Andrew Ko: http://blog.stevensanderson.com/wp-content/uploads/2009/11/image.png
[11:57:22] Wanderer: чому  люди так люблять чорно-білу палітру і едж-кейси 🙂 Певно тяжіють до бінарного мислення.
Я не маю на увазі тебе, Ендрю, це загальне спостереження.
Мене не цікавить ні low ні high. Більшість коду всередині. Все як в житті.
[11:59:35] Andrew Ko: а ти там бачиш тільки чотири квадратика і всьо? 🙂
[12:00:03] Wanderer: low && high. Де average? Півтонів нема.
[12:02:52] Kostya: по-моєму з юніт-тестами головне не страждати фанатизмом, створюючи їх на кожну дрібницю. Покриваючи ними основний функціонал і edge case-и можна витрачати не так багато часу, і при розробці зручно. Бо часто їх пишуть більше, ніж треба, і потім виявляється що велика частина із них нічого не тестує, або тестує одне й те саме по багато разів.
[12:04:27] Yuriy S.: спостереження з власного досвіду – нормально покрити апішку функціональними тестами дуже тяжко – постійно вилазять якісь проблеми, але це легко вирішується написанням юніттестів, які, як не дивно, пишуться трохи легше за функціональні, а працюють набагато швидше.
[12:06:08] Wanderer: мейкс сенс ту мі. Типу якщо тестів на колеса нема, а на машину є. Видає: помилка – не їде (колесо не крутиться). Розібрали – колесо квадратне.
Юніттест зловив би це швидше…
[12:14:04] Andrew Ko: Питання тільки в тому, що написати юніттест на машину швидше/дешевше чим на кожну гаєчку в автомобілі. Відповідно юніттести мали би бути на важливі агрегати (якшо ти будуєш не космічний корабель вартістю мільяри доларів). Що власне та діаграма (на мою думку) і відображає.
[12:17:14] Wanderer: Діаграма каже: тести на гайки не дуже потрібні, тести на колеса – в 100 разів потрібніші, тести на двигуни – в 1.000.000 разів потрібніші. Тому і претензія до бінарності картинки.
[12:18:28] Andrew Ko: Ти сам собі суперечиш. Ти назвав 3 значення потрібності. Хоча там не про потрібність, а про дві величини – корисність і вартість. Тобто на двовимірній площині кожен знаходить точку з потрібними координатами.
[12:19:48] Wanderer: Це гра в слова? Потрібність не корелює з вартістю і корисністю?
[12:20:18] Andrew Ko: для мене ні
[12:20:40] Wanderer: Біда картинки в тім, що код – штука небінарна. Він в більшості випадків лежить всередині картинки. Виходить що твердження “юніттести не потрібні” – невірне. Більшість коду і не так щоб тривіальне і не так щоб багато алгоритмів, і не так щоб багато інтеракцій. Середній код.
[12:22:24] Andrew Ko: Більшість коду навпаки тривіальна. Всі всьюшки тривіальні. Нетривіального коду мало.
[12:23:03] Wanderer: В джанго логіка не у вьюшках, звісно що вони тривіальні.
[13:39:58] Ендрю С.: IMNSHO

1) Корисність юніт теста обернено пропорційна кількості замоканих об’єктів при його написанні.
2) Ідеальний об’ект для юніт тестів – чиста фунція.
3) Бізнесу не пофіг на вартість додавання нових фіч – економічно це чиста задача на ROI — автотести це інвестиція.
4) юніт тести покривають сабсет того що можуть знайти інтеграційні/функціональні тести, тому коли доходить до вибору між ними то функціональні рулять
5) питання того що функційні тести довші вирішуються більшою к-стю заліза, шо є дешево
[13:42:24] Wanderer: Ага, і ще можливий випадок, коли ми перемкнемось на інший фреймворк, і отримаємо абсолютно нетестовані моделі (у випадку мвс) з невідомою поведінкою. А от якби були юніттести на моделі…
[13:44:41] Ендрю С.: А якщо є функ. тести на АПІ то взазалі пофіг якого рівня зміни коду ми робим всередині 😉
[13:45:00] Taras: скільки функціоналу покривають функ тести?? Хтось бачив покриття таких тестів ну хоча б 20%?
[13:46:31] Wanderer: Ну і да, тести таки круто показують коли код штиняє. Юніттести.
[13:46:44] Ендрю С.: Я і юніт тестів більше 50% не зустрічав в природі, но слухи ходять шо і ті і інші бувають суттєво вищі 🙂
[13:46:57] Andrew Ko: Тарас, всі критичні флови як правило покриті. Все, що не покрито тестами, покрито qa. 100% покриття коду тестами це взагалі єрєсь для багатих буратін.
“а якщо є функ. тести на АПІ то взазалі пофіг якого рівня зміни коду ми робим всередині ;)”

(y)  хоч на бейсіку все перепиши
[13:50:22] Yuriy S.: Я б так не сказав. На практиці це не підтверджується.
[13:50:22] Wanderer: Тести на АРІ банально складніші, а все програмування – це прагнення розбити код на прості чанки.
[13:53:06] Ендрю С.: Мікро-сервіси на допомогу, власне в цьому контексті вони рулять.
[13:54:24] Wanderer: Якщо сервіс настільки мікро, що те що під ним не вимагає юніттестів – питань нема. Але я такого не зустрічав.