Блок тестування для наукової бібліотеки обчислень


15

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

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

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

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

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

Відповіді:


19

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

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

  • рандомізовані алгоритми: є дві можливості. Якщо ви насправді хочете перевірити сам рандомізацію, просто заплануйте велику кількість повторень і стверджуйте, що очікувана частка випадків відповідає бажаному критерію, з достатньо великими похибками, що помилкові помилки тесту будуть досить рідкісними. (Тестовий набір, який ненадійно сигналізує про фантомні помилки, набагато гірший, ніж той, який не вловлює кожен можливий дефект.) Як варіант, скористайтеся настроюваним випадковим джерелом та замініть системний годинник (або все, що ви використовуєте) на детермінований джерело через залежність ін'єкцію, щоб ваші тести стали повністю передбачуваними.
  • алгоритми, визначені лише з точки зору точності / відкликання: ніщо не заважає вам ввести цілий набір вхідних справ і виміряти точність і згадати, додавши їх усі; це лише питання про автоматичне автоматичне генерування таких тестових випадків, щоб надання даних про тести не стало вузьким місцем для вашої продуктивності. Крім того, вказавши деякі розумно вибрані пари вводу / виводу та стверджуючи, що алгоритм обчислює саме потрібний вхід, також може працювати, якщо звичайна програма є достатньо передбачуваною.
  • нефункціональні вимоги: Якщо специфікація дійсно вимагає явних вимог простір / час, тоді ви, як правило, повинні запускати цілі набори пар введення / виводу та перевіряти, чи використання ресурсів відповідає приблизно необхідній схемі використання. Хитрість тут полягає в тому, щоб спочатку відкалібрувати свій власний тестовий клас, щоб не вимірювати десять проблем різного розміру, які в кінцевому підсумку є занадто швидкими для вимірювання або які займають стільки часу, що запуск тестового набору стає непрактичним. Ви навіть можете написати невеликий генератор випадків використання, який створює тестові випадки різного розміру, залежно від того, наскільки швидко працює ПУ.
  • швидкі та повільні тести: будь то тестові чи інтеграційні, ви часто отримуєте дуже багато дуже швидких тестів та декілька дуже повільних. Оскільки регулярно запускати тести дуже важливо, я зазвичай проходжу прагматичний шлях і розділяю все, що в мене є, на швидкий і повільний набір, щоб швидкий міг працювати як можна частіше (звичайно, перед кожним вчиненням), і неважливо, чи два тести "семантично" належать разом чи ні.

+1. Велике спасибі, є багато, якщо зрозуміти вашу відповідь. Лише пара питань: Як щодо алгоритмів оптимізації, таких як метаевристика. У мене є купа тестових функцій, але все, що я можу зробити з ними, це порівняти два різних алгоритми. Чи потрібно також знайти алгоритм орієнтиру? Що означає правильний генетичний алгоритм? І як я перевіряю кожну з "параметруючих" стратегій, таких як тип рекомбінації та мутації тощо?
Alejandro Piad

1
Для мета-евристики я б погодився вибрати декілька характерних пар вводу-виводу, тобто "відомих успіхів" рутини, і переконався, що метод (або кращий один з двох) насправді знаходить це рішення. Проблеми "вишні з вишнею", які трапляються добре, - це, звичайно, не "оптимізація", але для тестування програмного забезпечення, що не викликає особливих проблем - ви не запевняєте якість алгоритму, а лише правильна реалізація. Це єдина «правильність», яку ви можете довести. Що стосується багаторазових параметризованих процедур: так, я боюся, що потрібна комбінаторна кількість тестів ...
Kilian Foth

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