Skip to content

Commit

Permalink
Speed up running unit tests with Zeus
Browse files Browse the repository at this point in the history
This is an effort to vastly decrease the time it takes to run a single
unit test file and therefore increase productivity and happiness for
people working on this project.

If you want to run a unit test file, now you can use `zeus rspec`
instead of `rspec` -- assuming you run `zeus start` first -- and it will
run a LOT faster.

Because test files tend to have long file paths, you can even use a
shorter version of those paths. So instead of saying:

    zeus rspec spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb

you can say:

    zeus rspec active_record/validate_uniqueness_of_matcher_spec.rb
  • Loading branch information
mcmire committed Dec 14, 2015
1 parent 14b5658 commit 3ee734b
Show file tree
Hide file tree
Showing 17 changed files with 191 additions and 31 deletions.
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ request.
appraisal 4.2 rspec <path of test file to run>
```

You can also run unit tests by running `zeus start` in one shell, and then
running the following in another:

```
zeus rspec <path of test file to run>
```

And to run the entire test suite again:

```
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ gem 'pry', github: 'pry/pry'
gem 'pry-byebug'
gem 'rake', '~> 10.0'
gem 'rspec', '~> 3.2'
gem 'zeus'

# YARD
gem 'yard'
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ GEM
thor (0.19.1)
yajl-ruby (1.1.0)
yard (0.8.7.3)
zeus (0.15.4)
method_source (>= 0.6.7)

PLATFORMS
ruby
Expand All @@ -62,6 +64,4 @@ DEPENDENCIES
redcarpet
rspec (~> 3.2)
yard

BUNDLED WITH
1.10.6
zeus
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,52 @@ Shoulda::Matchers.configure do |config|
end
```

## Running tests

### Unit tests

Unit tests are the most common kind of tests in this gem, and the best way to
run them is by using [Zeus].

You'll want to run `zeus start` in one shell, then in another shell, instead of
using `rspec` to run tests, you can use `zeus rspec`. So for instance, you might
say:

```
zeus rspec spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb
```

As a shortcut, you can also drop the initial part of the path and say this
instead:

```
zeus rspec active_model/validate_inclusion_of_matcher_spec.rb
```

### Acceptance tests

The gem uses [Appraisal] to test against multiple versions of Rails and Ruby.
This means that if you're trying to run a single test file, you'll need to
specify which appraisal to use. For instance, you can't simply say:

```
rspec spec/acceptance/active_model_integration_spec.rb
```

Instead, you need to say

```
bundle exec appraisal 4.2 rspec spec/acceptance/active_model_integration_spec.rb
```

### All tests

You can run all tests by saying:

```
bundle exec rake
```

## Generating documentation

YARD is used to generate documentation, which can be viewed [online][rubydocs].
Expand Down Expand Up @@ -284,3 +330,5 @@ We are [available for hire][hire].
[contributors]: https://github.com/thoughtbot/shoulda-matchers/contributors
[shoulda]: http://github.com/thoughtbot/shoulda
[shoulda-context]: http://github.com/thoughtbot/shoulda-context
[Zeus]: https://github.com/burke/zeus
[Appraisal]: https://github.com/thoughtbot/appraisal
88 changes: 88 additions & 0 deletions custom_plan.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
require 'zeus/rails'
require_relative 'spec/support/tests/current_bundle'

class CustomPlan < Zeus::Plan
def initialize
super
@rails_plan = Zeus::Rails.new
end

def boot
ENV['BUNDLE_GEMFILE'] = File.expand_path(
"../gemfiles/#{latest_appraisal}.gemfile",
__FILE__
)

require 'bundler/setup'

$LOAD_PATH << File.expand_path('../lib', __FILE__)
$LOAD_PATH << File.expand_path('../spec', __FILE__)

require_relative 'spec/support/unit/load_environment'
end

def after_fork
# @rails_plan.reconnect_activerecord
end

def test_environment
require_relative 'spec/unit_spec_helper'
end

def rspec
ARGV.replace(file_paths_to_run)
RSpec::Core::Runner.invoke
end

private

def latest_appraisal
current_bundle.latest_appraisal
end

def current_bundle
Tests::CurrentBundle.instance
end

def file_paths_to_run
if given_file_paths.empty?
['spec/unit']
else
given_file_paths.map do |given_path|
determine_file_path_to_run(given_path)
end
end
end

def determine_file_path_to_run(given_rspec_argument)
expanded_file_path, location =
expand_rspec_argument(given_rspec_argument)

if File.exist?(expanded_file_path)
if location
expanded_file_path + location
else
expanded_file_path
end
else
given_rspec_argument
end
end

def expand_rspec_argument(rspec_argument)
match = rspec_argument.match(/\A(.+?)(:\d+|\[[\d:]+\])?\Z/)
file_path, location = match.captures
expanded_file_path = File.expand_path(
"../spec/unit/shoulda/matchers/#{file_path}",
__FILE__
)

[expanded_file_path, location]
end

def given_file_paths
ARGV
end
end

Zeus.plan = CustomPlan.new
1 change: 1 addition & 0 deletions gemfiles/4.0.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec", "~> 3.2"
gem "zeus"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
Expand Down
6 changes: 3 additions & 3 deletions gemfiles/4.0.0.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ GEM
json (>= 1.8.0)
yajl-ruby (1.2.1)
yard (0.8.7.6)
zeus (0.15.4)
method_source (>= 0.6.7)

PLATFORMS
ruby
Expand Down Expand Up @@ -215,6 +217,4 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
zeus
1 change: 1 addition & 0 deletions gemfiles/4.0.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec", "~> 3.2"
gem "zeus"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
Expand Down
6 changes: 3 additions & 3 deletions gemfiles/4.0.1.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ GEM
json (>= 1.8.0)
yajl-ruby (1.2.1)
yard (0.8.7.6)
zeus (0.15.4)
method_source (>= 0.6.7)

PLATFORMS
ruby
Expand Down Expand Up @@ -217,6 +219,4 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
zeus
1 change: 1 addition & 0 deletions gemfiles/4.1.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec", "~> 3.2"
gem "zeus"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
Expand Down
6 changes: 3 additions & 3 deletions gemfiles/4.1.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ GEM
json (>= 1.8.0)
yajl-ruby (1.2.1)
yard (0.8.7.6)
zeus (0.15.4)
method_source (>= 0.6.7)

PLATFORMS
ruby
Expand Down Expand Up @@ -212,6 +214,4 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
zeus
1 change: 1 addition & 0 deletions gemfiles/4.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ gem "pry", :github => "pry/pry"
gem "pry-byebug"
gem "rake", "~> 10.0"
gem "rspec", "~> 3.2"
gem "zeus"
gem "yard"
gem "redcarpet"
gem "pygments.rb"
Expand Down
6 changes: 3 additions & 3 deletions gemfiles/4.2.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ GEM
json (>= 1.8.0)
yajl-ruby (1.2.1)
yard (0.8.7.6)
zeus (0.15.4)
method_source (>= 0.6.7)

PLATFORMS
ruby
Expand Down Expand Up @@ -235,6 +237,4 @@ DEPENDENCIES
turbolinks
uglifier (>= 1.3.0)
yard

BUNDLED WITH
1.10.6
zeus
4 changes: 4 additions & 0 deletions spec/support/tests/current_bundle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ def appraisal_in_use?
path.dirname == root.join('gemfiles')
end

def current_or_latest_appraisal
current_appraisal || latest_appraisal
end

def latest_appraisal
available_appraisals.sort.last
end
Expand Down
12 changes: 12 additions & 0 deletions spec/support/unit/load_environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require_relative '../tests/current_bundle'
require_relative 'rails_application'

Tests::CurrentBundle.instance.assert_appraisal!

$test_app = UnitTests::RailsApplication.new
$test_app.create
$test_app.load

require 'active_record/base'

ENV['RAILS_ENV'] = 'test'
17 changes: 1 addition & 16 deletions spec/unit_spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
require_relative 'support/tests/current_bundle'

Tests::CurrentBundle.instance.assert_appraisal!

#---

require File.expand_path('../support/unit/rails_application', __FILE__)

$test_app = UnitTests::RailsApplication.new
$test_app.create
$test_app.load

require 'active_record/base'

ENV['BUNDLE_GEMFILE'] ||= app.gemfile_path
ENV['RAILS_ENV'] = 'test'
require_relative 'support/unit/load_environment'

require 'rspec/rails'
require 'shoulda-matchers'
Expand Down
11 changes: 11 additions & 0 deletions zeus.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"command": "ruby -rubygems -r./custom_plan -eZeus.go",

"plan": {
"boot": {
"test_environment": {
"rspec": []
}
}
}
}

0 comments on commit 3ee734b

Please sign in to comment.