Скільки тестів на метод?
Ну і теоретичний і дуже непрактичний максимум - це складність N-Path (припустимо, тести охоплюють різні способи через код;)). Мінімум ОДИН !. За загальнодоступним методом, тобто він не перевіряє деталі реалізації, лише зовнішню поведінку класу (повертає значення та викликає інші об'єкти).
Ви цитуєте:
* І думка про тестування кожного з ваших методів за допомогою власного методу тестування (у співвідношенні 1-1) буде смішною. *
а потім запитайте:
Отже, якщо створення тесту для кожного методу є "смішним", як / коли ви обирали те, для чого пишете тести?
Але я думаю, ви тут неправильно зрозуміли автора:
Ідея мати one test method
пер one method in the class to test
- це те, що автор називає "сміхотворним".
(Принаймні для мене) Мова не про те, що "менше", а про "більше"
Тож дозвольте перефразувати так, як я його зрозумів:
І думка про тестування кожного з ваших методів ТІЛЬКИ ОДНІМ МЕТОДОМ (власний метод тестування у взаємозв'язку 1-1) буде смішною.
Щоб процитувати ще раз:
Коли ви зрозумієте, що справа в тому, щоб вказати на поведінку, а не писати тести, ваша точка зору зміниться.
Коли ви практикуєте TDD, ви не думаєте :
У мене є метод, calculateX($a, $b);
і він потребує тесту, testCalculcateX
який перевіряє ВСЕ, що стосується методу.
Що TDD говорить вам, це подумати про те, що ваш код повинен робити :
Мені потрібно обчислити більше двох значень ( перший тестовий випадок! ), Але якщо $ a менше нуля, то це повинно призвести до помилки ( другий тестовий випадок! ), А якщо $ b менше нуля, він повинен .... ( третій тестовий випадок! ) тощо.
Ви хочете перевірити поведінку, а не лише окремі методи без контексту.
Таким чином ви отримуєте тестовий набір, який є документацією для вашого коду, і дійсно пояснює, що очікується зробити, можливо, навіть чому :)
Як ви вирішите вирішити, для якого фрагмента коду ви створите одиничні тести?
Ну, все, що потрапляє в сховище або в іншому місці виробництва, потребує перевірки. Я не думаю, що автор ваших цитат не погодиться з цим, як я намагався констатувати вище.
Якщо у вас немає тесту для нього, стає важче (дорожче) змінити код, особливо якщо це не ви вносите зміни.
TDD - це спосіб переконатися, що у вас є тести на ВСЕ, але поки ви будете писати тести, це добре. Зазвичай їх написання в один і той же день допомагає, оскільки ви не збираєтеся це робити пізніше, чи не так? :)
Відповідь на коментарі:
пристойну кількість методів не можна перевірити в конкретному контексті, оскільки вони або залежать, або залежать від інших методів
Ну є три речі, якими можна назвати ці методи:
Публічні методи інших класів
Ми можемо знущатися з інших класів, щоб ми там визначили стан. Ми контролюємо контекст, так що це не проблема.
* Захищені або приватні методи на тому самому *
Все, що не входить у загальнодоступний API класу, зазвичай не тестується безпосередньо.
Ви хочете перевірити поведінку, а не реалізацію, і якщо клас робить все, це працює в одному великому публічному методі або в багатьох менших захищених методах, які викликаються, це реалізація . Ви хочете змінити захищені методи БЕЗ торкання ваших тестів. Тому що ваші тести зламаються, якщо зміни вашого коду змінить поведінку! Ось для чого там ваші тести, щоб сказати вам, коли щось зламаєте :)
Публічні методи на одному класі
Це трапляється не дуже часто? І якщо це так, як у наступному прикладі, є кілька способів вирішити це:
$stuff = new Stuff();
$stuff->setBla(12);
$stuff->setFoo(14);
$stuff->execute();
Те, що встановники існують і не є частиною підпису методу Execute - це інша тема;)
Те, що ми можемо перевірити тут, - це те, чи виконується виконувати, коли ми встановлюємо неправильні значення. Це setBla
виняток, коли ви передаєте рядок, може бути перевірено окремо, але якщо ми хочемо перевірити, що ці два дозволені значення (12 і 14) не працюють РАЗОМ (з будь-якої причини), ніж один тестовий випадок.
Якщо ви хочете "хорошого" тестового набору, ви можете, в php, можливо (!) Додати @covers Stuff::execute
примітку, щоб переконатися, що ви генеруєте лише покриття коду для цього методу, а інші речі, які є лише налаштуваннями, потрібно перевірити окремо (ще раз, якщо ти цього хочеш).
Тож справа в тому: Можливо, вам потрібно спершу створити дещо з навколишнього світу, але вам слід вміти писати змістовні тестові випадки, які зазвичай охоплюють лише одну чи, можливо, дві реальні функції (сетери тут не враховуються). Решта може бути вилучена з ефіру або спершу випробувана, а потім покладатися на них (див. @depends
)
* Примітка: запитання було перенесено з SO і спочатку стосувалося PHP / PHPUnit, тому зразок коду та посилання є зі світу php, я думаю, це також застосовно до інших мов, оскільки phpunit не сильно відрізняється від інших xUnit тестування рамок.