Всі тестові одиниці в одному виконаному файлі чи розділити їх?


12

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

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

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

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


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

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

Це не так вже й багато. Менше 20 модулів. Я також можу зібрати їх усіх однаковими прапорами, тому CMake може генерувати Makefiles без особливої ​​роботи з мого боку.
Бенджамін Клостер

Відповіді:


5

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

Але що ще важливіше, це також дозволяє мені включати тести, написані різними мовами або використовувати різні ланцюжки інструментів в одному циклі. Наприклад, одиничні тести, які я пишу, найімовірніше, є основною мовою проекту, а їх виконання - це питання побудови та використання бінарних файлів; але я також хочу перевірити свою базу даних, і я, можливо, захочу подати SQL-скрипти безпосередньо до бази даних для цього; Я, можливо, захочу запустити на своєму коді якийсь інструмент аналізу статичного коду (навіть якщо це просто якийсь вкладиш). Можливо, я хочу запустити свій статичний HTML через перевірку дійсності. Я міг би виконати grepкоманду над кодовою базою, щоб перевірити наявність підозрілих конструкцій, порушень стилю кодування або ключових слів «червоний прапор». Можливості безмежні - якщо це можна запустити з командного рядка і дотримується "нульового статусу виходу означає ОК", я можу його використовувати.


Мовний агностичний аргумент є дуже хорошим моментом, оскільки я планую здійснити прив'язки пітона для бібліотеки вниз. Дякую!
Бенджамін Клостер

@tdammers: якась тестова основа?
JBRWilkinson

@JBRWilkinson: Просто сценарій оболонки на 30 рядків. Для більшості мов, якими я користуюся, у мене мало бібліотек для загальних тестових завдань, таких як виконання функції, порівняння результату з очікуваним значенням та кидання, коли вони не відповідають. Але будь-яка задана рамка тестування одиниць легко може бути інтегрована в таку "метасистему", якщо вона може працювати з командного рядка і сигналізує про успіх / невдачу через свій статус виходу.
tdammers

2

У мене, як правило, є одна бібліотека для одиничних тестів однієї програми (або для пакету бібліотек, якими зазвичай ділиться). У цій бібліотеці я намагаюсь тиражувати або наближати простори імен досліджуваних об'єктів до тестових приладів (в основному я використовую NUnit). Це спрощує компіляцію, так як в .NET є накладні витрати, притаманні побудові кожного бінарного файлу, що збільшило б час збірки 20-проектного рішення над тим, що 10-проектне рішення з тим же LOC. Тестові бінарні файли все одно не розповсюджуються, тому будь-яка організація тестів у бінарні файли - це для вашої зручності, і я, як правило, вважаю, що YAGNI застосовується тут як і де завгодно.

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


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