testing について
testing は Elixir プロジェクト向けのテスト早見スキルで、テストケースの選択、非同期処理、データベース分離、モック、ファクトリーを扱います。ExUnit、Mox、LiveView の実践的な規則とパターンをまとめています。
主な機能
- 01テスト種別に応じたケース選択
- 02非同期処理と Sandbox の指針
- 03モック利用範囲の明確化
- 04build と insert の使い分け
- 05ExUnit、Mox、LiveView のパターン参照
活用シーン
- 01コントローラーやコンテキストのテスト設定
- 02LiveView の動作テスト
- 03sleep を使わない非同期メッセージ処理
- 04ファクトリーでレコードを永続化するか判断
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ oliver-kriska/ claude-elixir-phoenix --skill testingインストール後、Claude Code で/testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/exunit-patterns.mdfactory-patterns.mdliveview-testing.mdmox-patterns.md詳細
Elixir テストリファレンス
Ash プロジェクト:
DataCaseとAsh.Testヘルパーを使用し、アクションはRepoを直接呼び出すのではなく、ドメインのコードインターフェースを介してテストしてください。ash-frameworkスキルを参照してください。
Elixir のテストパターンのクイックリファレンスです。
鉄則 — 決して破らないでください
- デフォルトは非同期 — テストがグローバル状態を変更する場合を除き、
async: trueを使用します - サンドボックスによる分離 — すべてのデータベーステストで Ecto.Adapters.SQL.Sandbox を使用します
- 境界でのみモックする — データベース、内部モジュール、標準ライブラリは決してモックしません
- コントラクトとしてのビヘイビアー — すべてのモックは、定義済みの
@callbackビヘイビアーを実装する必要があります - デフォルトは build — ファクトリーでは
build/2を使用し、DB が必要な場合にのみinsert/2を使用します - Process.sleep は禁止 — 非同期操作にはタイムアウト付きの
assert_receiveを使用します - VERIFY_ON_EXIT! — Mox のテストセットアップでは必ず呼び出します
- ファクトリーにはスキーマの必須フィールドを含める — ファクトリー定義には、スキーマの changeset で
validate_requiredが指定されたすべてのフィールドを含める必要があります。フィールドが不足すると、テストで連鎖的な失敗が発生します
すぐに確認できる判断基準
どのテストケースを使うか?
| テスト対象 | 使用するもの |
|---|---|
| コントローラー/API | use MyAppWeb.ConnCase |
| コンテキスト/スキーマ | use MyApp.DataCase |
| LiveView | use MyAppWeb.ConnCase + import Phoenix.LiveViewTest |
| 純粋なロジック | use ExUnit.Case, async: true |
async: true を使うタイミングは?
- ✅ 純粋関数、共有状態なし
- ✅ Sandbox を使うデータベーステスト(PostgreSQL)
- ❌
Application.put_envを変更するテスト - ❌ Mox のグローバルモードを使うテスト
モックするかどうか?
- ✅ モックする:外部 API、メールサービス、ファイルストレージ
- ❌ モックしない:データベース、内部モジュール、標準ライブラリ
build() と insert() のどちらを使うか?
- 速度を優先し、デフォルトでは
build()を使用します - DB ID、制約、または永続化された関連データが必要な場合にのみ
insert()を使用します
よく使うパターン
# 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
よくあるアンチパターン
| 誤り | 正しい方法 |
|---|---|
Process.sleep(100) | assert_receive {:done, _}, 5000 |
ファクトリー内の insert(:user) | ファクトリー内の build(:user) |
set_mox_global() と async: true の併用 | async: false |
| 内部モジュールをモックする | 公開 API を通じてテストする |
リファレンス
詳しいパターンについては、以下を参照してください。
${CLAUDE_SKILL_DIR}/references/exunit-patterns.md- セットアップ、アサーション、タグ${CLAUDE_SKILL_DIR}/references/mox-patterns.md- ビヘイビアー、expect/stub、非同期${CLAUDE_SKILL_DIR}/references/liveview-testing.md- フォーム、非同期、アップロード${CLAUDE_SKILL_DIR}/references/factory-patterns.md- ExMachina、シーケンス、特性
コメント
Markdown 対応