Тестування одиниць - додаток, пов'язане з базою даних


15

Який був би найкращий підхід при тестуванні одиниці моделі, яка інтегрується в додаток, щільно поєднаний з базою даних?

Конкретним сценарієм є кошик - я хотів би мати можливість перевірити додавання видалення та отримання предметів з кошика, а також логіку ціноутворення і т.д. слід уникати доступу до бази даних.


1
Цікаво, що за відповіді, які фактично говорять "перепишіть свій код додатка", проголосуйте
AD7six

Відповіді:


10

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

Просто під час тестування не підключайтеся до виробничої бази даних нічого!


1
Завдяки DI та правильному дизайну додатків, ви можете мати змогу протестувати без будь-якої бази даних --- за умови, що макет, який ви вводите, забезпечує достатньо детальний глуздок із базової бази даних.
Петро К.

4

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


2

Модель не повинна залежати від (конкретної) БД. Якщо він знає лише абстрактний БД (читайте "інтерфейс"), який передається в модель, ви можете замінити БД на об'єкт макету .

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


1

У мене була подібна проблема - у мене не було можливості гарантувати, що мій тестовий БД зберігає значення. Тому в майбутньому я отримую, наприклад, інші ціни.

Я витягнув потрібні мені дані в невеликий sqlite -DB і використав цю БД для моїх тестів. Тепер тест-БД є частиною налаштування мого модульного тесту.


2
Суть одиничних тестів полягає в тому, щоб перевірити код окремо. Якщо ви використовуєте sqllite db, то він не знаходиться в ізоляції. Також невідповідності між базами даних можуть спричинити помилки
Том Сквайрес

0

"Найкраще" є суб'єктивним, але ви можете просто використовувати тестовий db-з'єднання.

Використовуйте світильники для завантаження деяких тестових даних (наприклад, товари для придбання), а потім напишіть тестовий випадок для класу / функції, який ви хочете перевірити.


Опис одиничних тестів, які перевіряють функцію, яка діє на базу даних, як інтеграційні тести, є досить оманливим @murph.
AD7six

1
Гаразд, зараз я сильно збентежений - якщо він включає в себе базу даних, то це не за більшістю визначень - одиничний тест, оскільки його не містять у собі. Якщо у вас є база даних, ви виконуєте тести на більш високому рівні, той, який мав залежності, той, який дивиться на "поєднання" речей. Незважаючи на це, я не є чітким поясненням, як вирішити проблему.
Мерф

0

Я створив плагін для Symfony 1.4 (PHP), щоб вирішити цю проблему (серед інших). Він моделюється після того, як працює тестовий фреймворк Джанго (Python) : фреймворк будує та заповнює окрему тестову базу даних перед початком кожного тесту і знищує тестову базу даних після завершення кожного тесту.

У мене виникло кілька занепокоєнь щодо цієї стратегії, як щодо продуктивності (якщо схема не змінюється, чому б просто не очистити дані замість відновлення всієї структури?), Так і зручності (іноді я хочу перевірити базу даних після невдача тесту, тому не знищуйте його без розбору!), тому я взяв дещо інший підхід.

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

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

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


0

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

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

Наприклад, замість того, щоб скидати SQL безпосередньо в код, де він вам потрібен, є спосіб викликати метод, який робить лише те, що робить SQL. Використовуйте Person.getPhoneNumber(), наприклад, замість SELECT phone_number FROM person WHERE id = <foo>. Це не тільки зрозуміліше і простіше зрозуміти з першого погляду, але під час тестування ви можете знущатися над об’єктом Person, щоб getPhoneNumber()він завжди повертався 555-555-5555чи щось, замість того, щоб торкатися бази даних.


0

Це досить легко зробити з юнітом, якщо трохи довго намотано.

"Установка" повинна визначати і заповнювати набір тимчасових таблиць.

Потім ви можете виконати тести одиниць для всіх функцій оновлення, вставлення та видалення.

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

У фазі "сльоза" ви скидаєте всі таблиці.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.