Testing with RSpec
Resources
Getting Started
Install rspec, rspec-core, rspec-expectations, rspec-mocks, rspec-support
$ gem install rspec
Get help
$ rspec --help
Basics
- Describe the methods of the class you are testing
- Initialize a new object
- Call methods on the object
- The ‘expect’ clause tests what we expect to happen
require "rspec"
RSpec.describe Car do
describe "#new" do
it "creates a new instance when passed make, model, and year" do
car = Car.new("Tesla", "Model S", 2014)
expect(car).to be_a(Car)
end
it "initializes the odometer to zero" do
car = Car.new("Toyota", "Prius", 2010)
expect(car.odometer).to eq(0)
end
end
end
Test Driven Development
- Write a test case, and run it. It should fail. (Red)
- Write only enough code to make the test pass. (Green)
- Cleanup code, extract methods, eliminate duplication. (Refactor)
- Repeat
Pretty Output: Create a .rspec file
echo "--color --format doc" > .rspec
Exercises
- Circle class
- Pig Latin
- Blackjack
Circle
- initialize with a radius and optional position
- instance methods:
- radius:
r
- diameter:
d = 2r
- area:
a = πr^2
- point within circle:
(x1 - x)^2 + (y1 - y)^2 <= r^2
- radius:
- class methods:
- total area
Pig Latin
- initialize with a string
- instance methods:
- translate
- rules:
- starts with consonant, move to end, append ‘ay’
- starts with vowel, append ‘way’
Blackjack
- classes:
- Card
- Deck
- Hand
# circle_spec.rb
require "rspec"
require_relative "circle"
DELTA = 0.01
RSpec.describe Circle do
describe "#initialize" do
it "takes a value for the radius" do
circle = Circle.new(5)
expect(circle).to be_a(Circle)
end
it "takes an optional values for the center point" do
circle = Circle.new(5, 1, 2)
expect(circle).to be_a(Circle)
expect(circle.x).to eq(1)
expect(circle.y).to eq(2)
end
end
describe "#radius" do
it "returns the value for radius" do
circle = Circle.new(5)
expect(circle.radius).to eq(5)
end
end
describe "#diameter" do
it "returns 10 when the radius is 5" do
circle = Circle.new(5)
expect(circle.diameter).to eq(10)
end
it "returns 20 when the radius is 10" do
circle = Circle.new(10)
expect(circle.diameter).to eq(20)
end
it "returns 0.5 when the radius is 0.25" do
circle = Circle.new(0.25)
expect(circle.diameter).to eq(0.5)
end
end
describe "#area" do
it "returns 314.16 when radius is 10" do
circle = Circle.new(10)
expect(circle.area).to be_within(DELTA).of(314.16)
end
it "returns 12.57 when radius is 2" do
circle = Circle.new(2)
expect(circle.area).to be_within(DELTA).of(12.57)
end
it "returns 0.785 when radius is 0.5" do
circle = Circle.new(0.5)
expect(circle.area).to be_within(DELTA).of(0.785)
end
end
describe "#contains_point?" do
it "returns true for a point within the circle" do
circle = Circle.new(1)
expect(circle.contains_point?(0.25, 0.25)).to be true
end
it "returns true for a point on the edge of a circle" do
circle = Circle.new(1)
expect(circle.contains_point?(0, 1)).to be true
end
it "returns false for a point outside of the circle" do
circle = Circle.new(1)
expect(circle.contains_point?(4, 3)).to be false
end
end
end
# game_spec.rb
# install rspec, rspec-core, rspec-expectations, rspec-mocks, rspec-support
# $ gem install rspec
# get help
# $ rspec --help
# game spec
require "rspec"
require_relative "game"
RSpec.describe Game do
describe "#score" do
it "returns 0 for an all gutter game" do
game = Game.new
20.times { game.roll(0) }
expect(game.score).to eq(0)
end
end
end