Tuesday, November 20, 2018

RSpec Tutorial - How To Set Up Tests For Ruby / Rails Applications

Like many Ruby developers, the thought of having to test my code sent shivers down my spell. Not only did I have no idea about software testing (IE the regulations etc), but I've never used RSpec before.

Fortunately, when I did start using the system, things became much simpler.

RSpec is a testing framework for Ruby, and Rails. The system is extremely versatile, and meant to provide a simple framework for testing various features within applications or plugins.

The system works as intuitively as possible - meaning that each "test" is meant to deliver an expected result - allowing the developer to create an effective overview of the various pieces of functionality of a system, as well as giving the ability to extend the scope as required.

I will explain how it works in this post ...

What Is RSpec?

RSpec is a freely open source "gem" for Ruby, maintained by the core Ruby group.

The gem is available on Github, along with a number of others - most notably the "rspec-rails" gem (which was specifically designed for Rails).

The gem basically provides developers with a "framework" which can be called via the "rspec" command. This allows for integration with CI suites such as TravisCI and CoverAlls.

The point of having the likes of RSpec is to facilitate the creation of "unit tests" and "integration tests" - both of which are being a staple of the traditional software development pipeline.

Having the ability to thoroughly, and extensively, test a Ruby application - with a framework which is ubiquitous and extensible as the language itself - is one of the reasons why the Ruby ecosystem is held in such high regard.

For the first time, without the need of expensive software or large IDE integration - teams of developers can create software that works across platforms and technology-sets.

Thus, when considering developing in Ruby, the undering value of RSpec can not be overstated.

How It Works

RSpec has to be initialized within a plugin / application.

It typically lives in the "spec" directory - but this can also be "test".

To initialize RSpec - like most things in Ruby, it's best to follow the guidelines of what's already been developed - by using the "rspec --init" CLI command.

Initializing the framework populates the / spec folder with a "spec_helper.rb" file and populates it with a base amount of configuration options.

The "spec_helper.rb" file sits at the core of all RSpec functionality, and is thus extremely important.

Within the file, all of the configuration settings for an application are stored. This is where you are meant to include the various files required to get the test suite integrated into your script / application.

If you're able to run the "rspec --init" command (after adding "rspec" to your script's Gemfile), you'll be set to start the next step.

Setting It Up

After getting the "spec helper" set up, the next step is to get the various elements of the integration suite called.

This is a certain manual process, and - particularly if using Rails - can involve some steps outside the "traditional" rulebook.

The most important step in this case is to get a "dummy" Rails app set up.

I will not go into too much detail, but it's required if you're creating a rails gem (for example), and not something that can be done directly through rspec itself.

To do this, you need to basically create a fake "engine" from which you're able to extract the dummy Rails app:

  cd some_path_where_your_engine_IS_NOT 

rails plugin new YOUR_ENGINE_NAME --mountable --dummy-path = spec / dummy --skip-test-unit

  mv YOUR_ENGINE_NAME / spec / dummy / real / path / to / YOUR_ENGINE_NAME / spec 

rm -rf YOUR_ENGINE_NAME

This creates a / spec folder with a dummy Rails app, spec_helper.rb and another file which is not important.

Doing the above ensures that RSpec is set up correctly for Rails.

Again, without having the details on your specific application - if you need further information, you're welcome to email me (email in profile).

Performing Tests

Once you've got rspec set up, you need to sort out the tests.

This is a reliably simple process - it just takes some time to figure out the various methods through which you're able to ascertain particular results.

The most important thing to state is that there are a number of different types of test:

  • Routing tests
  • Controller tests
  • Model tests
  • Feature tests
  • View tests
  • Mailer tests
There are two ways to make sure these work - either by creating folders within your main / spec folder (/ spec / models or / spec / features etc) OR to simply use the "type :: feature" option when declaring tests.

The way this works becomes clearer when you consider how tests actually work.

Every "test" in RSpec needs to be wrapped in a "describe" block. Each file needs to pull from the RSpec class proper (RSpec.describe ___), but all the others can just be "describe":

# spec / models / model_spec.rb

RSpec.describe Model do

describe "has email method" do

it {___}

end

end

The way you create your tests is with the "it" method - used to describe (as verbosely as possible) what each feature is meant to do.

Within the "it" block, you're able to use a number of different methods, ranging from "expect" to "should" - to provide the system with the ability to determine the particular results required from the script / application.

From here, you're able to then create in-context placeholders, using such methods as "let" to provide context for each test.

Whilst I could write more tests, the bottom line is that this should give you a strong overview as to what's required to get it all working. After this, you just need to be able to write as many tests as required.