Bootstrap

Зачем нужен mix и как он работает

Зачем нужен <code>mix</code> и как он работает

Часть 1: Зачем нужен mix и как он работает?

Что такое mix?

mix — это инструмент сборки и управления проектами в экосистеме Elixir (аналог npm в Node.js, cargo в Rust, lein в Clojure).

Он входит в поставку Elixir и отвечает за:

ФункцияОписание
Создание проектовmix new my_app — генерирует структуру проекта
⚙️ Зависимостиmix deps.get, mix deps.compile — управление библиотеками из Hex
Тестированиеmix test — запуск тестов через ExUnit
Компиляцияmix compile — компиляция .ex.beam
ЗадачиСоздание собственных задач (mix run, mix phx.server, etc.)
Конфигурацияconfig/, mix.exs — центр управления проектом

Как создаётся проект с помощью mix?

1. Создание нового проекта

Terminal:

mix new my_app --sup

Флаг --sup добавляет супервизор (полезно для OTP-приложений, но можно и без него).

2. Сгенерированная структура:

Terminal:

my_app/
├── config/
│   └── config.exs           # настройки проекта
├── lib/
│   └── my_app.ex            # основной модуль
│   └── my_app/              # (если указать --module MyApp.Submodule — создаются подкаталоги)
├── test/
│   ├── test_helper.exs      # загрузка ExUnit и setup
│   └── my_app_test.exs      # пример теста
├── .formatter.exs           # правила форматирования
├── mix.exs                  # ✅ главный конфиг проекта (зависимости, приложения, версия)
└── README.md

3. Файл `mix.exs` — "сердце проекта":

Terminal:

defmodule MyApp.MixProject do
  use Mix.Project

  def project do
    [
      app: :my_app,
      version: "0.1.0",
      elixir: "~> 1.14",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Зависимости
  defp deps do
    [
      # {:plug, "~> 1.14"}
    ]
  end
end

4. Файл `test/test_helper.exs`:

Terminal:

ExUnit.start()  # <-- обязательная инициализация тестового фреймворка

5. Пример теста (`test/my_app_test.exs`):

Terminal:

defmodule MyAppTest do
  use ExUnit.Case
  doctest MyApp

  test "greets the world" do
    assert MyApp.hello() == :world
  end
end

use ExUnit.Case подключает макросы test, assert, refute, setup и др.

6. Запуск тестов:

Terminal:

# Все тесты
mix test

# Один файл
mix test test/my_app_test.exs

# Один конкретный тест (по строке)
mix test test/my_app_test.exs:5

# С подробным логом
mix test --trace

# С покрытием (coverage)
mix test --cover

Часть 2: Как создать проект *без* mix?

Да, можно — но это ручной, low-level способ, как писать на "голом" Elixir. Чаще используется для:

  • скриптов,
  • обучения,
  • мини-экспериментов,
  • embedded-сценариев (например, в Nerves).

Шаг 1: Создайте структуру вручную

Terminal:

mkdir my_script && cd my_script
mkdir -p lib test
touch lib/math.ex test/math_test.exs

Структура:

Terminal:

my_script/
├── lib/
│   └── math.ex
└── test/
    └── math_test.exs

Шаг 2: Напишите модуль (`lib/math.ex`)

Terminal:

defmodule Math do
  def add(a, b), do: a + b
  def multiply(a, b), do: a * b
end

Шаг 3: Напишите тест (`test/math_test.exs`)

⚠️ ВАЖНО: без mix нет автоматической загрузки test_helper.exs, поэтому нужно вручную инициализировать ExUnit:

Terminal:

# test/math_test.exs
ExUnit.start()  # ← обязателен при запуске вручную!

defmodule MathTest do
  use ExUnit.Case

  test "add/2 works" do
    assert Math.add(2, 3) == 5
  end

  test "multiply/2 works" do
    assert Math.multiply(4, 5) == 20
  end
end

> ❗ Обратите внимание:

> - Это файл .exs (script), а не .ex — он компилируется при каждом запуске, а не кэшируется.

> - ExUnit.start() должен быть выполнен до определения тестов.

Шаг 4: Запуск тестов *без mix*

Terminal:

# Запускаем напрямую через `elixir`, указывая пути к коду
elixir -r lib/math.ex -r test/math_test.exs

✅ Вывод:

Terminal:

..

Finished in 0.03 seconds
2 tests, 0 failures

> ⚠️ Минусы такого подхода:

> - Нет автоматического поиска всех тестов в папке.

> - Нужно вручную указывать каждый файл через -r.

> - Нет удобных флагов (--trace, --cover, фильтрация по тегам и т.д.).

> - Нет поддержки зависимостей (deps), конфигов, сборки релизов и т.п.


Часть 3: Можно ли писать тесты *внутри модулей*?

Да, технически можно, но это не рекомендуется согласно best practices (тесты должны быть отделены от production-кода), но для демонстрации — вот как:

✅ Способ: тесты внутри `.exs` (скрипта), но *возле* модуля

Создайте файл math_with_tests.exs:

Terminal:

# math_with_tests.exs

defmodule Math do
  def add(a, b), do: a + b
end

# ↓ Тесты прямо в том же файле (но это .exs!)
ExUnit.start(auto_run: false)  # отключаем автозапуск

defmodule MathTest do
  use ExUnit.Case, async: false

  test "add/2" do
    assert Math.add(1, 2) == 3
  end
end

# Явно запускаем тесты в конце
ExUnit.run()

Запуск:

Terminal:

elixir math_with_tests.exs

✅ Работает!


❌ Почему так делать **не стоит**:

ПроблемаОбъяснение
Загрязнение кодаProduction-код и тесты в одном месте — нарушает разделение ответственности
ПроизводительностьТесты могут замедлять компиляцию/запуск основного приложения
Нет CI-интеграцииИнструменты вроде GitHub Actions ожидают mix test
Зависимости:ex_unit — только для :test, в production он не нужен (only: :test в mix.exs)
СтруктураНарушается стандартная структура lib/ и test/, которую ожидают все инструменты

> ✅ Правильный путь:

> - Код — в lib/.ex

> - Тесты — в test/.exs, с use ExUnit.Case

> - Запуск — через mix test


Краткое резюме

ВопросОтвет
Что такое mix?Система сборки и управления проектами в Elixir — обязательный инструмент для реальных проектов.
Как создать проект?mix new имя_проекта [--sup] → создаёт mix.exs, lib/, test/, config/.
Как запустить тесты?mix test → находит всё в test/, запускает через ExUnit.
Можно ли без mix?Да, но вручную: elixir -r lib/mod.ex -r test/mod_test.exs, с ExUnit.start() в коде.
Тесты внутри модуля?Технически — да (в .exs), но не следует так делать в production-коде.

Копирование материалов разрешается только с указанием автора Roman Sakhno и индексируемой прямой ссылкой на сайт (http://itdid.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/sahroman.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/sahroman.

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как настроить свой компьютер

  2. Текстовая ссылка:

    Она выглядит вот так: Как настроить свой компьютер

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.

крипто-донат, на развитие сайта itdid.ru:

В новом окне с терминалом itdid.ru, введите любую сумму: