Services Spotlight:

How to Setup RSpec in a Rails Engine

Written By Corlew Solutions
Updated January 2, 2018
Published June 20, 2016
Why Corlew Solutions?

We write great software and provide amazing technical support. Contact us today if you need help with a software project:

  • Website: Send an inquiry
  • Email:
  • Phone: (703) 688-3058

Article Technology Info

This article discusses the following technologies:

  • Rails Engines - Small applications that provide functionality to larger Rails applications.
    (docs)
  • RSpec - A testing framework for Behavior Driven Development.
    (website | docs)
  • Ruby on Rails - An open source web application framework written in Ruby.
    (website | docs)

In this article, we will learn how to setup RSpec in a brand new engine that was generated using the rails plugin new command. If your engine is already created, you will be able to follow along and create/edit the necessary files in your current project.

Testing an engine using RSpec is very similar to testing a full blown Rails application. There are some differences in the setup, but for the most part, the process is similar. This isn’t surprising since a Rails app is just a “supercharged engine” according to the Getting Started with Engines guide. One thing to wrap your head around right off the bat is engine’s are tested through a host Rails application (called “the dummy application” in the Rails documentation) which resides in the engine’s spec/dummy folder. With a non-engine gem, you would typically use RSpec to test the gem modules directly; in an engine, you can still do that if needed, but you also have the extra ability to use the dummy Rails application for more advanced testing with tools like Capybara. This gives you a great opportunity to test your engine in a way that it will actually be used - inside a real Rails app.

Adding RSpec to Existing Engines

In order to keep the article short and focused, we’re going to proceed by creating and modifying a brand new engine. However, the steps for adding RSpec to an existing engine are almost identical so you will be able to follow along and make related changes to your existing engine. We’re going to review all the important files so you won’t miss anything if your engine was built using a different process from the one below.

Example Engine

A bare bones sample engine has been created on GitHub at you want to take a look at working code.

Create The Engine

First things first, let’s create the sample engine. We’re going to call our engine blorgh which is the name used in the Getting Started with Engines guide. Also, for this sample engine, we don’t particularly care if it’s a full or mountable engine. If you’re building a new engine and aren’t sure which way to go, Stackoverflow has a good thread on full vs mountable engines. You can always change your engine around later if you’re unsure. For now, we’ll create a full engine by executing:

1
rails plugin new blorgh --dummy-path=spec/dummy --skip-test --full

This will create an engine with a dummy rails application inside the spec/dummy folder. It will also tell the generator not to create a test folder for rails default testing framework.

Setup RSpec in the Engine

Delete the test Folder

If you have an existing engine, you might have a test folder. Delete it or move it out the engine if you think you need to reference it’s contents later.

Setup the dummy App

Our sample engine defines a dummy app at spec/dummy. If your engine doesn’t have a spec/dummy app, copy the one from the sample engine into your engine.

Open the spec/dummy/config/application.rb file and somewhere near the top, you’ll see a line where your engine is required. If you’re looking at the sample app, it will say require “blorgh”. Make sure your engine has a similar line that loads your engine. What you’re actually doing here is requiring the main gem file inside your engine’s lib folder. So, if your engine is named my_engine, then you probably have a lib/my_engine.rb file and you would need require “my_engine” inside your application.rb.

While still inside the application.rb file, take a look at how rails is required. Engines that use the default Rails testing framework have a require “rails/all” line near the top. Engines that are created with –skip-test don’t require all of rails because that would load the default testing framework too. Take a look at the sample engine and make sure your engine requires the same components. For Rails 4.2.6 this looks like:

1
2
3
4
5
6
7
# Pick the framework you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

Your dummy rails application is completely setup at this point!

Setup .gitignore

We don’t want Git including the temporary files in the dummy app when we commit our changes so make sure .gitignore includes the following

1
2
3
4
5
spec/dummy/db/*.sqlite3
spec/dummy/db/*.sqlite3-journal
spec/dummy/db/log/*.log
spec/dummy/tmp/
spec/dummy/.sass-cache

Setup .gemspec

The rails plugin new command generates a starting .gemspec for your project. It’s a little too bare bones for our tastes and we actually prefer the one generated by the bundle gem which is an alternative gem generator. Inside the .gemspec file, find the following line:

1
s.files = Dir["{app.config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"]

Replace it with the following which is generated by the bundle gem command:

1
2
3
4
5
6
s.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
s.bindir        = "exe"
s.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
s.require_paths = ["lib"]

s.test_files = Dir["spec/**/*"]

Setup bin/rails

The rails engine generator also created a bin/rails file for us. This file is important because RSpec has an installer that we will execute and that installer won’t run unless this file exists. Here are some things you should do with this file:

  1. If your engine is missing this file, copy the one in the sample app to your engine.
  2. Make sure this file is executable on your file system. If it isn’t, chmod +x bin/rails
  3. Open the file and find the line that sets the ENGINE_PATH constant. Make sure that line references your engine’s name and not the name of the sample app.

If you take a quick look at this file, you may notice that it looks a little different then the bin/rails file you would find in a full Rails application. This version of bin/rails has been configured to work with engines. If you try to execute a command like rails new from inside the engine’s root folder, you’ll get an error message like the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Error: Command not recognized
Usage: rails COMMAND [ARGS]

The common Rails commands available for engines are:
 generate    Generate new code (short-cut alias: "g")
 destroy       Undo code generated with "generate" (short-cut alias: "d")

All commands can be run with -h for more information.

If you want to run any commands that need to be run in context
of the application, like `rails server` or `rails console`,
you should do it from application's directory (typically test/dummy).

When you execute rails in the shell, it’s smart enough to know to execute the bin/rails version inside your engine instead of the more general version.

Setup Rakefile

Rakefile is another file where we need to do some work. Merge the contents of Rakefile from the sample app into your engine’s Rakefile if there are differences. The most important lines that may be missing from your Rakefile are:

1
2
3
4
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
load 'rails/tasks/statistics.rake'
Bundler::GemHelper.install_tasks

Make sure the path that sets APP_RAKEFILE says ../spec/dummy/Rakefile instead of ../test/dummy/Rakefile.

Also, depending on how you created your engine, your engine may simply have require “bundler/gem_tasks” . The sample engine probably has:

1
2
3
4
5
begin
  require 'bundler/setup'
rescue LoadError
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks`
end

Use the version from the sample engine.

Once you’ve made these lines you’ll be able to execute rake commands like rake db:drop from your engine’s root folder and the command will act on your dummy application.

Install RSpec

With the preliminary stuff out of the way, let’s finally install RSspec. Open your engine’s .gemspec file and add:

1
s.add_development_dependency "rspec-rails", "~> 3.4.2"

Next, bundle the dependencies to make sure rspec gets installed:

1
bundle

Now, invoke the rspec generator:

1
rails g rspec:install

This will create a spec/spec_helper.rb file and spec/rails_helper.rb file. Open rails_helper.rb and find the following line:

1
require File.expand_path('../../config/environment', __FILE__)

Change it to the line below (which tells RSpec how to load the application):

1
require File.expand_path("../dummy/config/environment.rb", __FILE__)

Automatically require rails_helper.rb (Optional)

When writing a new spec, you would typically add require “rails_helper” to the top of the file. You can simplify this by opening the .rspec file and changing

1
--require spec_helper

to

1
--require rails_helper

This change it will cause RSpec to automatically require rails_helper so you don’t have to include it in each spec file. There may be some performance issues depending on your particular tests, so we can’t recommend this 100%, but it’s probably helpful to do it.

Add Other Gem Dependencies

You may have noticed that your dummy application doesn’t have its own Gemfile. If you take a look at spec/dummy/config/boot.rb you’ll see that it tells bundler to use the Gemfile from your engine instead. If your dummy app needs other gems installed, you can add them as development dependencies in the engine’s .gemspec file or the engine’s Gemfile.

At this point, you probably have a dependency on sqlite3 because your dummy app is using it for the database. There’s nothing stopping you from using Postgres or MySQL, but sqlite3 is probably a good place to start. Make sure the following is in your engine’s .gemspec file:

1
spec.add_development_dependency "sqlite3", "~> 1.3.11"

Testing It All Out

We can now do a couple things to verify everything is working properly. First, rebuild the test database to make sure the rake commands are working properly.

1
2
3
rake db:drop
rake db:create
rake db:migrate

If everything works, we should have test.sqlite3 and development.sqlite3 files in the spec/dummy/db folder. Depending on your version of Rails, you may need to specify RAILS_ENV=test when running the above rake commands.

Next, kickoff RSpec by executing

1
rspec

If it’s working, it will report that zero tests were executed. Finally, try and run the dummy app and open it in the browser.

1
2
cd spec/dummy
rails s -b 0.0.0.0

Hopefully, you can fire up your browser and view the working dummy application.

Tips and Going Further

And just like that, we’re done! If you plan on using gems like database_cleaner, capybara or factory_girl you simply need to add the gems as a development dependency in the engine’s .gemspec or Gemfile, then configure them as you normally would.

A Helpful Hint About Gem Dependencies

I recently wrote a gem that had a dependency on the font-awesome-rails gem. It loaded font-awesome and provided some extra helpers to the host application that used the engine. Everything worked great in a full Rails app, but when I tried to get my engine working with the dummy application I kept getting font-awesome import errors. The issue turned out to be the sass-rails gem. This gem is added by default to most Gemfile’s in a Rails app. However, nothing was telling my dummy app to load this gem.

The solution was to simply add sass-rails as a development dependency inside the engine. The lesson learned here is you have to be mindful about requiring everything your dummy app needs to run. A full Rails app will load some extra gems that aren’t present by default for dummy apps in an engine.

Renaming the Dummy App

If you’re not a fan of naming the dummy app “Dummy”, you’re not alone. Many people think the term “dummy” doesn’t accurately reflect the purpose of the application. If you peek into a couple engines on GitHub you’ll run across some alternative names like: sample_app, sample, test_app, and rails_app.

Changing the name of the application is easy. This is how you would rename it to “Rails App”:

  1. Rename your spec/dummy folder to spec/rails_app.
  2. Open the spec/rails_app/config/application.rb file and change module Dummy to module RailsApp.
  3. Search all the files in your engine for spec/dummy. Change the results to spec/rails_app.
  4. Change spec/dummy/config/initializers/session_store.rb to use _rails_app_session as the key.

On the other hand, the term “dummy” application is built into Rails and it was the good enough to become the default. Maybe it’s best to stick with dummy since it’s common and people will understand what it means, even if it’s not perfect. The choice is yours.

What About Cucumber?

We’re glad you asked. Configuring cucumber is very similar. Check out our article on configuring cucumber to work for more information.

We hope you found this article useful. If you see any mistakes, missing features or ways to improve it, please let us know in the comments below so we can update its contents. If you're willing to link to us, we would sincerely appreciate it!

Corlew Solutions is a Web Design and Web Application Development company based in Fairfax Virginia, minutes away Washington D.C. If you're looking for great web design from the Northern Virginia area or web design from the Washington D.C. area we can help. Contact Us today!

comments powered by Disqus