discourse/lib/turbo_tests.rb
Daniel Waterworth e18ce56f4b DEV: Add a new way to run specs in parallel with better output (#7778)
* DEV: Add a new way to run specs in parallel with better output

This commit:

 1. adds a new executable, `bin/interleaved_rspec` which works much like
    `rspec`, but runs the tests in parallel.

 2. adds a rake task, `rake interleaved:spec` which runs the whole test
    suite.

 3. makes autospec use this new wrapper by default. You can disable this
    by running `PARALLEL_SPEC=0 rake autospec`.

It works much like the `parallel_tests` gem (and relies on it), but
makes each subprocess use a machine-readable formatter and parses this
output in order to provide a better overall summary.

(It's called interleaved, because parallel was taken and naming is
hard).

* Make popen3 invocation safer

* Use FileUtils instead of shelling out

* DRY up reporter

* Moved summary logic into Reporter

* s/interleaved/turbo/g

* Move Reporter into its own file

* Moved run into its own class

* Moved Runner into its own file

* Move JsonRowsFormatter under TurboTests

* Join on threads at the end

* Acted on feedback from eviltrout
2019-06-21 10:59:01 +10:00

63 lines
1.5 KiB
Ruby

require 'open3'
require 'fileutils'
require 'json'
require 'rspec'
require 'rails'
require 'parallel_tests'
require 'parallel_tests/rspec/runner'
require './lib/turbo_tests/reporter'
require './lib/turbo_tests/runner'
require './lib/turbo_tests/json_rows_formatter'
module TurboTests
FakeException = Struct.new(:backtrace, :message, :cause)
class FakeException
def self.from_obj(obj)
if obj
obj = obj.symbolize_keys
new(
obj[:backtrace],
obj[:message],
obj[:cause]
)
end
end
end
FakeExecutionResult = Struct.new(:example_skipped?, :pending_message, :status, :pending_fixed?, :exception)
class FakeExecutionResult
def self.from_obj(obj)
obj = obj.symbolize_keys
new(
obj[:example_skipped?],
obj[:pending_message],
obj[:status].to_sym,
obj[:pending_fixed?],
FakeException.from_obj(obj[:exception])
)
end
end
FakeExample = Struct.new(:execution_result, :location, :full_description, :metadata, :location_rerun_argument)
class FakeExample
def self.from_obj(obj)
obj = obj.symbolize_keys
new(
FakeExecutionResult.from_obj(obj[:execution_result]),
obj[:location],
obj[:full_description],
obj[:metadata].symbolize_keys,
obj[:location_rerun_argument],
)
end
def notification
RSpec::Core::Notifications::ExampleNotification.for(
self
)
end
end
end