testing

Elixir Testing Reference

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "testing" with this command: npx skills add oliver-kriska/claude-elixir-phoenix/oliver-kriska-claude-elixir-phoenix-testing

Elixir Testing Reference

Quick reference for Elixir testing patterns.

Iron Laws — Never Violate These

  • ASYNC BY DEFAULT — Use async: true unless tests modify global state

  • SANDBOX ISOLATION — All database tests use Ecto.Adapters.SQL.Sandbox

  • MOCK ONLY AT BOUNDARIES — Never mock database, internal modules, or stdlib

  • BEHAVIOURS AS CONTRACTS — All mocks must implement a defined @callback behaviour

  • BUILD BY DEFAULT — Use build/2 in factories; insert/2 only when DB needed

  • NO PROCESS.SLEEP — Use assert_receive with timeout for async operations

  • VERIFY_ON_EXIT! — Always call in Mox tests setup

  • FACTORIES MATCH SCHEMA REQUIRED FIELDS — Factory definitions must include all fields that have validate_required in the schema changeset. Missing fields cause cascading test failures

Quick Decisions

Which Test Case?

Testing Use

Controller/API use MyAppWeb.ConnCase

Context/Schema use MyApp.DataCase

LiveView use MyAppWeb.ConnCase

  • import Phoenix.LiveViewTest

Pure logic use ExUnit.Case, async: true

When to use async: true?

  • ✅ Pure functions, no shared state

  • ✅ Database tests with Sandbox (PostgreSQL)

  • ❌ Tests modifying Application.put_env

  • ❌ Tests using Mox global mode

Mock or not?

  • ✅ Mock: External APIs, email services, file storage

  • ❌ Don't mock: Database, internal modules, stdlib

build() or insert()?

  • Use build() by default for speed

  • Use insert() only when you need DB ID, constraints, or persisted associations

Quick Patterns

Setup chain

setup [:create_user, :authenticate]

Pattern matching assertion

assert {:ok, %User{name: name}} = create_user(attrs)

Async message assertion

assert_receive {:user_created, _}, 5000

Mox setup

setup :verify_on_exit! expect(MockAPI, :call, fn _ -> {:ok, "data"} end)

LiveView async

html = render_async(view) # MUST call for assign_async

Common Anti-patterns

Wrong Right

Process.sleep(100)

assert_receive {:done, _}, 5000

insert(:user) in factory build(:user) in factory

async: true with set_mox_global()

async: false

Mock internal modules Test through public API

References

For detailed patterns, see:

  • references/exunit-patterns.md

  • Setup, assertions, tags

  • references/mox-patterns.md

  • Behaviours, expect/stub, async

  • references/liveview-testing.md

  • Forms, async, uploads

  • references/factory-patterns.md

  • ExMachina, sequences, traits

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

oban

No summary provided by upstream source.

Repository SourceNeeds Review
General

ecto-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

phx:full

No summary provided by upstream source.

Repository SourceNeeds Review