Що таке тестування блоку чорної коробки?


11

Нещодавно у мене був випускний іспит з курсу програмної інженерії для моєї магістерської програми, і одне з питань на іспиті:

Unit Testing is considered:
a. White-box Testing
b. Black-box Testing
c. Either

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

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

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

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


4
як професор пояснив це, коли ви запитали їх про це? (Дивіться також Чому питання інтерв'ю роблять погані питання Програмного забезпечення Engineering.SE? )
комар

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

@Jesper вибач. Я мав на увазі сказати "як буде реалізований вихідний код". Я це зафіксував у питанні.
зворотний крок

2
While the implementation does not yet exist, whoever is writing the test generally has a pretty good idea about how the source code is going to be implemented.- Так, але сам тест цього не робить. Тестування білого поля означає тестування чогось внутрішнього у методі чи класі, як-от значення змінної. Це не означає, що тестувальник знає, як виглядає тестовий код.
Роберт Харві

Відповіді:


20

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

За допомогою тестування чорної скриньки ви дивитесь лише на інтерфейс та (якщо він існує) специфікацію для компонента. Коли функція має підпис int foo(int a, int b), я можу негайно генерувати декілька тестових випадків, просто випробувавши цікаві цілі числа: нуль, одне, мінус одне, багатоцифрове число, INT_MAX, INT_MAX - 1 тощо. Тести «чорної скриньки» чудові, оскільки вони не залежать від впровадження. Але вони також можуть пропустити важливі справи.

За допомогою тесту з білого поля я дивлюся на реалізацію, тобто вихідний код та генерує тестові випадки з цього. Наприклад, я б хотів досягти 100% покриття шляху для функції. Потім я вибираю вхідні значення, щоб усі шляхи були взяті. Тести у білій коробці чудові, оскільки вони можуть вичерпно виконувати фрагменти коду, з набагато більшою впевненістю, ніж тести з чорної скриньки. Але вони можуть лише перевіряти деталі реалізації, а не насправді важливу поведінку. У деяких випадках вони, очевидно, марно витрачають час.

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


3
"Оскільки тест" білого поля "є результатом реалізації, він може бути записаний лише після цього" - добре, якщо я збираюся написати невдалий тест у стилі TDD для наступної нової функції, яку я хотів би додати до своєї існуючої функції або класу , Спочатку я вивчаю поточну реалізацію, щоб дізнатися, що не підтримується дотепер, тому я можу створити більш значущий - спочатку невдалий - тест. Я називаю це першим тестовим підходом, а не тестом, написаним після цього. (Тим не менш, +1 від мене).
Док Браун

4

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

Зрештою, коли ви пишете тест, що ви тестуєте? Публічні методи / функції.

Якби ви писали інтерфейс для класу, а потім писали тести, а потім потрапляли на автобус, хлопець, який пише клас, поки ви знаходитесь у лікарні, повинен це зробити з вашого інтерфейсу, правда? Йому не слід було це викидати та писати власний інтерфейс та тести.

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

Розглянемо "Тестування на туалеті - тест-поведінка не реалізація" , де реалізація класу змінена, але тести все-таки повинні бути дійсними.

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


2
If you were to write the interface for a class, and then write the tests, and then you get hit by a bus, the guy who writes the class while you're in hospital should be able to do so from your interface, right?-- Не зовсім. Більшість контрактів API лише дійсно вказують підписи методів, а не семантику чи поведінку.
Роберт Харві

Ти правий; Я сприйняв це як те, що ваш інтерфейс буде містити специфікацію, з якої він написаний, а не буквально лише текст MyClassInterface.
AdamJS

@RobertHarvey Це правда, що більшість інтерфейсів прямо не описують семантику чи поведінку, але я думаю, що це, як правило, там неявно. Якби його не було, код, який вимагає певної семантики, не міг би залежати від абстракції. І інтерфейси нічого не можуть зупинити, включаючи деталі семантики та поведінки як коментарів / докблоків. Наприклад, див. Github.com/php-fig/http-message/blob/master/src/…
bdsl

3

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

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

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


1

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

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

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

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