Skip to content

Instantly share code, notes, and snippets.

@liuzxc
Forked from supertopher/rspec.md
Created June 4, 2018 05:50
Show Gist options
  • Save liuzxc/95dd0196bf2a2078e96e4aa7039a3171 to your computer and use it in GitHub Desktop.
Save liuzxc/95dd0196bf2a2078e96e4aa7039a3171 to your computer and use it in GitHub Desktop.
rspec best practices

Automated Testing.

Testing is helpful for ensuring that your code runs (driver code). This is to make sure that current features work, old features still work, and future work will be easily tested. By default, every Rails application has three environments: development, test, and production.

Rails offers three kinds of testing:

  • Unit tests: 
In the context of Rails, unit tests are meant primarily to cover the domain logic in your models, which include things like validations, calculations, search methods, and any other interesting functionality that your models implement.
  • Functional tests: These provide a way to verify that the actions for a single controller are working as expected, and allow you to do things such as post data to a specific action and verify the correct response is returned
  • Integration tests: Any given session with a Rails application will span across several models and controllers. Integration tests provide a way to test those kinds of interactions. Essentially, an integration test is written at the story level, allowing you to verify the correct behavior of your application for a given use case.

RSpec is testing tool for the Ruby programming language.

  • Tests should be reliable
  • Tests should be easy to write
  • Tests should be easy to understand

Note: If you have rails 4 you can run a specific version of rails new with ruby rails new _3.2.13_ your_app

Installing rspec with rails is easy and fun! use:

  • rails new your_project_name -T This will make a new application skeleton without test-unit
  • cd your_project_name
  • open your gemfile and add:
  group :development, :test do
    gem 'rspec-rails'
    gem 'factory_girl_rails'
    gem 'faker'
  end
  • bundle install
  • rails g rspec:install

please note this won't work unless you have included rake in your gemfile and then run bundle

============

So what did we just install?

  • rspec-rails: includes RSpec itself in a wrapper to make it play nicely with Rails 3.
  • when you generate just about anything it will also generate basic tests for whatever you generated along with it. Generate is a bad word now, but this will be nice in the future
  • factory_girl_rails: replaces Rails’ default fixtures for feeding test data to the test suite with much more preferable factories.
  • faker generates names, email addresses, and other placeholders for factories.

How to test

The following code is testing the very familiar numberal to arabic in Rspec:

require_relative "numeral_calc.rb"

  pairs = [
    [1, "I"],
    [2, "II"],
    [4, "IV"],
    [5, "V"],
    [6, "VI"],
    [7, "VII"],
    [9, "IX"],
    [10, "X"],
    [11, "XI"],
    [1982, "MCMLXXXII"]
  ]

describe "Numeral Function" do

  pairs.each do |limit, glyph|
    it "should return #{limit} for #{glyph}" do
      convert_arabic(glyph).should == limit
    end
  end

end # Numeral Function
  • the output of this in the terminal give you easy to read code explaining your failing and passing tests
  • Each of these specific tests describes "Numeral function" Simlarily your tests covering lets say a user controller will be
  describe "user controller" do
    it "should allow a user with passing validation to be created" do
      User.create(name: "passing name").should == User.find_by_name("passing name")
  end
  
  • rspec test descriptions like commit messages should be concise and descriptive to someone who doesn't know your code

Testing Examples

Be clear about what method you are describing

BAD

describe 'the authenticate method for User' do
describe 'if the user is an admin' do

GOOD

describe '.authenticate' do
describe '#admin?' do

Use contexts

BAD

it 'has 200 status code if logged in' do
  response.should respond_with 200
end

GOOD

context 'when logged in' do
  it { should respond_with 200 }
end

TBC

Testing with the Factory Girl gem

require 'spec_helper' 

describe Contact do 
  it "has a valid factory" do 
  Factory(:contact).should be_valid 
end 
  it "is invalid without a firstname" do 
    Factory.build(:contact, firstname: nil).should_not be_valid 
  end 
  it "is invalid without a lastname" do 
    Factory.build(:contact, lastname: nil).should_not be_valid 
  end 
  it "returns a contact's full name as a string" do 
    Factory(:contact, firstname: "John", lastname: "Doe").name.should == "John Doe" 
  end 

  describe "filter last name by letter" do 
    before :each do 
      @smith = Factory(:contact, lastname: "Smith") 
      @jones = Factory(:contact, lastname: "Jones") 
      @johnson = Factory(:contact, lastname: "Johnson") 
    end 
    
    context "matching letters" do 
      it "returns a sorted array of results that match" do 
        Contact.by_letter("J").should == [@johnson, @jones] 
      end 
    end 
    
    context "non-matching letters" do 
      it "does not return contacts that don't start with the provided letter" do 
        Contact.by_letter("J").should_not include @smith 
      end 
    end 
  end 
end 

For more information, please visit: http://everydayrails.com/2012/03/19/testing-series-rspec-models-factory-girl.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment