I am using the out of the box, vanilla test suite for Rails 5 beta. I am wondering if anyone has figured out how to run a global setup, and tear down.
The reason this is required to I am spinning up a in memory Elasticsearch cluster before any test begins and stop the cluster once the tests are done.
Rspec is not an option.
Under Minitest (which is the default testing environment in Rails 4+), to get the "global setup" behavior, simply run anything in your test_helper.rb (outside the tests themselves or any setup methods), i.e. in the file where you load your testing environment from. The test helper is usually required in the tests, so its code is run once before any tests.
For a "global teardown", Minitest provides the Minitest.after_run method. Anything inside its block will be run once after all tests are finished (it uses the program exit hook). Place it e.g. in the test_helper again. For this to work you need to require 'minitest/autorun' at the beginning of the test helper file.
test/test_helper.rb
class ActiveSupport::TestCase
# Some pre-generated stuff here
setup do
do_something
end
teardown do
do_something
end
end
Related
I'm working with Rails 5 and rspec (gem version 4). I was wondering if RSpec can be configured to only run tests that have been modified within a single file when only running that file, i.e.
bundle exec rspec spec/my_spec.rb
. If my file is like this
RSpec.describe MyClass do
context "context 1" do
it "tests condition 1" do
end
it "tests condition 2" do
end
...
end
context "context 2" do
...
end
...
end
and I only update tests in "context 1," is it possible to test the single file and have only modified tests from within that file run? With respect to this answer -- Can I get RSpec to only run changed specs?, it appears that only relates to actual files that have changed when running the complete suite of rspec tests.
I think you are looking for guard.
Checkout nicely written article https://collectiveidea.com/blog/archives/2017/02/09/guard-is-your-friend
There is a Ruby Gem called retest designed to do exactly that. Just run retest, and it will watch for changes in the code or the specs themselves, and rerun just the respective spec file.
To run a single test in Rails, we normally do:
rails test TEST=test/system/invitation_test.rb
But that doesn't work with system tests. Neither do this work:
rails test:system TEST=test/system/invitation_test.rb
With both those commandos above, all system tests (files) are run.
So my question is, how can I run a single system test?
As a side note, to run (all) system tests in Rails, you need to append :system to test.
rails test:system
While rails test doesn't seem to work if you want to run your system tests (you need to append test with :system), if you only want to run a single test it does seem to work:
rails test test/system/my_little_test.rb
When testing lib code there is rarely any need to require spec_helper and load all of rails. This is why I have been removing require "spec_helper" in favour of require_relative "../../lib/my_lib.rb".
These tests pass when called directly (rspec spec/lib/my_lib.rb) and are blazingly fast. Winner.
My issue comes when I try and run these tests as a group.
When I call rspec spec/lib it runs any lib specs that have a require "spec_helper" line but not any tests that don't.
I have played with spec_helper.rb to load in these tests, and that kind of works only it means that when I run rspec spec/models/blah.rb it will also run these lib tests, which obviously isn't what I want.
Is there a different way I should be calling my tests? Or is there a way I can get them added to the test run?
Notes
My spec_helper is configured to run the tests in a random order, I wonder if this has anything to do with it?
You should add _spec to your files:
spec/lib/my_lib_spec.rb
Rspec rake task will look only for files which end in _spec.
I was having some problem with zeus + rspec and the solution I found says that I must to delete require 'rspec/autorun' from spec_helper.rb.
That worked great, but I was wondering what's the utility of rspec/autorun? It comes in spec_helper.rb by default, but the specs works anyway with or without it.
As far as i understand, you would need rspec/autorun if you want to run specs using "ruby" command.
From RSpec docs:
Generally, life is simpler if you just use the rspec command. If you must use the ruby command, however, you’ll want to do the following:
require 'rspec/autorun'
rspec/autorun installs an at_exit hook that runs your tests. That way you can simply execute your testfiles directly rather than passing them to the rspec command (and a few other tricks, like having tests run automatically when you execute a library file).
Most setups don't need it.
I've got an interesting problem that's causing myself and my team a lot of headaches when it comes to running our spec suite.
Our spec suite is broken up into the following sub-folders, and next to them is their total execution time to completion:
rspec spec/acceptance 311.67s
rspec spec/controllers 18.97s
rspec spec/decorators 4.39s
rspec spec/helpers 9.45s
rspec spec/lib 16.88s
rspec spec/mailers 5.27s
rspec spec/models 121.05s
rspec spec/presenters 0.03s
rspec spec/workers 19.3s
Total run time: 8m 27s
Which certainly could be improved, but all in all is pretty managable.
However, if, I run rspec spec and run the entire suite at once, the total time to complete is 27m 11s!
So, obviously something we are doing is dramatically affecting the performance of the entire suite when run at once. I'm hoping that I can get some pointers as to where I can begin to try to troubleshoot this problem.
If it helps, I've posted my spec_helper.rb file here
Thanks in advance,
Joe
At a guess, I'd say your integration specs are setting DatabaseCleaner to :truncation and it's not getting switched back to :transaction for the other specs. I have a sample spec_helper that navigates the situation here. There are also a couple methods provided that help you dig in and figure out which strategy is being used at any given time. Here it is for your convenience:
def cleaner_strategy
active_record_cleaner.instance_variable_get(:#strategy).class
end
def active_record_cleaner
DatabaseCleaner.instance_variable_get(:#cleaners)[[:active_record, {}]]
end
Side note: we use a filter for our integration specs since they are so slow. We disable them by default in our local env, and then let CI run them.
config.filter_run_excluding :slow unless ENV['SLOW']
Then you can run them individually with:
$ SLOW=true rspec spec/features/some_awesome_feature_spec.rb
What does profiling tell you?
Run rspec spec --profile or add --profile to your ~/.rspec file.
On completion of your tests, it will report the 10 slowest tests.