Assert. Що це?
Assert'и можна розділити на такі класи:
- Перевірка вхідних аргументів на початку функції.
Важливо розуміти, що аргументи функції можуть бути неявними. Наприклад, при виклику методу класу на функцію неявно передається покажчик на об'єкт даного класу (aka this і self). Також функція може звертатися до даних, оголошених у глобальній області видимості, або даних з області видимості лексичного замикання. Ці аргументи теж бажано перевіряти за допомогою assert'ів при вході в функцію. Якщо некоректні дані виявлені на цьому етапі, то код даної функції може містити баги. Приклад:
Що таке арифметика з довільною точністю. Результат функції може бути неявним. Наприклад, функція може модифікувати дані, на які посилаються (прямо чи опосередковано) аргументи функції. Також функція може модифікувати дані з глобальної області видимості або області видимості лексичного замикання. Коректність цих даних бажано перевіряти перед виходом із функції.
- Перевірка даних, із якими працює функція, всередині коду функції.
Коли не можна використовувати assert'и? Т.к. assert'и можуть бути видалені на етапі компіляції або під час виконання програми, вони не повинні змінювати поведінку програми. Якщо в результаті видалення assert'а поведінка програми може змінитися, то це явна ознака неправильного використання assert'а. Таким чином,всередині assert'а не можна викликати функції, що змінюють стан програми або зовнішнього оточення програми. Наприклад, наступний код неправильно використовує assert'и:
Очевидно, що дані можуть виявитися незахищеними при відключених assert'ах. Щоб виправити цю помилку, потрібно зберігати результат виконання функції в часовій змінній, після чого використовувати цю змінну всередині assert'а
Т.к. основне призначення assert'ів - відлов багів (aka помилки програмування), то вони не можуть замінити обробку очікуваних помилок, які не є помилками програмування. Наприклад:
Якщо write() повертає 0, це зовсім не означає, що в нашій програмі є баг. Якщо assert'и в програмі будуть відключені, то помилка запису може залишитися непоміченою, що може призвести до сумних результатів. Тому assert() тут не підходить. Тут краще підходить нормальна обробка помилки. Наприклад:
Я програмую на JavaScript. У ньому немає assert'ів. Що мені робити? У деяких мовах програмування відсутня явна підтримка assert'ів. За бажання вони легко можуть бути там реалізовані, дотримуючись наступного «патерну проектування»:
Взагалі, assert'и зазвичай реалізовані у різних фреймворках та бібліотеках, призначених для автоматизованого тестування. Іноді вони там називаються expect'ами. Між автоматизованим тестуванням та застосуванням assert'ів є багато спільного – обидві техніки призначені для швидкого виявлення та виправлення багів у програмах. Але, незважаючи на загальні риси, автоматизоване тестування та assert'и є не взаємовиключними, а, швидше за все, взаємодоповнюють один одного. Грамотно розставлені assert'и полегшують автоматизоване тестування коду, т.к. тестуюча програма може опуститиперевірки, що дублюють assert'и в коді програми. Такі перевірки зазвичай становлять суттєву частку всіх перевірок у програмі, що тестує.