Як зробити тест залежним від результатів іншого тесту?


13

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

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

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

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

Я не зміг знайти для цього відповідний тег, але я використовую тестовий двигун Visual Studio.


1
Я розумію, що аналізатор працює неправильно, якщо утиліта не працює. Але якщо ви запустите свої тести, ви побачите, що тести на корисність виходять з ладу. Чому ви хочете, щоб і інші тести не вийшли з ладу?
Євген Мартинов

1
Я ніколи раніше не чув, щоб хтось цього бажав. Що ви намагаєтеся досягти?
Есбен Сков Педерсен


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

3
@ t3chb0t Якщо ви хочете переконатися, що ваша утиліта працює, вам потрібно написати тести для перевірки своєї корисності. Одиничні випробування повинні бути атомними. Ви хочете, щоб вони протестували один компонент.
maple_shaft

Відповіді:


11

Немає сенсу переконатися, що кожен дефект у вашій системі відповідає лише одному тесту.

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

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

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


8

Це залежить від ваших інструментів, але ви, мабуть, не можете (і не повинні)

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

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

Ви можете помістити ці корисні методи в окреме рішення або тестову категорію. Переконайтесь, що вони візуально «виділяються» у вашого тестового бігуна, або що ця категорія запускається першою та не проводить жодних інших тестів, якщо тести в цій категорії проходять *. Якщо один з цих тестів не вдасться, помилка, ймовірно, пройде через усі тести, і ви повинні допомогти переконатися, що той, хто запускає тести, знає для початку, перш за все виправляючи ці невдалі тести. Те саме стосується тестів одиниць та інтеграції. Якщо Unittest не вдасться, це призведе до каскаду та спричинить різного роду пошкодження в тестах інтеграції. Всім відомо, що коли тести Unit та Integration не вдаються, ви починаєте з перевірки Unittests ...

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


5

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

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

Ви можете перемістити утиліти до власного рішення та додати посилання на отриманий dll у поточному проекті.


4

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

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

Таким чином ви можете зберігати свої тести атомними, як уже було запропоновано, і дозволити CI подбати про те, щоб перевірити ваші тести.

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


4

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

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

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

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

Я не знаю, як це працює у Visual Studio, тому що мені ще потрібно зробити що-небудь, пов’язане з широким тестуванням на C #, але в частині світу Java це працює так: Під папкою вихідного проекту у нас зазвичай є дві папки, один називається "основним", що містить виробничий код, і один називається "тест", що містить код тестування. У розділі "main" у нас є ієрархія папок, яка точно відповідає ієрархії пакетів нашого вихідного коду. Пакети Java приблизно відповідають просторам імен C #. C # не вимагає, щоб ви відповідали ієрархії папок ієрархії простору імен, але бажано це зробити.

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

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

Отже, що я роблю, це те, що я називаю папки (тобто пакети) моїх тестів так:

t001_SomeSubsystem
t002_SomeOtherSubsystem
t003_AndYetAnotherSubsystem
...

Це гарантує, що всі тести для "SomeSubsystem" будуть виконані перед усіма тестами для "SomeOtherSubsystem", які, в свою чергу, будуть виконані перед усіма тестами для "AndYetAbodySubsystem" тощо, і так далі.

У папці окремі тестові файли називаються так:

T001_ThisTest.java
T002_ThatTest.java
T003_TheOtherTest.java

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


2
I don't know about everyone else, but I would prefer to have the freedom to try to do something in an odd way, and see for myself whether the results are better or worse++ товариш. Я не знаю, що мені подобається рішення, але мені подобається ставлення, яке ви там показали.
RubberDuck
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.