Сопровождение приложений на Elixir

В процессе создания кода будет не лишним подумать о том, каково придётся читающему его человеку, будь то другой разработчик или вы сами. Будь то завтра или через полгода.

Участники сообщества Elixir/Erlang написали множество различных инструментов для улучшения читабельности кода и удобства его сопровождения. В данной статье мы рассмотрим четыре основных инструмента для этого и обсудим каждый из.

Прежде чем перейти к обсуждению инструментов, оставлю небольшую заметку. Я возлагаю большие надежды на технику разработки через тестирование и полное покрытие кода. ExUnit — замечательный инструмент для создания быстро работающих юнит-тестов на Elixir, а все перечисленные ниже инструменты следует использовать при выполнении условия полного покрытия кода.

Почему мне можно доверять?

Недавно с моей командой разработчиков мы закончили работу над проектом по созданию API на Elixir, где одной из основных целей было обеспечение удобного сопровождения. Ниже приведены инструменты, которые мы использовали для достижения этой цели.

ExDoc

Github / Hex

С помощью данного инструмента была сгенерирована официальная документация Elixir, а также документация к пакетам на ресурсе Hex, наиболее популярном менеджере пакетов для экосистемы Elixir/Erlang. Его главная задача — сделать процесс создания документации как можно более простым, и я считаю, что он прекрасно с этим справляется.

Добавление инструмента в проект

Поместите в файл mix.exs следующий код:

def deps do
  {:ex_doc, "~> 0.13", only: :dev}
end

Более подробные инструкции по установке и настройке инструмента можно найти на странице Github.

Создание документации

Инструмент ExDoc создаёт при запуске «скелет» документации, состоящий из модулей проекта, который просто нужно заполнить необходимой информацией.

Это делается путём добавления атрибутов в модули. Например:

defmodule MyProject.Response do
  @moduledoc """
  This module will respond to a greeting.
  """
end

Из примера видно, что для добавления документации на уровне модуля используется атрибут @moduledoc.

Добавить документацию для отдельной функции можно с помощью атрибута @doc. Если использовать этот атрибут с функциями, повторно определёнными через сопоставления с образцом, документация будет выглядеть неаккуратно. Чтобы этого избежать, можно определить функцию с пустым телом и добавить для неё атрибут @doc. Например:

defmodule MyAnimals.Sound do

  @doc """
  Recognises an animal given its sound.
  """
  def recognise(sound)

  def recognise("oink") do
    :pig
  end

  def recognise("moo") do
    :cow
  end
end

Помимо добавления документации в проект, ExDoc может похвастаться такой волшебной возможностью, как DocTest. Она позволяет проводить юнит-тестирование функции на примерах её использования, которые вы описываете внутри документации. Рассмотрим такой пример:

defmodule MyMaths.Basic do

  @doc """
  This function will add two numbers together.

  ## Examples

      iex> MyMaths.Basic.add(3, 4)
      7

  """
  def add(num_one, num_two) do
    num_one + num_two
  end
end

defmodule MyMaths.BasicTest do
  use ExUnit.Case, async: true
  doctest MyModule
end

Из примера видно, что команда iex> присутствует в атрибуте @doc в качестве примера использования функции. Затем в соответствующем тест-файле с помощью макроса doctest проводится тестирование вышеописанных примеров.

Основная задача DocTest — сделать документацию достоверной, убедившись, что приведённые в ней примеры актуальны и безошибочны. Но это совершенно не значит, что такая проверка может заменить юнит-тесты. Справедливо и обратное: если юнит-тест пройден, это не значит, что в документации содержатся рабочие примеры.

Подробную информацию о процессе создания документации можно найти на официальном сайте Elixir.

Генерация документации

В корневом каталоге проекта нужно запустить mix docs, после чего документация станет доступна в файле doc/index.html.

Чтобы узнать о других доступных действиях, запустите mix help docs.

Dialyzer / Dialyxir

Github / Hex

Ещё один атрибут — @spec — позволяет задавать типы входных и выходных данных функции. Он добавляется на созданные с помощью ExDoc страницы, помогая пользователю разобраться в нюансах использования функции. Например:

@spec multiply(integer, integer) :: integer
def multiply(a, b) do
  a * b
end

Подробную информацию о типах данных и спецификациях можно найти на официальном сайте Elixir.

Но как проверить корректность объявленных типов? Здесь-то нам и пригодится Dialyxir, работающий на базе инструмента Dialyzer.

Добавление инструмента в проект

Поместите в файл mix.exs следующий код:

defp deps do
  [{:dialyxir, "~> 0.3", only: :dev}]
end

Запуск анализа

Перед первым использованием Dialyxir придётся сначала запустить файл mix dialyzer.plt. Это займёт достаточно много времени, но зато последующие запуски будут осуществляться быстрее.

После этого запустите инструмент с помощью mix dialyzer. К сожалению, отчёт Dialyzer далёк от идеала, но как бы то ни было, польза от него всё-таки есть. Подсказка: если требуется найти результат анализа какого-то определённого файла, можно передать результат работы в grep.

Credo

Github / Hex

Credo — инструмент для анализа кода, особое внимание в котором уделяется согласованности кода внутри кодовой базы. Он покажет, правильно ли вы расставили пробелы и табуляцию, выполнили ли вы действия из списка TODO, не содержат ли функции слишком много аргументов и многое другое.

Инструмент выделяет все найденные неточности, что упрощает процесс исправления ошибок.

Добавление инструмента в проект

Поместите в файл mix.exs следующий код:

def deps do
  {:credo, "~> 0.4", only: [:dev, :test]}
end

Более подробные инструкции по установке инструмента можно найти на странице Github.

Конфигурация

Credo можно настроить таким образом, чтобы при анализе включались/исключались определённые директории или проверки и даже создавались отдельные профили.

Конфигурации хранятся в файле .credo.exs, который находится либо в корневом каталоге проекта, либо в папке config/. Пример файла конфигураций.

Запуск анализа

Находясь в корневой директории проекта, выполните команду mix credo. Советую сделать это, указав аргумент --strict, тогда результаты будут более полными.

ExCoveralls

Github / Hex

ExCoveralls — инструмент для анализа покрытия кода в проекте. Он способен выводить отчёт в командную строку и работать с такими инструментами непрерывной интеграции, как Travis CI или Gitlab CI.

Очень удобно копаться в отчётах с помощью бесплатного для публичных репозиториев сервиса coveralls.io.

Добавление инструмента в проект

Поместите в файл mix.exs следующий код:

def project do
  [...
   test_coverage: [tool: ExCoveralls],
   preferred_cli_env: ["coveralls": :test]]
end

defp deps do
  [{:excoveralls, "~> 0.5", only: :test}]
end

Запуск анализа

Запустите файл mix coveralls, находящийся в корневом каталоге проекта.

Заключение

Надеюсь, данная статья поможет вам в изучении инструментов для обеспечения более высокой надёжности эксплуатации кода. Также обратите особое внимание на ссылки в тексте, если вы хотели бы узнать все подробности об использовании описанных выше инструментов.

© 2020 / Россия Любые мысли и вопросы пишите на elixir@wunsh.ru.