Rails 4.1 allows us to use Spring to run our rails
and rake
commands quickly by running your application in the background and avoiding the rails startup time penalty. It took me a little while to find this information, so here is my guide to setting this up.
I’m using the RSpec testing framework with the Guard event watcher as the test runner. Spring allows us to watch the test run almost immediately after hitting save of a file in the editor.
First, let’s start with a fresh app to understand things. Upgrading an existing app is straightforward with this technique as well. Note that I am using Rails 4.1.0.beta1 on Ruby 2.1.0p0.
1 2 3 |
|
After we open the Gemfile
in our editor, we add the following gems
- rspec-rails - The RSpec testing framework with Rails integrations
- spring-commands-rspec - Adds rspec command for spring. Includes a dependency for the spring Rails application preloader.
- guard-rspec - The Guard file watcher for running rspec
- rb-fsevent - For OS/X only, waits for file changes from the Mac OS/X FSEvents API instead of polling the disk for changes.
Add this block to the Gemfile
(You may wish to add gem versions as well.)
1 2 3 4 5 6 |
|
Bundle
again after saving to install the dependent gems.
1
|
|
Setup Spring
The spring
command runs a command through the spring application runner. By default, it is configured to run rails
and rake
commands only. We added a plugin gem to allow it to run rspec
for us.
Spring has a binstub
subcommand that updates the scripts in myapp/bin
to load the spring runner. Run this command to configure these scripts (when converting to spring) and for the rspec command.
1 2 3 4 |
|
You can check if spring has your application running as a background process with the status subcommand. When you run a spring-enabled command, it will start the server.
The startup for the first time will take a moment as rails initializes. Now that spring has started the app server for you, subsequent runs will use a forked process from this server instead and return faster.
1 2 3 4 5 6 7 8 9 |
|
The spring server will shutdown automatically when your shell session is closed. You can shut it down yourself by:
1 2 |
|
That’s about all you need to know to get started with spring.
Setting up RSpec and Guard
This process is the same as you normally would do:
1 2 3 4 5 6 7 8 |
|
This sets up the files for rspec and guard. Now we have to tell guard to use the spring runner when using rspec. Edit your Guardfile
and change the command for rspec to spring rspec
. Change this line:
1
|
|
to
1
|
|
Running
(Running with binstubs, shell extensions, alias, etc. may make executing these commands different on your system. You may need to bundle exec rails
or bin/rails
, or however your environment is setup.)
Check out the time gains running rspec through spring, I’ll use the time command:
1 2 3 4 5 6 7 |
|
This is on a minimal app with a single, scaffolded resource. As your app grows larger, the initial startup time will be longer, and your time savings will multiply accordingly. (Of course, you can just run the spring rspec
command if you are more interested in the results rather than the timings.)
To start TDD’ing, fire up guard in a terminal session.
1 2 3 4 5 |
|
This runs guard
to watch your app files and kicks off the spring rspec command to run your changed spec file or suite.
If you need to change something basic in your app, such as adding a gem, updating a local dependency that could be cached, you need to restart both guard (Ctrl-D at the console) (or a server or console process), and spring (spring stop
). Restarting guard
will restart spring as well, with your dependencies reloaded.