Коли слід написати інтеграційні тести?


30

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

Чи повинні вони бути записані перед одиничними тестами або після коду виробництва лише для перевірки "проводки"?

Зауважте, що я кажу не про прийняття чи функціональні тести, а про тести інтеграції нижчого рівня.

Відповіді:


49

Книга Rspec , серед інших ресурсів BDD, пропонує такий цикл:

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

По суті, процес:

While behaviour required
    Write an integration test for a specific behaviour
    While integration test failing
        Write a unit test to fulfil partial behavior
        While unit test failing
            Write code to make unit test pass
        Commit
        While refactoring can be done
            Refactor
            While unit test failing
                Write code to make unit test pass
            Commit
    Push

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

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


2
Дякую @pdr, але я вказав, що я не говорю про тести прийняття, які написані до / на початку ітерації, мене цікавлять інтеграційні тести нижчого рівня.
Chedy2149

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

Нижній рівень: поведінка яких не визначено користувачами чи клієнтами та які використовуються для тестування взаємодій класів / компонентів, очікували розробники.
Chedy2149

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

@DocBrown, тож ваша відповідь - після виробничого коду та перед випуском?
Chedy2149

10

Реальний проект показав мені, що писати одиничні тести неможливо, і тоді інтеграція і навіть протилежний напрямок неправильні :-) Отже, я зазвичай пишу одиничні тести разом з інтеграційними.

Чому? Дозвольте мені написати, як я бачу обидва типи тестів:

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

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

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

    Це дійсно важливо, оскільки іноді вам кажуть, що ваш API не має сенсу ззовні.

Ну, а що станеться, коли я потім написав одиничні тести та інтеграційні тести?

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

Ну, а що станеться, коли я потім написав інтеграційні тести та одиничні тести?

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

Яка моя порада?

Я дізнався наступний потік:

  1. Розробіть базовий скелет свого коду
  2. Напишіть інтеграційні тести, які говорять, чи має сенс це з точки зору споживачів. На сьогоднішній день достатньо базового використання. Тест, очевидно, не працює.
  3. Напишіть код разом з одиничними тестами для кожного класу.
  4. Напишіть решту / пропущені тести інтеграції. Було б краще реалізувати ці тести протягом №3, як ви вдосконалюєте свій код.

Зауважте, що я зробив невелику презентацію про тестування блоку / інтеграції, див. Слайд №21, де описаний кістяк.


5

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

Ось де проводяться інтеграційні тести :
вони випробовують ці новостворені деталі, які складаються з попередньо перевірених підрозділів під час встановлення цих деталей разом. Найкращим випадком було б написати тести в цей момент під час написання самої заявки.


Отже, ваша відповідь - після виробничого коду?
Chedy2149

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

1
@MathewFoscarini - оновлена ​​відповідь. Сподіваюся, що зараз стане зрозуміліше.
Ben McDougall

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

3

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

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


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

2

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

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

  • Розуміння дизайну, що надається TDD, не має великого значення, оскільки дизайн досить відомий заздалегідь, і зазвичай немає нічого страшного складного, ви просто збираєте речі з однієї системи в іншу.

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

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

Ви можете знайти приклади такого підходу тут: http://davesquared.net/2011/04/dont-mock-types-you-dont-own.html (шостий абзац) http://blog.8thlight.com/eric- Сміт / 2011/10/27 / thats not not your.html


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

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

1

Тому я збирався прийняти першу відповідь, але вона була видалена.
Підсумовуючи це
за заданою ітерацією:

  1. Напишіть одиничний тест
  2. Напишіть виробничий код
  3. Напишіть інтеграційні тести для тестування взаємодій

Пам’ятайте про тестування інтеграції в той час, як 1 і 2 гарантують перевірку на рівні інтеграції.

Інтеграційні тести не обов'язково записуються в кінці на етапі 3, вони можуть бути частково записані між кроком 1 і 2.


3
Це підсумок повністю ігнорує ітеративний характер процесу. Після того як API певного коду буде стабільним до певної міри, ви можете почати писати інтеграційні тести. Потім ви можете знову працювати над виробничим кодом і, ймовірно, змінювати або розширювати свої тести на інтеграцію. Тому в більшості випадків ви не "пишете інтеграційні тести після виробничого коду", як правило, ви робите обидва в певній мірі паралельно. Насправді це дуже залежить і від того, з яким програмним забезпеченням ви працюєте. «Чорно-біле» мислення не підводить вас далі.
Док Браун

Гарний момент. Відповідь, здається, ігнорує ітеративний характер дизайну через рефакторинг.
Chedy2149

0

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

Пишіть одиничні тести при розробці коду за інтерфейсом.
Пишіть тести інтеграції при розробці інтерфейсу або будь-якого коду, який реалізує інтерфейс.

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

Однак якщо ви впроваджуєте набір REST-послуг або переробляєте модель даних та додаєте підтримку транзакцій XA, ви майже відразу розпочнете розробку інтеграційних тестів, оскільки більша частина вашої роботи зосереджена на інтерфейсі, будь то API REST або як програма використовує модель даних.


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

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

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

FYI: Wiki визначає інтеграційне тестування як "фазу тестування програмного забезпечення, в якій окремі програмні модулі поєднуються і тестуються як група"
Марко,

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