Тестування - Elixir School

Тестування – важлива частина розробки. В цьому уроці ми дізнаємося, як тестувати наш Elixir-код з використанням ExUnit, а також познайомимося з деякими відмінними прийомами.

Зміст

У Elixir є вбудований фреймворк для тестування ExUnit, який включає все необхідне для ретельного тестування нашого коду. Перед тим, як рухатися далі, варто відзначити, що тести реалізовані у вигляді скриптів Elixir, тому нам потрібно використовувати розширення .exs. Щоб виконувати тести, потрібно запустити ExUnit за допомогою виклику ExUnit.start() , зазвичай це робиться в test/test_helper.exs .

Коли ми згенерували приклад проекту минулого уроку, Mix зробив для нас тест, який можна знайти в test/example_test.exs :

Тести проекту можна запустити за допомогою команди mix test. Якщо ми виконаємо її, то побачимо приблизно таке:

Звідки у висновку з'явився другий тест? Погляньмо на lib/example.ex. Mix створив ще один тест для нас – doctest.

Якщо ви раніше писали тести, ви повинні бути знайомі з assert ; у деяких фреймворках роль assert виконують should або expect.

Макрос assert використовується, щоб перевірити, що вираз істинний. Якщо це не так, виникне помилка, а тести завершаться з помилкою. Давайте змінимо наш приклад і запустимо mix test, щоб протестувати помилку:

Зараз ми побачимо інший результат:

ExUnit покаже, яке саме твердження було помилковим, яке значення очікувалося і яке було отримано насправді.

Макрос refute відноситься до assert також, як unless до if . Використовуйте refute , якщо ви хочете переконатися, що вираз завжди є хибним.

assert_raise

Іноді необхідно перевірити, чи в коді виникла помилка. Це можнадселати за допомогою assert_raise. Ми зіткнемося з прикладом застосування assert_raise у наступному уроці Plug.

assert_receive

У Elixir програми складаються з процесів-акторів, які відправляють повідомлення один одному. Досить часто потрібно протестувати, що повідомлення надсилаються. Оскільки ExUnit працює у своєму процесі, він може отримувати повідомлення. Саме отримання повідомлень цим процесом можна перевірити за допомогою assert_received:

assert_received не чекає стандартних повідомлень, але можна вказати час очікування.

capture_io та capture_log

Отримання виводу програми можливе за допомогою ExUnit.CaptureIO без зміни коду програми. Просто передайте функцію, що генерує висновок як параметр:

ExUnit.CaptureLog - еквівалент відправки виведення програми в Logger.

Налаштування тесту

У деяких випадках перед тестами необхідно налаштувати. Зробити це можна з допомогою макросів setup і setup_all. Макрос setup викликається перед кожним тестом, а setup_all один раз перед усім набором. Очікується, що вони повернуть кортеж виду , state буде доступним для наших тестів.

Як приклад змінимо наш код і скористаємося setup_all :

Використання заглушок

Проста порада щодо використання заглушок в Elixir: не робіть цього. Можливо, за звичкою захочеться скористатися заглушкою (mock), але це вкрай не вітається спільнотою Elixir з вагомих причин.

Ця тема розкрита докладніше у чудовій статті. Суть у тому, що замість того, щоб підміняти методи для тестування, створюйте інтерфейси в коді поза програмою та використовуйте об'єкти-заглушки, які реалізовуватимуть цей інтерфейс у процесі тестування.

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

Caught a mistake або want to contribute to the lesson? Edit this page on GitHub!