mcpField
R
rails-testing

rails-testing

github.com/marckohlbrugge测试与质量73052 次安装20 周前更新
代码仓库

关于 rails-testing

rails-testing 是用于编写和审查 Rails 应用测试的技能,采用 Minitest 和 fixtures,强调关注行为、保持测试确定性,并选择合适的测试层级。

主要功能

  1. 01Minitest 与 fixtures 规范
  2. 02以行为为中心的测试覆盖
  3. 03测试层级选择建议
  4. 04异步与外部边界测试
  5. 05授权和租户测试模式

适用场景

  1. 01审查 Rails 测试覆盖情况
  2. 02端到端测试用户工作流
  3. 03为授权问题添加回归测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/marckohlbrugge/37signals-skills --skill rails-testing

安装后在 Claude Code 中输入/rails-testing确认已加载。

详细介绍

Rails 测试

适用于编写和审查测试的任务。模式参考 Campfire 和 Fizzy 的测试套件。

默认做法

  • 使用 Minitest + fixtures。不使用 RSpec,也不使用 FactoryBot。
  • 测试行为,而非实现细节。
  • 保持测试确定且快速;使用 parallelize(workers: :number_of_processors)。
  • 功能的测试应与功能在同一个 commit/PR 中提交,不提前,也不延后。安全修复始终要包含回归测试。
  • 切勿为了便于测试而增加生产代码的复杂度(不得因测试损害设计)。

覆盖预算(37signals 实际投入的地方)

  • 重点: 模型测试(领域不变量、concerns)和控制器/集成测试(完整请求周期、身份验证、格式)。
  • 少量: 为关键的顺畅流程编写少数系统测试(一个冒烟测试即可覆盖注册→使用);仅为包含实际逻辑的作业编写作业测试。
  • 不写: 视图测试、JS/Stimulus 单元测试、穷举式频道测试。UI 行为通过系统测试间接覆盖。
  • 不要在多个层重复断言相同行为。

Fixtures

  • 使用标签而非 ID 表示关系;使用 ERB 表示相对时间戳(created_at: <%= 1.hour.ago %>)以及共享的计算值(重复使用一个 bcrypt 摘要)。
  • 让 test/models 中的结构与 app/models 对应:app/models/card/closeable.rb ↔ test/models/card/closeable_test.rb;共享 concerns 放在 test/models/concerns/ 下。
  • UUID 主键会打乱 fixture 顺序:在 fixtures 中生成由标签确定的 UUIDv7,以确保 .first/.last 的顺序稳定,且运行时记录始终更新。
  • 使用生产代码构建富内容 fixtures(ActionText::Attachment.from_attachable(user).to_html),不要手写标记。

良好实践

  • 使用系统/集成测试验证用户工作流;使用模型测试验证领域不变量。
  • 对基于时间的逻辑使用 travel_to。
  • 仅在边界处进行模拟/替身处理(外部 API、网络、时间、SecureRandom);对外部 HTTP 使用 VCR——根据类名和测试名称自动命名 cassette,并在匹配时规范化时间戳。
  • 在模型测试中,使用 perform_enqueued_jobs(only: SpecificJob) 和 assert_enqueued_with 测试异步副作用,而不是对简单的作业类进行单元测试。
  • 在一个断言中验证相关计数变化:assert_difference({ -> { card.assignees.count } => -1, -> { Event.count } => +1 })。
  • 控制器提供多种响应格式时,分别测试每种格式:as: :turbo_stream(断言 stream 目标)和 as: :json(状态码、Location 标头、响应正文)。
  • 按层测试 Turbo/广播:模型测试使用 assert_turbo_stream_broadcasts,控制器测试使用 assert_turbo_stream action:, target:,负向测试使用 assert_no_turbo_stream_broadcasts。
  • 授权测试要断言不可访问的情况:跨租户/角色访问应返回 403/404,不能只验证允许访问正常工作。
  • 多租户套件:在 setup 中设置 Current.account(行为取决于操作者时还要设置 Current.session);集成/系统测试设置 default_url_options[:script_name];为身份验证路由提供 untenanted { } helper。在 teardown 中清除 Current。
  • 使用 Rack::MockRequest 单独测试中间件。
  • 系统测试:在多用户场景中使用 using_session("Kevin");断言实时行为前等待 cable 连接;通过快速的 session-transfer helper 进行身份验证,将完整登录流程限制在一个冒烟测试中。
  • 存在非事务性副作用(FTS 表)的套件,按 helper 选择退出事务:使用 self.use_transactional_tests = false 并显式清理。
  • 并行套件中,每个测试都要重置共享的全局状态(线程池、ActionCable.server.pubsub、Current)。

警示信号

  • 仅为便于测试而增加生产代码的复杂度。
  • 过度模拟/替身处理应用内部代码。
  • 在多个层重复测试相同行为。
  • 因每个测试都进行不必要的 setup 而导致套件变慢(这正是 fixtures 的用途)。
  • 为只有一行代码的作业类或简单委托编写单元测试。
  • 手写 HTML 字符串,而生产渲染器/helper 可以自动保持同步。
  • 不使用 travel_to 的时间相关断言。

评论

支持 Markdown