如何让RSpec仅重跑带有指定标签的失败测试?
问题场景
我们编写了大量Selenium UI测试,偶尔会因Web服务器响应过慢等非业务原因失败。我们通过RSpec标签筛选测试,希望仅重跑同时带有指定标签且上一次执行失败的测试。但当前执行rspec --tag all --only_failures时,会运行所有上次失败的测试(包括不带:all标签的案例),不符合预期。
相关代码与运行结果
spec_helper.rb
RSpec.configure do |config| config.example_status_persistence_file_path = "RunResults.txt" end
test_spec.rb
require 'rspec' require 'spec_helper' require './test' RSpec.describe Test do it "should pass", :all, :one do expect(1).to eql(1) end it "should fail", :all, :two do expect(1).to eql(2) end it "should fail", :three do expect(1).to eql(2) end end
RunResults.txt
example_id | status | run_time | ------------------------ | ------ | --------------- | ./spec/test_spec.rb[1:1] | passed | 0.00055 seconds | ./spec/test_spec.rb[1:2] | failed | 0.01796 seconds | ./spec/test_spec.rb[1:3] | failed | 0.00017 seconds |
异常运行结果
$ rspec --tag all --only_failures Run options: include {:all=>true, :last_run_status=>"failed"} .FF Failures: 1) Test should fail Failure/Error: expect(1).to eql(2) expected: 2 got: 1 (compared using eql?) # ./spec/test_spec.rb:11:in `block (2 levels) in <top (required)>' 2) Test should fail Failure/Error: expect(1).to eql(2) expected: 2 got: 1 (compared using eql?) # ./spec/test_spec.rb:15:in `block (2 levels) in <top (required)>' Finished in 0.01949 seconds (files took 0.24733 seconds to load) 3 examples, 2 failures Failed examples: rspec ./spec/test_spec.rb:10 # Test should fail rspec ./spec/test_spec.rb:14 # Test should fail
解决方案
方案1:自定义RSpec过滤逻辑(推荐)
在spec_helper.rb中添加自定义配置,通过环境变量传递目标标签,精准筛选同时满足「带指定标签」和「上次失败」的测试:
RSpec.configure do |config| config.example_status_persistence_file_path = "RunResults.txt" # 自定义过滤:仅运行带指定标签且上次失败的测试 if ENV['RUN_FAILED_TAGGED'] target_tag = ENV['RUN_FAILED_TAGGED'].to_sym # 加载上一次失败的测试ID列表 failed_example_ids = RSpec::Core::ExampleStatusPersistence.load_failed_example_ids config.filter_run do |example| # 同时满足:测试带有目标标签,且属于上次失败的列表 example.metadata.key?(target_tag) && failed_example_ids.include?(example.id) end end end
运行时通过环境变量指定标签(比如:all):
RUN_FAILED_TAGGED=all rspec
方案2:命令行组合过滤(无需修改代码)
通过命令行工具提取并交集「带指定标签的测试」和「上次失败的测试」,再运行结果:
- 导出上次失败的测试命令列表:
rspec --only_failures --dry-run | grep 'rspec' > failed_tests.txt
- 导出带指定标签的测试命令列表:
rspec --tag all --dry-run | grep 'rspec' > tagged_tests.txt
- 取两个列表的交集,得到需要重跑的测试:
comm -12 <(sort failed_tests.txt) <(sort tagged_tests.txt) > to_run.txt
- 运行筛选后的测试:
cat to_run.txt | xargs rspec
方案3:升级RSpec版本
如果是RSpec版本过低导致--tag与--only_failures组合逻辑异常,升级到最新稳定版(推荐3.12+),默认的rspec --tag all --only_failures即可实现「同时满足标签和失败状态」的过滤效果。
内容的提问来源于stack exchange,提问作者kroe761
相关产品推荐
相关产品推荐

