class RSpec::Core::Bisect::ForkRunner
A Bisect
runner that runs requested subsets of the suite by forking sub-processes. The main process bootstraps RSpec
and the application environment (including preloading files specified via ‘–require`) so that the individual spec runs do not have to re-pay that cost. Each spec run happens in a forked process, ensuring that the spec files are not loaded in the main process.
For most projects, bisections that use ‘ForkRunner` instead of `ShellRunner` will finish significantly faster, because the `ShellRunner` pays the cost of booting RSpec
and the app environment on every run of a subset. In contrast, `ForkRunner` pays that cost only once.
However, not all projects can use ‘ForkRunner`. Obviously, on platforms that do not support forking (e.g. Windows), it cannot be used. In addition, it can cause problems for some projects that put side-effectful spec bootstrapping logic that should run on every spec run directly at the top level in a file loaded by `–require`, rather than in a `before(:suite)` hook. For example, consider a project that relies on some top-level logic in `spec_helper` to boot a Redis server for the test suite, intending the Redis bootstrapping to happen on every spec run. With `ShellRunner`, the bootstrapping logic will happen for each run of any subset of the suite, but for `ForkRunner`, such logic will only get run once, when the `RunDispatcher` boots the application environment. This might cause problems. The solution is for users to move the bootstrapping logic into a `before(:suite)` hook, or use the slower `ShellRunner`.
@private
Public Class Methods
# File rspec-core/lib/rspec/core/bisect/fork_runner.rb, line 43 def self.name :fork end
# File rspec-core/lib/rspec/core/bisect/fork_runner.rb, line 47 def initialize(shell_command, spec_runner) @shell_command = shell_command @channel = Channel.new @run_dispatcher = RunDispatcher.new(spec_runner, @channel) end
# File rspec-core/lib/rspec/core/bisect/fork_runner.rb, line 36 def self.start(shell_command, spec_runner) instance = new(shell_command, spec_runner) yield instance ensure instance.shutdown end
Public Instance Methods
# File rspec-core/lib/rspec/core/bisect/fork_runner.rb, line 58 def original_results @original_results ||= dispatch_run(ExampleSetDescriptor.new( @shell_command.original_locations, [])) end
# File rspec-core/lib/rspec/core/bisect/fork_runner.rb, line 53 def run(locations) run_descriptor = ExampleSetDescriptor.new(locations, original_results.failed_example_ids) dispatch_run(run_descriptor) end
# File rspec-core/lib/rspec/core/bisect/fork_runner.rb, line 63 def shutdown @channel.close end