Чи погані тести інтеграції (бази даних)?


120

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

Я вважаю, що в деяких випадках одиничне тестування просто нічого не доводить.

Візьмемо для прикладу наступну (тривіальну, наївну) реалізацію сховищ (у PHP):

class ProductRepository
{
    private $db;

    public function __construct(ConnectionInterface $db) {
        $this->db = $db;
    }

    public function findByKeyword($keyword) {
        // this might have a query builder, keyword processing, etc. - this is
        // a totally naive example just to illustrate the DB dependency, mkay?

        return $this->db->fetch("SELECT * FROM products p"
            . " WHERE p.name LIKE :keyword", ['keyword' => $keyword]);
    }
}

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

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

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

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

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

Як ви вирішуєте подібні ситуації?

Чи справді інтеграційні тести "погані" у такому випадку?

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


5
Прочитайте agitar.com/downloads/TheWayOfTestivus.pdf , особливо на сторінці 6 "Тест важливіший за одиницю".
Док Браун

2
@ user61852 в описі написано "наївно", так?
mindplay.dk

4
Як би ваш колега був абсолютно впевнений, що його знущається база даних поводиться як справжня річ?
Thorbjørn Ravn Andersen

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

3
@ mindplay.dk: ключове речення в цьому пункті - "Але не зациклюйтеся на будь-якій догмі. Напишіть тест, який потрібно написати". Ваш співробітник, здається, застряг у догмі. І вам хтось не потрібен пояснюючи, що таке тест, який потрібно записати у вашому прикладі - це ви вже знаєте. Цілком очевидно, що для тестування, якщо ваша база даних розуміє запит, вам потрібно запустити запит проти реальної бази даних - жоден макет не може сказати вам це.
Док. Браун

Відповіді:


129

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

Поширений спосіб мислення про тестування - це тестування піраміди . Ця концепція часто пов'язана з Agile, і багато хто писав про неї, включаючи Мартіна Фаулера (який приписує це Майку Конну в успіху з Agile ), Алістера Скотта та блогу тестування Google .

        /\                           --------------
       /  \        UI / End-to-End    \          /
      /----\                           \--------/
     /      \     Integration/System    \      /
    /--------\                           \----/
   /          \          Unit             \  /
  --------------                           \/
  Pyramid (good)                   Ice cream cone (bad)

Поняття полягає в тому, що швидкодіючі, стійкі випробування блоку є основою тестового процесу - повинні бути більш цілеспрямовані одиничні тести, ніж тести системи / інтеграції, і більше системних / інтеграційних тестів, ніж тестові. Коли ви наближаєтесь до вершини, тести, як правило, потребують більше часу / ресурсів для запуску, як правило, піддаються більшої крихкості та в’ялості та менш специфічні для визначення того, яка система чи файл порушена ; природно, бажано уникати "топ-важкої".

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


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


13
+1 для "Тест, який є ідеальним дзеркалом його реалізації, насправді взагалі нічого не тестує." Все занадто поширене. Я називаю це " Доппельгангер" Антипаттером .
dodgethesteamroller

6
Контрарна школа програмного забезпечення QA, керована контекстним тестуванням , частково присвячена тому, що існують такі корисні загальні правила, як "Піраміда тестування". Зокрема, нарізні тексти руху дають багато прикладів, коли тести на інтеграцію набагато цінніші, ніж інші види тестів (тому що вони тестують систему в контексті, як система ) ....
dodgethesteamroller

7
... отже, Фоулер та ін., стверджуючи, що на інтеграційні тести та тести прийняття користувачів потрібно витратити менше зусиль, оскільки їх надто складно написати надійним та доступним способом, насправді просто надають ex post facto привід для того, чому вони не придумали, як добре протестувати на більш високих рівнях.
dodgethesteamroller

1
@dodgethesteamroller Поглиблені обговорення такої "контраріанської школи", напевно, найкраще підходять для їх власної відповіді. Особисто я вважаю, що Блог тестування Google виконує досить непогану роботу, описуючи достоїнства швидких, чітко оцінених автоматизованих тестів поряд із тестами системи в контексті. Якщо ви вважаєте це незрозумілим, я перелічую тут тестову піраміду як корисну модель або вихідну точку, а не як привід перестати думати як інженера.
Джефф Боуман

1
Настійно рекомендується подання про ієрархію та співвідношення одиничних тестів до інтеграційних тестів: vimeo.com/80533536 Дуже добре пояснено.
szalski

88

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

Це трохи схоже на те, що антибіотики погані - все потрібно вилікувати вітамінами.

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

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

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

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


Ви б не перевіряли, чи містить база даних певні дані чи ні?
Tulains Córdova

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

Так - приклад, який я використав, як вказувалося, тривіальний; справжній сховище може мати всілякі складні варіанти пошуку та сортування, наприклад, використовуючи
конструктор

2
Хороша відповідь, але я хотів би додати, що БД має бути в пам'яті, щоб переконатися, що одиничні тести швидко проходять.
BЈович

3
@ BЈовић: На жаль, це не завжди можливо, оскільки, на жаль, там немає двох сумісних БД і не всі вони працюють в пам'яті. Також існують проблеми з ліцензуванням комерційних БД (у вас може не бути ліцензії на запуск її на будь-якій машині), ...
Matthieu M.

17

Блок тестів не фіксує всіх дефектів. Але вони дешевші у встановленні та (повторному запуску) порівняно з іншими видами тестів. Тестові одиниці виправдані поєднанням середньої вартості та низької до середньої вартості.

Ось таблиця, що показує показники виявлення дефектів для різних видів тестування.

введіть тут опис зображення

Джерело: стор.470 в Кодексі 2 , який МакКоннелл


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

3
@RubberDuck Ця діаграма складається з книги 2006 року, і вона заснована на даних 1986, 1996, 2002 (якщо уважно подивитися). Я не переглянув протоколи збору даних у джерелах, не можу сказати, коли вони почали відслідковувати дефект та як повідомлялося про це. Чи може цей графік бути дещо застарілим? Це може. У грудні минулого року я був на семінарі, і викладач зазначив, що інтеграційні тести виявляють більше помилок, ніж одиничні тести (в 2 рази, iirc). Ця діаграма говорить, що вони приблизно однакові.
Нік Алексєєв

13

Ні, вони непогані. Сподіваємось, у вас повинні бути тести для інтеграції та інтеграції. Вони використовуються та працюють на різних етапах циклу розвитку.

Тестові одиниці

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

Отже, для бази даних слід мати щось на зразок:

IRespository

List<Product> GetProducts<String Size, String Color);

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

Інтеграційні тести

Інтеграційні тести, як правило, є тестами граничного перетину. Ми хочемо запустити ці тести на сервері розгортання (реальне середовище), пісочниці або навіть локально (вказано на пісочницю). Вони не запускаються на сервері збірки. Після того, як програмне забезпечення буде розгорнуте в оточуюче середовище, вони зазвичай виконуватимуться як діяльність після розгортання. Їх можна автоматизувати за допомогою утиліт командного рядка. Наприклад, ми можемо запустити nUnit з командного рядка, якщо класифікуємо всі тести інтеграції, які ми хочемо викликати. Вони насправді викликають реальний сховище за допомогою реального виклику бази даних. Цей тип тестів допомагає:

  • Навколишнє середовище Готовність до стабільності здоров'я
  • Тестування реальної речі

Ці тести іноді важче провести, оскільки нам може знадобитися налаштувати та / або зруйнувати. Подумайте про додавання продукту. Ми, мабуть, хочемо додати продукт, запитати його, щоб побачити, чи він був доданий, а потім, коли ми закінчимо, видаліть його. Ми не хочемо додавати 100-ти або 1000-ти "інтеграційних" продуктів, тому потрібні додаткові налаштування.

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

Одне повинно мати і те, і інше.

  • Запустіть одиничні тести для кожної збірки.
  • Запустіть тести інтеграції для кожного розгортання.

Я б рекомендував запускати тести інтеграції для кожної збірки, а не робити зобов'язання та натискати. Залежить, скільки часу вони займуть, але також непогано тримати їх швидкими з багатьох причин.
artbristol

@ArtBristol - Зазвичай на нашому сервері збірки не налаштована повна залежність від середовища, тому ми не можемо там проводити наші інтеграційні тести. Але якщо там можна запустити інтеграційні тести, займіться цим. У нас є пісочниця розгортання, створена після збірки, яку ми використовуємо для тестування інтеграції для перевірки розгортання. Але кожна ситуація різна.
Джон Рейнор

11

Тести на інтеграцію баз даних непогані. Навіть більше, вони необхідні.

Напевно у вас додаток розбито на шари, і це добре. Ви можете протестувати кожен шар ізольовано, глузуючи з сусідніх шарів, і це теж добре. Але незалежно від того, скільки шарів абстракції ви створюєте, в якийсь момент повинен бути шар, який виконує брудну роботу - насправді спілкуйтеся з базою даних. Якщо ви не тестуєте його, ви взагалі не тестуєте. Якщо ви перевіряєте шар n шляхом глузування шару n-1, ви оцінюєте припущення, що шар n працює за умови, що шар n-1 працює. Для того, щоб це працювало, потрібно якось довести, що шар 0 працює.

Хоча теоретично ви могли б використовувати тестову базу даних, аналізуючи та інтерпретуючи створений SQL, набагато простіше та надійніше створити тестову базу даних на льоту та поговорити з нею.

Висновок

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


Я думав додати відповідь, подібний до вашої, але ви сказали це краще! З мого досвіду, деякі тести на шарі, який отримує і зберігає дані, врятували мені багато горя.
Даніель Холлінрак

Тести на інтеграцію бази даних погані. Чи є у вас в базі ci / cd база даних? Це здається мені досить складним. Набагато простіше знущатися з баз даних і будувати шар абстракції, щоб використовувати це. Мало того, що набагато більш елегантне рішення, воно настільки швидке, наскільки це можливо. Одиничні випробування повинні бути швидкими. Тестування вашої бази даних уповільнює ваші тестові одиниці до рівня, який не є прийнятним. Експерименти не повинні займати більше 10 хвилин, навіть якщо їх у вас тисячі.
Девід

@David Чи є у вас в базі ci / cd база даних? Звичайно, це досить стандартна функція . До речі, я не виступаю за інтеграційні тести замість одиничних тестів - я виступаю за інтеграційні тести спільно з одиничними тестами. Швидкі тести блоку є важливими, але бази даних занадто складні, щоб покладатися на одиничні тести з глузливими взаємодіями.
el.pescado

@ el.pescado Я не погоджуюся. Якщо комунікація у вашій базі даних знаходиться за шаром абстракції, насмішкувати насправді легко. Ви можете просто вирішити, який об’єкт повернути. Також факт, що щось є стандартним, не робить це доброю справою.
Девід

@David Я думаю, це залежить від того, як ви підходите до бази даних. Це деталізація впровадження чи важлива частина системи ? (Я схиляюся до останнього) . Якщо ви розглядаєте базу даних як німе зберігання даних, то так, ви можете обійтися без інтеграційних тестів. Однак, якщо в базі даних є якась логіка - обмеження, тригери, сторонні ключі, транзакції, або ваш рівень даних використовує користувацький SQL замість простих методів ORM, я вважаю, що одиничних тестів не вистачить.
el.pescado

6

Вам потрібно обоє.

У вашому прикладі, якщо ви протестували цю базу даних у певному стані, під час findByKeywordзапуску методу ви отримуєте назад дані, які ви очікуєте, це тест на інтеграцію.

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


6

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

Багато програм сьогодні просто не працюють, якби їх сервер баз даних не працював. Принаймні, подумайте про це в контексті функції, яку ви намагаєтеся перевірити.

З одного боку, якщо те, що ви намагаєтеся протестувати, не залежить або може бути змушене взагалі не залежати від бази даних, тоді напишіть свій тест таким чином, щоб він навіть не намагався використовувати база даних (просто надайте макетні дані за потребою). Наприклад, якщо ви намагаєтеся перевірити певну логіку автентифікації під час подання веб-сторінки (наприклад), можливо, це добре відірвати це від БД (якщо ви не покладаєтесь на БД для аутентифікації, або це можна знущатися з цього розумно легко).

З іншого боку, якщо це функція, яка безпосередньо покладається на вашу базу даних, і яка взагалі не працюватиме в реальному середовищі, якщо база даних не буде доступна, то знущайтеся з того, що робить БД у вашому клієнтському коді DB (тобто шарі, що використовує це БД) не обов'язково має сенс.

Наприклад, якщо ви знаєте, що ваша програма покладається на базу даних (а можливо, і на певну систему баз даних), глузування з поведінки бази даних заради неї часто буде марною витратою часу. Двигуни бази даних (особливо RDBMS) - це складні системи. Кілька рядків SQL насправді можуть виконати багато роботи, що було б важко імітувати (адже, якщо ваш запит SQL має кілька рядків, швидше за все, вам знадобиться ще багато рядків Java / PHP / C # / Python код для отримання однакового результату всередині): дублювання логіки, яку ви вже впровадили в БД, не має сенсу, і перевірка цього тестового коду стала б проблемою сама по собі.

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

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

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

  • Якщо ваш додаток просто відповідає моделі CRUD, де у вас є шар абстракції, який дозволяє обмінюватися між будь-якими RDBMS простими засобами налаштування конфігурації, швидше за все, ви зможете працювати з макетною системою досить легко (можливо, розмиття лінія між блоком та інтегрованим тестуванням з використанням RDBMS в пам'яті).
  • Якщо ваша програма використовує більш складну логіку, що було б специфічно для одного з SQL Server, MySQL, PostgreSQL (наприклад), тоді, як правило, більше сенсу буде тест, який використовує цю конкретну систему.

"Багато додатків сьогодні просто не працювали б, якби їх сервер баз даних знизився" - це дійсно важливий момент!
el.pescado

Добре пояснення меж складних макетів, як використання іншої мови для знущання над SQL. Коли тестовий код стає досить складним, здається, що його потрібно перевірити, це запах якості QA.
dodgethesteamroller

1

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

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

Однак часто забута і дещо дорога альтернатива / супутник глузування - це "віртуалізація" .

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

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


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

0

Unit Testsі Integration Testsє ортогональними один для одного. Вони пропонують інший погляд на додаток, який ви будуєте. Зазвичай потрібно обох . Але момент часу відрізняється, коли ви хочете, які саме випробування.

Найчастіше ви хочете Unit Tests. Одиничні тести зосереджуються на невеликій частині тестованого коду - те, що саме називається a unit, залишається читачеві. Але мета проста: отримання швидкого зворотного зв’язку про те, коли і де ваш код зламався . З огляду на це, повинно бути зрозуміло, що виклики до фактичної БД є nono .

З іншого боку, є речі, які можна перевірити лише у жорстких умовах без бази даних. Можливо, у вашому коді є умова перегонів, і виклик до БД кидає порушення, unique constraintяке може бути викинуте лише у тому випадку, якщо ви фактично використовуєте свою систему. Але такі види тестів дорогі, що ви не можете (і не хочете) їх запускати так часто unit tests.


0

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

Знущання з шару доступу до даних (DAO) і фактичне посягання на базу даних не тільки не дозволяє мені кодувати те, як мені подобається і до якого я звик, але він пропускає велику частину фактичної бази коду. Якщо ви не справді тестуєте рівень доступу до даних та базу даних та просто робите вигляд, а потім витрачаєте багато часу на знущання над речами, я не можу зрозуміти корисність такого підходу, щоб фактично перевірити свій код. Я тестую невеликий шматочок замість більшого з одним тестом. Я розумію, що мій підхід може бути в більшій мірі тесту на інтеграцію, але здається, що одиничний тест з макетом - це надмірна витрата часу, якщо ви насправді просто пишете тест на інтеграцію раз і перший. Це також хороший спосіб розвитку та налагодження.

Насправді вже деякий час я знаю про TDD та поведінку, керовану дизайном (BDD) і роздумував над способами її використання, але важко додати одиничні тести заднім числом. Можливо, я помиляюся, але написання тесту, який охоплює більше коду до кінця з включеною базою даних, здається набагато більш повним і більш високим пріоритетом тесту для написання, який охоплює більше коду, і є більш ефективним способом написання тестів.

Насправді, я думаю, що щось подібне до дизайну, що керується поведінкою (BDD), що намагається протестувати цілком у кінці доменної мови (DSL). У нас є SpecFlow у світі .Net, але він розпочався як відкритий код із огірком.

https://cucumber.io/

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

Згідно з Stack Overflow, глузування використовується, коли реальні об’єкти недоцільно включати в тест одиниці.

https://stackoverflow.com/questions/2665812/what-is-mocking

"Знущання в основному застосовуються при тестуванні одиниць. Об'єкт, що перевіряється, може мати залежність від інших (складних) об'єктів. Для ізоляції поведінки об'єкта, який ви хочете перевірити, ви замінюєте інші об'єкти макетами, що імітують поведінку реальних об'єктів. Це корисно, якщо реальні об’єкти недоцільно включати в одиничний тест ".

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

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

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

https://www.joelonsoftware.com/2009/01/31/from-podcast-38/


настільки очевидно, що ви не розумієте різниці між
тестовими модулями

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

-1

Зовнішні залежності слід глузувати, оскільки ви не можете їх контролювати (вони можуть пройти під час фази тестування інтеграції, але не вдасться у виробництві). Диски можуть вийти з ладу, з’єднання з базою даних можуть вийти з ладу з будь-якої кількості причин, можуть виникнути проблеми з мережею і т. Д. Наявність тестів на інтеграцію не надає додаткової впевненості, оскільки всі вони можуть виникнути під час виконання.

Істинними тестовими одиницями ви тестуєте в межах пісочниці, і це повинно бути зрозуміло. Якщо розробник написав запит SQL, який не вдався до QA / PROD, це означає, що вони навіть не перевіряли його жодного разу до цього часу.


+1 для "ви не можете керувати ними (вони можуть пройти під час фази тестування інтеграції, але не вдасться у виробництві)" .
Tulains Córdova

Ви можете керувати ними задовільно.
el.pescado

Я розумію, але я вважаю, що це було правдивіше, ніж сьогодні? За допомогою автоматизації та інструментів (як Docker) ви можете точно та надійно повторити та повторити налаштування всіх ваших бінарних / серверних залежностей для інтеграції тестових наборів. Звичайно, так, фізичне обладнання (та сторонні послуги тощо) може вийти з ладу.
mindplay.dk

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

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