Elixir测试模式参考Skill testing

这是一个关于Elixir编程语言测试技能的参考指南,涵盖了ExUnit、Mox、属性测试和LiveView测试等多种模式。它提供了最佳实践、快速决策和常见反模式,帮助开发者在编写和审查测试时提高效率和质量。关键词:Elixir、测试、ExUnit、Mox、属性测试、LiveView、最佳实践、软件开发。

测试 0 次安装 0 次浏览 更新于 3/11/2026

name: 测试 description: Elixir 测试模式 - ExUnit、Mox、属性测试、LiveView 测试。在编写或审查测试时加载。 user-invocable: false

Elixir 测试参考

Elixir 测试模式的快速参考。

铁律 — 永不违反这些

  1. 默认异步 — 除非测试修改全局状态,否则使用 async: true
  2. 沙盒隔离 — 所有数据库测试使用 Ecto.Adapters.SQL.Sandbox
  3. 仅在边界模拟 — 永远不要模拟数据库、内部模块或标准库
  4. 行为作为契约 — 所有模拟必须实现定义的 @callback 行为
  5. 默认构建 — 在工厂中使用 build/2;仅在需要数据库 ID、约束或持久化关联时使用 insert/2
  6. 不使用 Process.sleep — 对于异步操作,使用带超时的 assert_receive
  7. VERIFY_ON_EXIT! — 在 Mox 测试设置中始终调用
  8. 工厂匹配架构必需字段 — 工厂定义必须包括所有在架构变化集中有 validate_required 的字段。缺失字段会导致级联测试失败

快速决策

使用哪个测试用例?

测试类型 使用
控制器/API use MyAppWeb.ConnCase
上下文/架构 use MyApp.DataCase
LiveView use MyAppWeb.ConnCase + import Phoenix.LiveViewTest
纯逻辑 use ExUnit.Case, async: true

何时使用 async: true?

  • ✅ 纯函数,无共享状态
  • ✅ 使用沙盒的数据库测试(PostgreSQL)
  • ❌ 修改 Application.put_env 的测试
  • ❌ 使用 Mox 全局模式的测试

模拟与否?

  • ✅ 模拟:外部 API、电子邮件服务、文件存储
  • ❌ 不模拟:数据库、内部模块、标准库

build() 或 insert()?

  • 默认使用 build() 以提高速度
  • 仅在需要数据库 ID、约束或持久化关联时使用 insert()

快速模式

# 设置链
setup [:create_user, :authenticate]

# 模式匹配断言
assert {:ok, %User{name: name}} = create_user(attrs)

# 异步消息断言
assert_receive {:user_created, _}, 5000

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

# LiveView 异步
html = render_async(view)  # 必须调用以用于 assign_async

常见反模式

错误 正确
Process.sleep(100) assert_receive {:done, _}, 5000
在工厂中使用 insert(:user) 在工厂中使用 build(:user)
async: trueset_mox_global() async: false
模拟内部模块 通过公共 API 测试

参考

有关详细模式,请参阅:

  • references/exunit-patterns.md - 设置、断言、标签
  • references/mox-patterns.md - 行为、expect/stub、异步
  • references/liveview-testing.md - 表单、异步、上传
  • references/factory-patterns.md - ExMachina、序列、特征