Тести є для підтримки та забезпечення оборонного програмування
Оборонне програмування захищає цілісність системи під час виконання.
Тести - це (в основному статичні) засоби діагностики. Під час виконання ваших тестів ніде не видно. Вони схожі на ліси, що використовуються для встановлення високої цегляної стіни або скельного куполу. Ви не залишаєте важливих частин конструкції, тому що під час будівництва у вас є будівельні ліси. У вас є будівельні ліси, які тримають його під час будівництва, щоб полегшити розміщення всіх важливих деталей.
EDIT: Аналогія
Як щодо аналогії з коментарями в коді?
Коментарі мають своє призначення, але можуть бути зайвими або навіть шкідливими. Наприклад, якщо ви помістите в коментарі суттєві знання про код , то змініть код, коментарі в кращому випадку стають неактуальними та в гіршому випадку шкідливими.
Тому скажіть, що ви поставили багато тестових знань про свою кодову базу в тести, такі як MethodA не може взяти нуль, а аргумент MethodB повинен бути > 0
. Потім код змінюється. Нуль нормально для A зараз, і B може приймати значення як -10. Існуючі тести тепер функціонально помиляються, але продовжуватимуть проходити.
Так, вам слід оновлювати тести одночасно з оновленням коду. Ви також повинні оновлювати (або видаляти) коментарі одночасно з оновленням коду. Але всі ми знаємо, що це не завжди буває, і це помилки.
Тести перевіряють поведінку системи. Ця реальна поведінка властива самій системі, а не властива тестам.
Що може піти не так?
Мета тестів - придумати все, що може піти не так, написати тест на нього, який перевіряє правильність поведінки, а потім скласти код виконання, щоб він пройшов усі тести.
Що означає, що оборонне програмування - це суть .
TDD управляє оборонним програмуванням, якщо випробування є комплексними.
Більше тестів, водіння більш захисного програмування
Коли помилок неминуче знайдеться, пишеться більше тестів для моделювання умов, які виявляють помилку. Потім код фіксується, і код для переходу цих тестів, і нові тести залишаються в тестовому наборі.
Хороший набір тестів передасть і хороші, і погані аргументи функції / методу, і очікує стійких результатів. Це, в свою чергу, означає, що перевірений компонент буде використовувати перевірки передумов (захисне програмування) для підтвердження переданих йому аргументів.
Загалом кажучи ...
Наприклад, якщо аргумент нуля для певної процедури недійсний, то принаймні один тест пройде нуль, і він очікує винятку / помилки "недійсний нульовий аргумент".
Принаймні один інший тест, звичайно, пройде дійсний аргумент - або прокрутить великий масив і передасть незрозумілі вірні аргументи - і підтвердить, що отриманий стан є відповідним.
Якщо тест не передає цей нульовий аргумент і отримує відхилення від очікуваного винятку (і цей виняток було викинуто через те, що код захищено перевірив стан, переданий йому), то null може в кінцевому підсумку бути присвоєним властивості класу або поховано у збірці якогось роду, де цього не повинно бути.
Це може спричинити несподіване поведінку в якійсь зовсім іншій частині системи, до якої передається екземпляр класу, в деякій віддаленій географічній місцевості після доставки програмного забезпечення . І це те, чого ми насправді намагаємось уникати, правда?
Це може бути навіть гірше. Екземпляр класу з недійсним станом можна серіалізувати та зберігати, лише щоб викликати збій, коли він буде відновлений для подальшого використання. Гейз, я не знаю, можливо, це якась механічна система управління, яка не може перезапуститись після відключення, оскільки не може дезаріалізувати власний стійкий стан конфігурації. Або екземпляр класу може бути серіалізований і переданий до якоїсь зовсім іншої системи, створеної іншим об'єктом, і ця система може збоїти.
Особливо, якщо програмісти цієї іншої системи не кодували оборонно.