Написання автоматизованих тестів (Writing Automated Tests)
У своєму есе 1972 року “The Humble Programmer” Едсгер В. Дейкстра сказав, що “Тестування програм може бути дуже ефективним способом показати наявність помилок, але воно безнадійно недостатнє для показу їхньої відсутності.” (“program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence.”) Це не означає, що нам не слід намагатися тестувати якнайбільше!
Правильність у наших програмах — це міра того, наскільки наш код робить те, що ми маємо намір, щоб він робив. Rust розроблено з високим рівнем уваги до правильності програм, але правильність є складною і її не так легко довести. Система типів Rust бере на себе величезну частину цього тягаря, але система типів не може вловити все. Тому Rust включає підтримку для написання автоматизованих програмних тестів.
Припустімо, ми пишемо функцію add_two, яка додає 2 до будь-якого числа,
переданого їй. Сигнатура цієї функції приймає ціле число як параметр і
повертає ціле число як результат. Коли ми реалізуємо й компілюємо цю функцію,
Rust виконує всю перевірку типів і перевірку запозичень, яку ви вже вивчили,
щоб переконатися, що, наприклад, ми не передаємо цій функції значення String
або недійсне посилання. Але Rust не може перевірити, що ця функція робитиме
саме те, що ми маємо намір, а саме повертатиме параметр плюс 2, а не, скажімо,
параметр плюс 10 або параметр мінус 50! Саме тут і з’являються тести.
Ми можемо написати тести, які стверджують, наприклад, що коли ми передаємо 3
до функції add_two, то повернене значення є 5. Ми можемо запускати ці тести
кожного разу, коли вносимо зміни до нашого коду, щоб переконатися, що будь-яка
наявна правильна поведінка не змінилася.
Тестування — це складна навичка: хоча ми не можемо в одному розділі охопити всі деталі про те, як писати хороші тести, у цьому розділі ми обговоримо механіку засобів тестування Rust. Ми поговоримо про анотації та макроси, доступні вам під час написання ваших тестів, поведінку за замовчуванням і параметри, надані для запуску ваших тестів, а також про те, як організувати тести в модульні тести (unit tests) та інтеграційні тести (integration tests).