Дізнаймося, як тестувати вправи з Elixir на Exercism
У терміналі перейдімо до базової теки вправи, а потім виконаймо тести за допомогою:
$ mix test
Це виконає файл тестів із підтеки test, тобто файл, назва якого закінчується на _test.exs.
У наборах тестів практичних вправ усі тести, крім першого, позначені як пропущені.
Коли тест почне проходити, ми можемо увімкнути наступний, закоментувавши відповідний @tag :pending символом #.
Наприклад:
# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
Якщо ми хочемо запустити всі тести одразу, можна включити всі пропущені тести за допомогою прапорця --include у команді mix test:
$ mix test --include pending
Або можна увімкнути всі тести, закоментувавши рядок
ExUnit.configure у наборі тестів.
# ExUnit.configure exclude: :pending, trace: true
ExUnit і mix test пропонують чимало способів групування, тегування й виконання
тестів, а також різні способи керування виконанням тестів; більшість із них підсумовано
нижче.
Документація:
Усі тести з одного файлу можна виконати за допомогою mix test, указавши цей файл:
$ mix test test/<FILE>.exs
ПРИМІТКА:
taggingможе впливати на те, які тести насправді виконаються в цей спосіб.
Окремі тести можна виконати, указавши номер рядка тесту у файлі:
$ mix test test/<FILE>.exs:LINENUM
Кілька тестів можна виконати, указавши кілька номерів рядків, розділених :.
Наприклад, для файлу з таким вмістом і номерами рядків:
test "Test 1" do # 1
# test implementation # 2-6
end # 7
# 8
test "Test 2" do # 9
# test implementation # 10-21
end # 22
# 23
test "Test 3" do # 24
# test implementation # 25-35
end # 36
Перший і третій тести можна виконати так:
$ mix test test/FILE.exs:1:24
ПРИМІТКА: коли тести вказують через номери рядків,
taggingігнорується.
Тести можна групувати за допомогою describe:
describe "short test group description" do
test "test description" do
# test implementation
end
test "another test description" do
# test implementation
end
end
Усі тести з групи можна виконати, указавши номер її рядка у файлі, так само, як ми вказуємо та виконуємо окремі тести.
Документація:
mix test
--include і --exclude - запускають або не запускають конкретні тести залежно від їхніх @tag
--failed - запускає лише ті тести, які не пройшли минулого разу--max-failures - набір тестів перестає виконувати тести, коли досягнуто цієї кількості невдач--seed - задає початкове значення генератора випадкових чисел, який перемішує порядок тестів.
--seed 0 вимикає перемішування, тож тести в одному файлі завжди виконуватимуться
в тому порядку, у якому їх визначено--stale - запускає лише ті тести, які посилаються на модулі, що змінилися відтоді,
як тести востаннє запускали з --stale
--only task_id:1 - або з іншим номером: у навчальних вправах запускає лише тести, повʼязані з конкретним завданнямДокументація:
Вправи з Elixir містять файл-заготовку з реалізацією в підтеці lib. Цей файл
окреслює модуль і функції, які нам належить реалізувати. У більшості вправ ми
знайдемо типоспецифікації над оголошенням функції. Вони починаються з тегу @spec і
зазвичай мають формат @spec function_name(type1, type2) :: return_type.
Їх використовують в Elixir та Erlang як документацію і
разом з інструментом Dialyzer, щоб знаходити невідповідності типів
і можливі помилки. Докладніше див. документацію про типоспецифікації. Про
Dialyzer див. Erlang -- dialyzer.
За бажанням можна перевірити
типи своєї реалізації за допомогою Dialyzer. Для цього потрібно зробити кілька
кроків. Щоб це зробити, треба додати залежність Dialyxir
у файл mix.exs своєї вправи.
defp deps do
# Add this:
[{:dialyxir, "~> 0.4", only: [:dev]}]
end
Потім скористаймося завданнями mix, щоб завантажити й скомпілювати їх із командного рядка:
$ mix deps.get
...
$ mix deps.compile
...
Якщо ми запускаємо Dialyzer уперше,
файлу plt, найімовірніше, ще не буде. Постійна таблиця пошуку,
або PLT, використовується Dialyzer для кешування інформації про вбудовані
типи Elixir та Erlang. Щоб створити plt із прийнятними типовими значеннями, виконаймо:
$ mix dialyzer --plt
Нарешті, його можна запустити так:
$ mix dialyzer
Обовʼязково замінімо шлях на шлях до бібліотек Elixir у нашій системі. Наприклад,
якщо ми встановили Elixir через homebrew, то, найімовірніше, знайдемо його за шляхом
/usr/local/Cellar/elixir/1.3.2.
Повторимо ще раз: запуск Dialyzer і виправлення всіх попереджень - необовʼязковий
крок під час виконання вправи. Попередження Dialyzer буває
важко розшифрувати. Наприклад, погляньмо на попередження для цієї вкрай безглуздої
реалізації вправи Bob.
defmodule Bob do
@spec hey(input :: String.t()) :: String.t()
def hey(input) do
1
end
def hey(input) do
end
end
Це дає такі попередження.
bob.exs:2: Invalid type specification for function 'Elixir.Bob':hey/1. The success typing is (_) -> 1
bob.exs:7: The variable _input@1 can never match since previous clauses completely covered the type any()
Перше попередження означає, що функція повертає не той тип. Останнє вказує на те, що до другого визначення функції ніколи не дійде черга, бо перше визначення функції завжди збігається.