Speeding up rspec tests

We have a large test-suite that runs >2200 examples, that took 900 seconds to complete on my machine. Using a few optimisation techniques I was able to bring this time down to 650secs. Which is still long :) But if I run the tests in parallel it takes me down to 300secs (I have two cores). First off, I think it is crucial that your tests are as much as possible in isolation. You are only testing the code under test. Only the model, the controller, the view. This is not something we do consequently everywhere. Sometimes I stub the ActiveRecord finders, but more often I do not. I just make sure the correct data is available. But when a controller calls a method on a model, which I have tested in the model-test, I can safely stub that call. That is sometimes the hardest call: how much mocking and stubbing will you do. A lot of mocks and stubs will make your tests fast, but also brittle, as they are tied in too much with the implementation. If I am certain that the used modules are tested correctly, I will use mocks and stubs. Otherwise I test the used modules as well. So why test ActiveRecord as well? Because sometimes I use somewhat complicated queries and scopes, and want to make sure I did not make a mistake there. Aside of that, my tips to speed up rspec tests:

  • speed up your database: either use sqlite if possible, or tune your database for maximum speed. In my case I am using postgresql and i did the following to improve that.
    • set fsync=off in postgresql.conf
    • set shared_buffers to 28MB -- I even tried setting it to 128MB but that did not make any difference anymore. Using these settings will make postgresql almost behave as an in-memory database. You can even take it further, see here.
  • If you need a lot of data instantiated, using factories, use before(:all) instead of before(:each). Clean up the data in the after(:all). Note: we cannot use before(:all) for everything. Look that up :)
  • use tip from corey haines where applicable to not include spec_helper. For me this means you should take a good look at your spec_helper. We included a lot of helpers and support-methods in our spec_helper, which makes it every easy to write a test, but also makes running a test slower. Maybe it could be profitable to always use a lean spec_helper, and include what you need inside your spec-file. And for some files inside your lib you probably don't even need spec_helper at all.
  • Test smart! Use factories, but always try to create the minimum set needed to work. If you need more than 1 item, 2 items will suffice :)
  • Use rspec-prof to profile slow parts

Do you have any more tips to speed up tests?


Comments
Add comment

Recent comments

Tags

ruby on rails 34 ruby 26 rails3 17 rails 15 oracle 11 rspec 9 rspec2 7 jquery 7 ubuntu 5 javascript 5 windows 5 activerecord 3 refactoring 3 geoserver 3 gis 3 arrrrcamp 3 actionmailer 2 oracle spatial 2 tdd 2 postgis 2 routing 2 rvm 2 mongoid 2 csharp 2 thin 2 win32 2 gem 2 rails4 2 git 2 service 2 haml 2 cucumber 2 view testing 2 i18n 1 displaysleep 1 spatial 1 gemsets 1 wubi 1 oracle_enhanced_adapter 1 migrations 1 watchr 1 ci 1 plugins 1 coderetreat 1 ie8 1 ssl 1 oci 1 nested model form 1 wcf 1 11.04 1 jsonp 1 ruby-oci8 1 teamcity 1 engines 1 pgadmin 1 soap 1 content_for 1 word automation 1 plugin 1 capybara 1 xml 1 bootstrap 1 migrate to rails3 1 mvc 1 unity 1 rendering 1 word2007 1 x64 1 limited stock 1 fast tests 1 pl/sql 1 delayed_job 1 pdf 1 test coverage 1 optimization 1 processing 1 borland 1 method_missing 1 cross-browser 1 devise 1 schema_plus 1 mongo 1 mongrel 1 dual boot 1 usability 1 mongrel_service 1 dba 1 mission statement 1 model 1 metadata 1 rcov 1 exceptions 1 image_tag 1 attachments 1 bde 1 css 1 yield 1 ajax 1 generative art 1 rails-assets 1 coordinate systems 1 submodules 1 netzke 1 ora-01031 1 authlogic 1 postgresql 1 shopping cart 1 agile 1 fast_tagger 1 subjective 1 wice_grid 1 generators 1 nvidia 1 mongodb 1 etsyhacks 1 staleobjecterror 1 session 1 jeweler 1 wordpress hacked 1 jasmine 1 heroku 1 rjs 1 life 1 unobtrusive-javascript 1 render_anywhere 1 html5 1 rails31 1 json 1 cocoon 1 mingw32 1 observe_field 1 osx 1 actionwebservice 1 testing 1 debugging 1 strings 1