使用cucumber-rails 1.4.2时如何中断单个测试并继续执行其余测试?
Great question! I’ve run into this exact frustration with older cucumber-rails versions—stopping the entire suite just because one test hangs or fails is such a waste of time. Here are two practical approaches to achieve what you want:
1. Custom Signal Handling in env.rb
You can override Cucumber’s default SIGINT (Ctrl+C) behavior to skip the current scenario instead of terminating the whole suite. Add this code to your features/support/env.rb file:
require 'cucumber/cli/main' module Cucumber module Cli class Main alias_method :original_trap_interrupt, :trap_interrupt def trap_interrupt @interrupted = false Signal.trap('INT') do if @interrupted # Second Ctrl+C: exit immediately like normal original_trap_interrupt.call else @interrupted = true puts "\n\n--- User Interrupt: Skipping Current Scenario ---" # Mark the current scenario as failed/skipped and continue if @runtime && @runtime.current_scenario @runtime.current_scenario.fail!("Interrupted by user request") # Reset flag so next Ctrl+C will exit @interrupted = false else # No active scenario? Exit normally original_trap_interrupt.call end end end end end end end # Track the current scenario for clarity Before do |scenario| $current_cucumber_scenario = scenario end After do |scenario| $current_cucumber_scenario = nil end
How it works:
- First Ctrl+C: Skips the currently running scenario (marks it as failed) and resumes the rest of the suite.
- Second Ctrl+C: Triggers the original "exit immediately" behavior if you want to stop everything entirely.
Note: This relies on internal Cucumber 1.3.x/1.4.x APIs, so you might need minor tweaks if your exact version has slight differences in the Main or Runtime classes.
2. Use the cucumber-skip Gem (Alternative)
While there’s no dedicated gem for interrupt handling in older Cucumber versions, the cucumber-skip gem lets you mark scenarios as skipped programmatically. You can combine it with a custom signal handler to trigger skips on Ctrl+C.
Add it to your Gemfile:
gem 'cucumber-skip', group: :test
Then update your signal handler in env.rb to use the gem’s skip method instead of failing the scenario:
# Inside the SIGINT handler block if @runtime && @runtime.current_scenario @runtime.current_scenario.skip!("Interrupted by user") @interrupted = false end
This will mark the scenario as skipped instead of failed, which might be preferable if you don’t want to clutter your test results with failures from intentional interrupts.
内容的提问来源于stack exchange,提问作者Andrew Grimm

