Pre-built assertion helpers for common Elixir coding conventions.
Import this module (via use ArchTest.Conventions) to access pre-built
rules that go beyond dependency checking.
Usage
defmodule MyApp.ConventionTest do
use ExUnit.Case
use ArchTest
use ArchTest.Conventions
test "no IO.puts in production code" do
assert no_io_puts_in(modules_matching("MyApp.**"))
end
test "domain modules don't use Plug" do
assert no_plug_in(modules_matching("MyApp.Domain.**"))
end
end
Summary
Functions
Asserts that all public functions in subject modules have documentation.
Asserts that no module in subject calls Application.get_env/2,3 directly.
Asserts that no module in subject calls dbg/0,1,2 (Elixir 1.14+ debug macro).
Asserts that no module in subject has IO.puts or IO.inspect calls.
Asserts that no module in subject directly uses Plug.
Asserts that no module in subject calls Process.sleep/1.
Asserts that no module in subject raises a bare string (i.e., raise "message").
Functions
@spec all_public_functions_documented( ArchTest.ModuleSet.t(), keyword() ) :: :ok
Asserts that all public functions in subject modules have documentation.
A public function is considered documented if its module has a @moduledoc
and none of its functions are missing @doc (i.e., @doc false or missing
docs are both treated as undocumented).
This check inspects :beam_lib chunk data.
@spec no_application_get_env_in( ArchTest.ModuleSet.t(), keyword() ) :: :ok
Asserts that no module in subject calls Application.get_env/2,3 directly.
Direct Application.get_env calls scattered across the codebase make
configuration harder to find and test. Centralize config access in a
dedicated config module.
@spec no_dbg_in( ArchTest.ModuleSet.t(), keyword() ) :: :ok
Asserts that no module in subject calls dbg/0,1,2 (Elixir 1.14+ debug macro).
dbg calls are debugging artifacts that must not appear in production code.
@spec no_io_puts_in( ArchTest.ModuleSet.t(), keyword() ) :: :ok
Asserts that no module in subject has IO.puts or IO.inspect calls.
These are debugging artifacts that should not appear in production modules.
@spec no_plug_in( ArchTest.ModuleSet.t(), keyword() ) :: :ok
Asserts that no module in subject directly uses Plug.
Useful to keep domain/application modules free from web framework coupling.
@spec no_process_sleep_in( ArchTest.ModuleSet.t(), keyword() ) :: :ok
Asserts that no module in subject calls Process.sleep/1.
Process.sleep in production code is a code smell — it indicates polling,
artificial delays, or race condition workarounds. Use proper synchronization
mechanisms instead.
@spec no_raise_string_in( ArchTest.ModuleSet.t(), keyword() ) :: :ok
Asserts that no module in subject raises a bare string (i.e., raise "message").
Bare string raises produce RuntimeError with no structured data. Use typed
errors (defexception) or raise MyError, key: value instead for better
error handling and pattern matching.