Skip to content

Instantly share code, notes, and snippets.

@spencereldred
Last active August 29, 2015 13:59
Show Gist options
  • Save spencereldred/10484221 to your computer and use it in GitHub Desktop.
Save spencereldred/10484221 to your computer and use it in GitHub Desktop.
Rspec Test Lesson

RSpec Testing

  • TDD - Test Driven Development

Student Learning Objectives:

  • By the end of this lesson you should be able to:

    • 1) Set up an rspec testing environment for a ruby project

    • 2) Write basic describe/it blocks to test an existing Class

    • 3) Go through Red/Green/Refactor routine to create a Class with tests

Why do we write tests

  • Helps you organize your thoughts to understand the problem or feature you are trying to code.

  • Go back to edit your program after a period of time, you can review the tests to see how the program is supposed to work.

  • You can refactor you code with some degree of assuance that your program still works.

  • For every new edit you want to release, you don't want to have to test all the buttons and links in you web site

  • On a project team, you write code that could break someone else's code.

  • On a project team, someone writes code that could break your code.

Test Driven Development Flow:

Mantra: Red, Green, Refactor

  • "Red" => write test, run test, test fails

  • "Green" => write just enough code to make it pass

  • "Refactor" => look for ways to improve your code

1) Setup rspec test environment:

Installation

$ gem install rspec
$ rspec --v
$ rspec --help

Go to your working folder for todays lesson

$ rspec --init
	create spec/spec_helper.rb
	create .rspec
  • rspec --init created:

    *

    a spec folder with the spec_helper.rb file in it

    *

    a .rspec file that is for your configuration

Edit .rspec ( use: "ls -la" to see the hidden files)

Open .rspec and add the lines:

--color
--format documentation

Review spec_helper.rb

  • spec_helper.rb makes the RSpec tests are run in a random order.

  • Beware of dependencies, tests should be indepentent.

      $ cd spec
      $ cat spec_helper.rb
    
  • spec_helper.rb:

      # This file was generated by the `rspec --init` command. Conventionally, all
      # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
      # Require this file using `require "spec_helper"` to ensure that it is only
      # loaded once.
      #
      # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
      RSpec.configure do |config|
      	config.treat_symbols_as_metadata_keys_with_true_values = true
      	config.run_all_when_everything_filtered = true
      	config.filter_run :focus
    
      	# Run specs in random order to surface order dependencies. If you find an
      	# order dependency and want to debug it, you can fix the order by providing
      	# the seed, which is printed after each run.
      	#     --seed 1234
      	config.order = 'random'
      end
    

#2) Write basic describe/it blocks to test an existing Class

RSpec Testing Syntax Structure:

  • describe blocks

  • context block (optional)

  • it blocks

Sample code

describe Square do
  it "has a side attribute" do
    test code
  end

  it "has an area method" do
    test code
  end
end

Special blocks: Before & After

  • Due to the random order of tests, you can't rely on the conditions of one test to setting up the other.

  • Eliminate the "order dependencies".

  • Before block runs before each test

      before(:each) do  
      	@my_square = Square.new(5)
      end
      
      after(:each) do  
      	@my_square = nil
      end
    
  • After block runs after each test

square.rb

class Square
	attr_accessor :side
	
	def initialize(side)
		@side = side
	end
	
	def area
		@side ** 2
	end
	
	def perimeter
		@side * 4
	end
	
	def to_s
		"I am a square. My sides are of length: #{@side}. My area is: #{self.area}, and my perimeter is: #{self.perimeter}"
	end
end

square_spec.rb

require './square'
require 'spec_helper'

describe Square do  

	before(:each) do  
		@my_square = Square.new(5)
	end

	it "should have a side" do
	    my_square = Square.new(5)
		@my_square.side.should eq(5)
	end

end

3) Go through Red/Green/Refactor routine to create a Class with tests

Employee Code Along

Let's design an Employee class:

  • What attributes and behaviors should our Employee object have?

Create two files: employee.rb and employee_spec.rb

employee_spec.rb:

require './employee'
require 'spec_helper'

describe Employee do
  
  before(:each) do
    @employee = Employee.new("YourName")
  end

  it "has a name " do
  	@employee.name.should eq("YourName")
  end
  
  it "can change the name" do
    @employee.name = "NewName"
    @employee.name.should eq("YourName")
  end
  
end

employee.rb

class Employee
  attr_accessor :name

  def initialize(name)
	@name = name
  end

end

employee_spec.rb:

require './employee'
require 'spec_helper'

describe Employee do
  
  before(:each) do
    @employee = Employee.new("YourName")
  end

  it "has a name " do
  	@employee.name.should eq("YourName")
  end
  
  it "can change the name" do
    @employee.name = "NewName"
    @employee.name.should eq("YourName")
  end
  
end

list of commands like eq

should vs. expect

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