Skip to content
dwayne.fm

gem rspec-rails

Hieroglyphs3 min read

What is Test Driven Development

“Test-driven development” refers to a style of programming in which three activities are tightly interwoven: coding, testing (in the form of writing unit tests), and design (in the form of refactoring).

If you've written a functioning application and didn't write tests, you've practiced in "Error Driven Development". As the name suggests, you've written of code, and relied on the errors in your terminal or browser to know if it was written properly.

There is nothing wrong with Error Driven Development per se. However, as your app scales (grows), and accumulates hundreds of migration files, endless endpoints / routes, and countless interwoven models, relying on errors as they arise is simply not feasible.

Why Test?

Pros

There are many reasons why TDD is important. I'll rattle off a few like the good TDD evangelist that I am. As previously mentioned, testing helps to maintain some semblance of order as your application scales. Additionally:

  1. It pushes you to write cleaner code!
    I think back to middle school and having to write book reports (or any paper in school, really). First you write an outline, then the paper. Writing an outline first generally helped in keeping the execution of the paper, and it's content more organized. The same can be said of Test Driven Development.

  2. Safer refactoring.
    Let's suppose you step away from a part of the app for a few months. Upon return, you've identified code you can refactor. Tests will aide in keeping your refactor, reasonable.

  3. Living Documentation!
    In my humble opinion, this is the greatest benefit to writing tests. Tests act as documentation for your application. If I arrive to unfamiliar code and I'm curious as to how this area of the application might behave, I can look at the test(s) to get an idea.

Cons

Time. It takes time and patience to plan and craft well written tests. However the time spent on writing tests upfront, saves so much time in the long run. So really there are no cons; WRITE TESTS!

Types of Tests

TDD requires a minimum of two styles of tests to successfully cover an application: Unit Tests and Integration Tests.

In the essence of brevity, we will explore simple Unit Testing in Rails, and I will save Integration Tests for a subsequent post.

Unit Tests with RSpec

If you are a Flatiron student and reading this, you are in luck. You have an entire curriculum worth of tests for examples of well written tests. If you are not a Flatiron student and need some examples of tests, check out opensourcerails.com. Quite frankly, whenever I am in search of examples of well written code, I look at open source projects.

Installing RSpec

I am assuming that you are working with a Rails app that does not have a testing unit already installed. If you are starting from scratch, run rails new your_app_name -T. The -T flag will tell Rails to skip adding the default testing suite (I believe its name is minitest).

If you

  1. Update Gemfile
    In your development and test group add gem 'rspec-rails', '~> 4.0.2'
1group :development, :test do
2 gem 'rspec-rails', '~> 4.0.2'
3 end
  1. Update Gemfile.lock
    Run $ bundle install to update your gemfile.lock.

  2. Generate necessary files and directories
    Run $ rails generate rspec:install
    This will generate the necessary files and directories necessary for RSpec.

1create .rspec
2 create spec
3 create spec/spec_helper.rb
4 create spec/rails_helper.rb
  1. Format your RSpec readout Locate your .rspec file and add --format documentation to it. That's all. Save and close the file, let's continue on our merry little way.

And thats it! For all intents and purposes RSpec is installed in your application. So like, now what do we do? Well we can test a bunch of things -- Did you set up your models correctly? Are necessary routes available? How about controllers?

Let's start with testing one model, in this case, your User model.

  1. Generating boilerplate User model specs In your terminal run $ rails generate rspec:model user
    You should see
1create spec/models/user_spec.rb

Great! Now lets write a simple test to see if we can save an instance of a User with a first_name attribute. Navigate your user_spec.rb located in spec/models/user_spec.rb

first things first, we want to require require "rails_helper" at the top of every test file. (Doesn't feel very DRY to me, but whatever.)

Next, lets describe our first test for User. We want to check if a user can succesfully be saved with a first name.

1describe User do
2 it "can have a first name" do
3 user = User.new
4 user.first_name = "Dwayne"
5 user.save
6 user.first_name.should == "Dwayne"
7 end
8end

TO BE CONTINUED

LINKS