Модульні тести. Вступ до RSpec
Ruby 🇺🇦Сьогодні у статті:
Модульні тести
Модульні тести (Unit tests) - це тести, які перевіряють коректність роботи окремих компонентів програми. Це найменша одиниця тестування, де окремі методи, класи або функції тестуються на правильність роботи зі сподіваними результатами. Це дозволяє виявляти помилки та дефекти на ранніх етапах розробки, зменшуючи вартість розробки та покращуючи якість коду.
У Ruby для написання модульних тестів найчастіше використовують фреймворк RSpec. Він дозволяє написати тести, які будуть відображатись як природна мова, що полегшує їх читання та зрозуміння.
Основні принципи модульних тестів в Ruby:
- Тести мають бути повністю автоматизовані, щоб вони могли бути запущені при кожній зміні в коді.
- Тести повинні бути незалежними один від одного. Кожен тест має перевіряти окрему функціональність, а не залежати від результатів інших тестів.
- Тести мають бути написані з розумінням тестованої функціональності. Тобто, розробник повинен знати, що очікується від кожної функції та який буде очікуваний результат.
- Тести мають бути читабельними та легкими для розуміння. Це дозволить іншим розробникам легко зрозуміти тестовий код та внести необхідні зміни.
Вступ до RSpec
У цій статті ми розглянемо, як створювати модульні тести в мові програмування Ruby з використанням бібліотеки RSpec.
Щоб почати, ми повинні встановити бібліотеку RSpec за допомогою менеджера пакетів Bundler. Створіть новий проект Ruby за допомогою команди:

Встановіть RSpec, додавши його до файлу Gemfile вашого проекту:

Після цього виконайте команду bundle install, щоб встановити бібліотеку.
Розглянемо приклад тестування методу, який додає два числа. Створіть новий файл calculator.rb та додайте наступний код:

Цей клас містить метод add, який приймає два числа і повертає їх суму.
Тепер створимо тест для цього методу. Створіть новий файл calculator_spec.rb та додайте наступний код:

Цей тест перевіряє, чи повертає метод add вірну суму двох чисел. Метод describe визначає, що ми тестуємо клас Calculator. Метод it визначає конкретний тест, який перевіряє поведінку методу add. Останній рядок перевіряє, чи повертає метод add вірну суму двох чисел.
Запустіть тест за допомогою команди:

Ви повинні побачити результат виконання тесту у вашій консолі. Якщо все вірно, то ви повинні побачити повідомлення про те, що 1 приклад пройшов успішно:

Тепер, давайте добавимо ще один тест до нашого файлу calculator_spec.rb:

Доданий тест перевіряє, що коли один з аргументів методу add є nil, то генерується помилка TypeError.
Для цього використовується метод expect з бібліотеки RSpec. Він очікує, що при виклику методу calculator.add з аргументами -2 та nil буде згенерована помилка TypeError, інакше тест буде проваленим.
Запустимо тест за допомогою команди rspec calculator_spec.rb:

Ми бачимо, що обидва тести були виконані успішно.
Модульні тести можуть допомогти забезпечити правильну роботу вашого коду та виявити проблеми, які можуть виникнути в результаті змін у вашому коді. Рекомендується написання тестів на кожен метод, клас або модуль у вашому програмному коді. Таким чином, ви зможете переконатися, що ваш код працює правильно, та запобігти появі помилок. RSpec надає читабельну та докладну інформацію про те, що тестується і де саме була виявлена помилка.
Let
Давайте розглянемо приклад з використанням функції let. Перепишемо наш попередній тест для додавання з використанням цієї функції:

У цьому тесті ми використовуємо функцію let для створення нового об'єкту Calculator перед кожним тестом. Це дозволяє нам зменшити повторення коду та скоротити час виконання тестів, оскільки ми не створюємо новий об'єкт Calculator кожного разу вручну.
Функція let приймає блок коду, який повинен повернути значення для змінної, що називається за ім'ям блоку. У нашому випадку, ми створюємо змінну calculator за допомогою функції let, яка повертає новий об'єкт Calculator.
Також можна використовувати before та after функції, які дозволяють виконувати певний код перед тестом або після нього. Наприклад:

У цьому прикладі ми використовуємо before та after функції, щоб додати вивід "Starting test" перед кожним тестом та "Test complete" після кожного тесту.
Shared example
Також можна використовувати shared_examples та shared_context для спільного використання коду між різними тестами. shared_examples дозволяє використовувати один блок коду у багатьох тестах, тоді як shared_context дозволяє використовувати однакові об'єкти та методи в багатьох тестах.
Наприклад, використаємо shared_examples для перевірки правильності виконання арифметичних операцій. Спочатку визначимо блок коду, який буде використовуватись у різних тестах:

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

У цьому прикладі ми використовуємо include_examples для підключення блоку коду arithmetic operation у різних блоках describe. Кожен раз, коли ми передаємо параметри до блоку include_examples, RSpec виконує тест з використанням цих параметрів.
Також можна використовувати shared_context для створення спільних об'єктів та методів, які використовуються в декількох тестах. Наприклад, у нашому прикладі з калькулятором ми можемо використовувати shared_context для створення калькулятора, який буде використовуватись в кожному тесті.

У цьому прикладі ми використовуємо shared_context "calculator", щоб створити змінну calculator, яку ми використовуємо в кожному тесті. Це дозволяє нам уникнути дублювання коду та зробити тестування більш організованим та легким для розуміння.
Висновок
У цілому, модульне тестування дозволяє перевірити коректність роботи окремих частин програми та допомагає виявити та виправити помилки до того, як вони стануть проблемою в продакшні. RSpec дозволяє зручно та чітко писати тести в Ruby, додатково забезпечуючи зрозумілі повідомлення про помилки та розширені можливості для організації тестів.
Ось кілька джерел про модульні тести та RSpec:
- Офіційна документація RSpec: https://rspec.info/documentation/
- "Everyday Rails Testing with RSpec" - книга містить багато практичних прикладів тестування на RSpec: https://leanpub.com/everydayrailsrspec
- "Better Specs" - сайт з кращими практиками тестування за допомогою RSpec: https://www.betterspecs.org/
- "RSpec Best Practices" - стаття з кращими практиками використання RSpec: https://dev.to/bambangsinaga/rspec-best-practice-26k5
Ці ресурси допоможуть початківцям та досвідченим програмістам поглибити свої знання про модульне тестування та RSpec
Сьогоднішній урок файлом - лінк.
Чат для спілкування - лінк.
Канал - лінк.