Cyrus Stoller home about consulting

Using rspec without Rails

Ruby is a great for building things besides rails applications. But, for newcomers, figuring out how to use tools like rspec without the nice plug and play rails generators can be confusing because the documentation assumes you understand how to setup your project.

In this tutorial I’m going to show you how to setup rspec to test your code and how to use guard-rspec to run your specs whenever you save. I find that by deceasing the amount of work I have to do to run my tests, the more likely I am to write them.

Here’s the basic directory structure (github repo) I use:

my_project
├── Gemfile
├── Guardfile
├── lib
│   ├── file1.rb
│   └── file2.rb
└── spec
    ├── lib
    │   ├── file1_spec.rb
    │   └── file2_spec.rb
    └── spec_helper.rb

Now I’ll go through each of these files and explain what they do.

# Gemfile
source 'https://rubygems.org'
group :development do
  gem 'rspec', '~> 3.0.0'
  gem 'guard-rspec', '~> 4.2.10'
end

Your Gemfile is where you define which gems you are using in your project. For this tutorial, I’m assuming you know what gems are. I suggest using rubygems.org and ruby-toolbox.org before you start writing new code. It’s possible that someone else has already written what you need.

# Guardfile
guard 'rspec', cmd: "bundle exec rspec", :all_after_pass => false, 
  :failed_mode => :none do
  watch(%r{\Aspec/.+_spec\.rb\z})
  watch(%r{\Alib/(.+)\.rb\z})   { |m| "spec/lib/#{m[1]}_spec.rb" }
  watch('spec/spec_helper.rb')  { "spec" }
end

Your Guardfile specifies which specs to run when a file is saved. If the file is in the spec directory and its filename ends with _spec.rb, we’re telling guard to run the specs in that file. If the file is in the lib directory, we’re telling guard to look for the corresponding spec file in the spec/lib directory and run it. And lastly, if the spec_helper.rb is changed, we’re telling guard to run all of the specs.

Place the code you want tested in the lib directory and place corresponding specs in the spec/lib directory. For example, if you have a file lib/file1.rb make a spec file called spec/lib/file1_spec.rb.

Setting up your specs

Now let’s look at how to setup your spec directory. In a rails project pretty much all of your classes have been preloaded. This won’t be true for your new project by default. First we need to add our lib directory to the $LOAD_PATH so that we can require those files in our specs. To learn more about how ruby loads files, click here.

# spec/spec_helper.rb
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rspec'

RSpec.configure do |config|
  config.order = 'random'
end

Depending on your project there are a couple of approaches that might work well for you.

Option 1

Load only the necessary files per spec file. So, at the top of spec/lib/file1_spec.rb you would have:

# spec/lib/file1_spec.rb
require "spec_helper"
require "file1"

Option 2

If you don’t want to have to remember to load a file in each of your spec files or if you have classes that need to interact with each other, you may just want to require all of them. To do this you can add the following to your spec/spec_helper.rb.

# spec/spec_helper.rb
Dir[File.join(File.dirname(__FILE__), "..", "lib" , "**.rb")].each do |f|
  require f
end

Update: Thanks to Eric Chiang for catching a typo.

Hopefully this was helpful. Happy coding.

Category Tutorial