Перевірка вхідних даних підпрограм та тестування
Зміст
Розглянемо задачу: Описати процедуруMean(X, Y, AMean, GMean), що обчислює середнє арифметичнеAMean= (X+Y)/2 та середнє геометричнеGMean= (X·Y) 1/2 двох позитивних чиселXіY(XіY- вхідні,AMeanтаGMean- вихідні параметри речовинного типу) .
Зверніть увагу, що позитивність параметрів X та Y потрібна для обчислення середнього геометричного, яке відбувається всередині процедури Mean . Ніхто не гарантує, що на вхід до процедури будуть передаватися лише коректні вхідні дані, але правильна робота самої процедури — турбота розробника цієї процедури. Він повинен «убезпечити» себе від невірних вхідних даних, тому їх перевірка повинна знаходитися саме всередині процедури Mean.
Ми знаємо, як перевіряти вхідні дані: можна використовувати оператор Assert. Рекомендовано використовувати оператор Assert для кожного параметраокремо. Тобто в цьому прикладі має бути два оператори:
Тестування підпрограми за допомогою Assert
Принадність алгоритму, укладеного в підпрограмі, полягає в тому, що його легко викликати багаторазово з різними вхідними значеннями. Це дозволяє нам перейти до надійнішого способу тестування. Тепер ми можемо зашити в основну програму виклики підпрограми з необхідними тестовими значеннями.
Отже, нехай процедуру Mean написано. У неї два вхідні та два вихідні параметри. Значитькожний тестовий прикладповинен перевіряти, що при заданих значеннях X і Yобидва вихідні параметри мають очікувані значення. Тобто:
- потрібно встановити значення вхідних параметрів ( X, Y );
- викликати процедуру Mean , передавшиїй ці вхідні значення;
- перевірити, що значення вихідних параметрів ( AMean, GMean ) збігаються з очікуваними.
Спробуємо це запрограмувати. Почнемо з найпростішого прикладу: для X, Y X = Y мають бути отримані значення AMean = X, GMean = X.
Питання: як виконуватимемо перевірку (крок 3)? Згадаймо, що при вирішенні завдань з рядами ми вже перевірили правильність знайденого значення за допомогою оператора Assert . Як параметр потрібно передати логічний вираз, значення якого істинно, якщо рішення правильне. Нам потрібно перевірити, що AMean = X, GMean = X. Може бути так?
Математично це правильно, алеречовічисла так не порівнюють на рівність. А у нас якраз речові числа. Виправимо. Введемо деяку константу Eps (рівну, наприклад, значення 0.00000001), тоді перевірка буде виглядати так:
Порівнювати речові значення нам знадобиться неодноразово (принаймні потрібно написати ще кілька тестів). Це чудовий претендент на підпрограму. Для двох даних дійсних чисел нам потрібно знати, чи рівні вони чи ні. Отже підпрограма повинні мати принаймні два вхідні речові параметри і один вихідний — логічного типу (оскільки нам потрібна тільки відповідь так/ні). Вихідний параметр один, тож зручно використовувати функцію. Крім того, зручно передавати як вхідний параметр і точність порівняння, адже в різних завданнях може бути потрібна різна точність.
Тепер використовуємо цю функцію для перевірки роботи процедури Mean:
Таким чином, повний код для одного тестового прикладу виглядає так:
Додамо ще кілька тестових прикладів:
Зауваження.Зверніть увагу, що у двох останніх прикладах значення змінних x та y не використовуються.Оскільки цевхідніпараметри, можемо переписати код так:
Навіщо потрібне таке тестування?
Важливими перевагами таких «вшитих» тестів перед ручним тестуванням (яке ми робили раніше) є те, що ці тести: (a) виконуються автоматично та (b) виконуються завжди.
Ви написали тести один раз і більше не дбаєте про це. Якщо з якихось причин ви змінили підпрограму, запускати її вручну на всіх наборах тестових даних не потрібно, це буде виконано автоматично. І якщо після зміни раптом щось «зламалося», то під час запуску програми це буде одразу ж виявлено.
Перевірка правильності роботи підпрограми – окреме завдання, завдання тестування. Тому тестування також можна виділити в спеціальну підпрограму, щоб не засмічувати тестами основну програму. А в основну програму залишається тількивключити виклик підпрограми. Таким чином, повний код може виглядати так:
Тестування функцій
Перевірка коректності чистих функцій (у яких всі параметри є вхідними і немає побічних ефектів на кшталт друку на консоль) відбувається дещо простіше, оскільки виклик функції сам вираз, значення якого потрібно перевірити. Тому тестування функції intMin (мінімум двох цілих чисел) може бути таким:
Тестування предикатів
Предикат це окремий випадок функції, а саме, функція, що повертає значення типу boolean. Для їхнього тестування не потрібно навіть виконувати порівняння. Наведемо приклад для предикату перевірки цілого числа те що, що є двозначним. Зверніть увагу, що другим аргументом Assert зручно передавати повідомлення з текстом умови, що перевіряється, щоб при виникненні помилок відразу ставало зрозуміло, зяким значенням не впоралася функція, що перевіряється. Це зауваження стосується будь-яких Assert.