From 3ee734bb7e38dfead71a7eeb66f58d38ece35f13 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Sun, 29 Nov 2015 18:57:45 -0700 Subject: [PATCH] Speed up running unit tests with Zeus 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 --- CONTRIBUTING.md | 7 +++ Gemfile | 1 + Gemfile.lock | 6 +- README.md | 48 +++++++++++++++ custom_plan.rb | 88 +++++++++++++++++++++++++++ gemfiles/4.0.0.gemfile | 1 + gemfiles/4.0.0.gemfile.lock | 6 +- gemfiles/4.0.1.gemfile | 1 + gemfiles/4.0.1.gemfile.lock | 6 +- gemfiles/4.1.gemfile | 1 + gemfiles/4.1.gemfile.lock | 6 +- gemfiles/4.2.gemfile | 1 + gemfiles/4.2.gemfile.lock | 6 +- spec/support/tests/current_bundle.rb | 4 ++ spec/support/unit/load_environment.rb | 12 ++++ spec/unit_spec_helper.rb | 17 +----- zeus.json | 11 ++++ 17 files changed, 191 insertions(+), 31 deletions(-) create mode 100644 custom_plan.rb create mode 100644 spec/support/unit/load_environment.rb create mode 100644 zeus.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0e2884a..c426b8d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,13 @@ request. appraisal 4.2 rspec ``` + You can also run unit tests by running `zeus start` in one shell, and then + running the following in another: + + ``` + zeus rspec + ``` + And to run the entire test suite again: ``` diff --git a/Gemfile b/Gemfile index 9128ebcd..d236e01c 100644 --- a/Gemfile +++ b/Gemfile @@ -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' diff --git a/Gemfile.lock b/Gemfile.lock index 3b33886c..a1b6f37e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 @@ -62,6 +64,4 @@ DEPENDENCIES redcarpet rspec (~> 3.2) yard - -BUNDLED WITH - 1.10.6 + zeus diff --git a/README.md b/README.md index d4c805d4..1045106a 100644 --- a/README.md +++ b/README.md @@ -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]. @@ -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 diff --git a/custom_plan.rb b/custom_plan.rb new file mode 100644 index 00000000..9283d6bf --- /dev/null +++ b/custom_plan.rb @@ -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 diff --git a/gemfiles/4.0.0.gemfile b/gemfiles/4.0.0.gemfile index 951935c7..d2b50146 100644 --- a/gemfiles/4.0.0.gemfile +++ b/gemfiles/4.0.0.gemfile @@ -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" diff --git a/gemfiles/4.0.0.gemfile.lock b/gemfiles/4.0.0.gemfile.lock index e62cbc9b..cc84bcc1 100644 --- a/gemfiles/4.0.0.gemfile.lock +++ b/gemfiles/4.0.0.gemfile.lock @@ -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 @@ -215,6 +217,4 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) yard - -BUNDLED WITH - 1.10.6 + zeus diff --git a/gemfiles/4.0.1.gemfile b/gemfiles/4.0.1.gemfile index 4d8bf0c6..5cdddd3b 100644 --- a/gemfiles/4.0.1.gemfile +++ b/gemfiles/4.0.1.gemfile @@ -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" diff --git a/gemfiles/4.0.1.gemfile.lock b/gemfiles/4.0.1.gemfile.lock index f73a1006..be66e320 100644 --- a/gemfiles/4.0.1.gemfile.lock +++ b/gemfiles/4.0.1.gemfile.lock @@ -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 @@ -217,6 +219,4 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) yard - -BUNDLED WITH - 1.10.6 + zeus diff --git a/gemfiles/4.1.gemfile b/gemfiles/4.1.gemfile index b6996380..9281076f 100644 --- a/gemfiles/4.1.gemfile +++ b/gemfiles/4.1.gemfile @@ -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" diff --git a/gemfiles/4.1.gemfile.lock b/gemfiles/4.1.gemfile.lock index 96f3d907..1e911602 100644 --- a/gemfiles/4.1.gemfile.lock +++ b/gemfiles/4.1.gemfile.lock @@ -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 @@ -212,6 +214,4 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) yard - -BUNDLED WITH - 1.10.6 + zeus diff --git a/gemfiles/4.2.gemfile b/gemfiles/4.2.gemfile index f3df039a..5fa8c178 100644 --- a/gemfiles/4.2.gemfile +++ b/gemfiles/4.2.gemfile @@ -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" diff --git a/gemfiles/4.2.gemfile.lock b/gemfiles/4.2.gemfile.lock index 23bb00b6..82b6473d 100644 --- a/gemfiles/4.2.gemfile.lock +++ b/gemfiles/4.2.gemfile.lock @@ -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 @@ -235,6 +237,4 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) yard - -BUNDLED WITH - 1.10.6 + zeus diff --git a/spec/support/tests/current_bundle.rb b/spec/support/tests/current_bundle.rb index 696753c6..dcc71872 100644 --- a/spec/support/tests/current_bundle.rb +++ b/spec/support/tests/current_bundle.rb @@ -24,6 +24,10 @@ EOT path.dirname == root.join('gemfiles') end + def current_or_latest_appraisal + current_appraisal || latest_appraisal + end + def latest_appraisal available_appraisals.sort.last end diff --git a/spec/support/unit/load_environment.rb b/spec/support/unit/load_environment.rb new file mode 100644 index 00000000..e4dface3 --- /dev/null +++ b/spec/support/unit/load_environment.rb @@ -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' diff --git a/spec/unit_spec_helper.rb b/spec/unit_spec_helper.rb index 26c0d005..a0d0f190 100644 --- a/spec/unit_spec_helper.rb +++ b/spec/unit_spec_helper.rb @@ -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' diff --git a/zeus.json b/zeus.json new file mode 100644 index 00000000..91598f3e --- /dev/null +++ b/zeus.json @@ -0,0 +1,11 @@ +{ + "command": "ruby -rubygems -r./custom_plan -eZeus.go", + + "plan": { + "boot": { + "test_environment": { + "rspec": [] + } + } + } +}