Короткий вступ до цього питання. Я використовую TDD і останнім часом BDD вже більше року. Я використовую такі методи, як глузування, щоб зробити письмові тести ефективніше. Останнім часом я розпочав особистий проект, щоб написати для себе невелику програму управління грошима. Оскільки у мене не було застарілого коду, це був ідеальний проект, який можна було розпочати з TDD. На жаль, я не пережив такої радості від TDD. Це навіть настільки зіпсувало мою забаву, що я відмовився від проекту.
У чому була проблема? Ну, я використовував подібний підхід TDD, щоб тести / вимоги розвивали дизайн програми. Проблема полягала в тому, що більше половини часу на розробку, як для написання / тестування рефактора. Отже, врешті-решт, я не хотів реалізовувати більше функцій, тому що мені потрібно було б переробляти та писати на багато тестів.
На роботі у мене є багато спадкового коду. Тут я пишу все більше і більше інтеграційних та приймальних тестів і менше одиничних тестів. Це не є поганим підходом, оскільки помилки в основному виявляються за допомогою тестів прийняття та інтеграції.
Моя ідея полягала в тому, щоб я міг врешті-решт написати більше інтеграційних та приймальних тестів, ніж тестових одиниць. Як я вже говорив, для виявлення помилок одиничні тести не є кращими, ніж тести інтеграції / прийняття. Тест блоку також хороший для дизайну. Оскільки я писав багато з них, мої заняття завжди розроблені так, щоб вони були добре перевірені. Крім того, підхід, який дозволяє тестам / вимогам керувати дизайном, призводить в більшості випадків до кращого дизайну. Остання перевага одиничних тестів полягає в тому, що вони швидші. Я написав достатньо інтеграційних тестів, щоб знати, що вони можуть бути майже такими ж швидкими, як одиничні тести.
Після того, як я шукав через Інтернет , я виявив, що є дуже схожі ідеї , по-моєму , згадані тут , і там . Що ви думаєте про цю ідею?
Редагувати
Відповідаючи на запитання, один приклад, коли дизайн був хорошим, але мені потрібна була велика реконструкція для наступної вимоги:
Спочатку були певні вимоги до виконання певних команд. Я написав розширюваний командний аналізатор - який розбирав команди з якогось командного рядка і називав правильний на моделі. Результат був представлений у модельному класі перегляду:
Тут нічого поганого не було. Усі класи були незалежними один від одного, і я міг легко додавати нові команди, показувати нові дані.
Наступна вимога полягала в тому, щоб кожна команда мала своє представлення подання - якесь попереднє перегляд результату команди. Я переробив програму, щоб досягти кращого дизайну для нової вимоги:
Це було також добре, оскільки тепер у кожної команди є своя модель перегляду, а отже, і власний попередній перегляд.
Вся справа в тому, що аналізатор команд був змінений на використання розбору команд на основі лексеми і позбавлений його здатності виконувати команди. Кожна команда отримала свою власну модель перегляду, а модель представлення даних знає лише поточну модель перегляду команд, яка, ніж знає дані, які повинні бути показані.
Я хотів знати в цей момент, якщо новий дизайн не порушив жодної існуючої вимоги. Мені не довелося змінювати жодного мого тесту на прийняття. Мені довелося переробляти або видаляти майже КОЖНІ тести одиниць, що було величезною купою роботи.
Я хотів показати тут загальну ситуацію, яка часто траплялася під час розвитку. Не було проблем зі старими чи новими конструкціями, вони просто природно змінилися з вимогами - як я це зрозумів, це одна перевага TDD, що дизайн розвивається.
Висновок
Дякую за всі відповіді та обговорення. Підсумовуючи цю дискусію, я продумав підхід, який я випробую під час свого наступного проекту.
- Перш за все, я пишу всі тести, перш ніж реалізувати щось подібне, як завжди.
- Для вимог я спочатку пишу кілька тестів на прийняття, які перевіряють всю програму. Потім я пишу кілька тестів на інтеграцію для компонентів, де мені потрібно реалізувати вимогу. Якщо є компонент, який тісно співпрацює з іншим компонентом, щоб реалізувати цю вимогу, я також написав би тести інтеграції, де обидва компоненти тестуються разом. І останнє, але не в останню чергу, якщо мені доведеться написати алгоритм або будь-який інший клас з високою перестановкою - наприклад, серіалізатором - я б писав одиничні тести для цього конкретного класу. Усі інші класи не перевіряються, але будь-які одиничні тести.
- Для помилок процес можна спростити. Зазвичай помилка викликається одним або двома компонентами. У цьому випадку я б написав один інтеграційний тест для компонентів, які тестують помилку. Якби це стосувалося алгоритму, я б написав лише одиничний тест. Якщо виявити компонент, де виникає помилка, непросто, я написав би тест на прийняття, щоб знайти помилку - це має бути винятком.