关于 rspec-skill
rspec-skill 是使用 RSpec 编写 Ruby 测试的参考技能,介绍匹配器、钩子、惰性 `let`、替身、共享示例和常见反模式。
主要功能
- 01RSpec 测试结构
- 02匹配器与比较
- 03钩子和惰性 `let`
- 04Mock、替身与存根
- 05可复用共享示例
- 06反模式指导
适用场景
- 01测试 Ruby 类和服务
- 02存根化仓库依赖
- 03复用模型测试示例
- 04改进测试设置与可读性
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ lambdatest/ agent-skills --skill rspec-skill安装后在 Claude Code 中输入/rspec-skill确认已加载。
附带文件reference/advanced-patterns.mdreference/playbook.md
详细介绍
RSpec 测试技能
核心模式
基本测试
RSpec.describe Calculator do
subject(:calculator) { described_class.new }
describe '#add' do
it 'adds two positive numbers' do
expect(calculator.add(2, 3)).to eq(5)
end
it 'handles negative numbers' do
expect(calculator.add(-1, 1)).to eq(0)
end
end
describe '#divide' do
it 'divides evenly' do
expect(calculator.divide(10, 2)).to eq(5)
end
it 'raises on zero divisor' do
expect { calculator.divide(10, 0) }.to raise_error(ZeroDivisionError)
end
end
end
匹配器
# Equality
expect(actual).to eq(expected) # ==
expect(actual).to eql(expected) # eql?
expect(actual).to equal(expected) # equal? (same object)
expect(actual).to be(expected) # equal?
# Comparison
expect(value).to be > 5
expect(value).to be_between(1, 10).inclusive
# Truthiness
expect(value).to be_truthy
expect(value).to be_falsey
expect(value).to be_nil
# Collections
expect(array).to include(3)
expect(array).to contain_exactly(1, 2, 3)
expect(array).to match_array([3, 1, 2])
expect(hash).to include(name: 'Alice')
# Strings
expect(str).to include('hello')
expect(str).to start_with('He')
expect(str).to match(/\d+/)
# Types
expect(obj).to be_a(String)
expect(obj).to be_an_instance_of(MyClass)
# Exceptions
expect { method }.to raise_error(StandardError)
expect { method }.to raise_error(StandardError, /message/)
# Change
expect { user.activate }.to change(user, :active).from(false).to(true)
expect { list.push(1) }.to change(list, :size).by(1)
钩子和 Let
RSpec.describe UserService do
let(:repo) { instance_double(UserRepository) }
let(:service) { described_class.new(repo) }
before(:each) do
allow(repo).to receive(:save).and_return(true)
end
after(:each) { cleanup }
before(:all) { setup_database }
after(:all) { teardown_database }
context 'when creating a user' do
it 'saves to repository' do
service.create('Alice', '[email protected]')
expect(repo).to have_received(:save).once
end
end
end
模拟和桩
# Doubles
user = double('User', name: 'Alice', email: '[email protected]')
user = instance_double(User, name: 'Alice')
# Stubs
allow(service).to receive(:fetch).and_return(data)
allow(service).to receive(:fetch).with('id').and_return(user)
# Expectations
expect(service).to receive(:save).once
expect(service).to receive(:notify).with('[email protected]')
expect(service).not_to receive(:delete)
共享示例
RSpec.shared_examples 'a valid model' do
it { is_expected.to be_valid }
it { is_expected.to respond_to(:save) }
end
RSpec.describe User do
subject { described_class.new(name: 'Alice') }
it_behaves_like 'a valid model'
end
反模式
| 不佳做法 | 良好做法 | 原因 |
|---|---|---|
使用 before 进行繁重的设置 | 使用 let(惰性求值) | 仅在使用时求值 |
| 没有上下文 | 使用 context 'when...' | 场景清晰 |
| 实例变量 | let 块 | 更简洁、惰性求值 |
should 语法 | expect().to | 现代 RSpec |
设置:先运行 gem install rspec,再运行 rspec --init
运行:bundle exec rspec 或 rspec spec/models/user_spec.rb
配置:.rspec 文件中设置 --format documentation --color
深入模式
有关高级模式、调试指南、CI/CD 集成和最佳实践,
请参阅 reference/playbook.md。
评论
支持 Markdown