Slide 1

Slide 1 text

Straight Up Rspec a neat Ruby BDD tool

Slide 2

Slide 2 text

Organization $0 Options $0 Refactoring Exercise $0 Configuration $0 Other Libraries $0 The Menu

Slide 3

Slide 3 text

Organization

Slide 4

Slide 4 text

.rspec lib/barkeep.rb lib/barkeep/martini.rb spec/spec_helper.rb spec/support/configure.rb spec/support/matchers/drink.rb spec/martini_spec.rb

Slide 5

Slide 5 text

spec_helper.rb require 'rspec' require 'barkeep' ! Dir["#{File.dirname(__FILE__)}/support/**/*.rb"]. each {|file| require file } spec_helper

Slide 6

Slide 6 text

Options

Slide 7

Slide 7 text

$ rspec spec -f documentation

Slide 8

Slide 8 text

$ rspec spec/martini_spec.rb -l 16

Slide 9

Slide 9 text

$ rspec spec -t slow

Slide 10

Slide 10 text

Barkeep github.com/gsterndale/barkeep a refactoring exercise

Slide 11

Slide 11 text

martini_spec.rb describe "Barkeep::Martini" do before do @martini = Barkeep::Martini.new end it "should have an attribute named booze" do @martini.should respond_to(:booze) @martini.should respond_to(:booze=) end it "should have an attribute named garnish" do @martini.should respond_to(:garnish) @martini.should respond_to(:garnish=) end end Martini Spec Draft

Slide 12

Slide 12 text

have_attribute.rb module AttributeMatchers ! Spec::Matchers.define :have_attribute do |name| match do |target| getter = name.to_sym setter = (name.to_s + "=").to_sym target.respond_to?(getter) && target.respond_to?(setter) end end ! end Custom Matcher

Slide 13

Slide 13 text

martini_spec.rb describe "Barkeep::Martini" do include AttributeMatchers before do @martini = Barkeep::Martini.new end it "should have an attribute named booze" do @martini.should have_attribute(:booze) end it "should have an attribute named garnish" do @martini.should have_attribute(:garnish) end end Custom Matcher

Slide 14

Slide 14 text

martini_spec.rb describe "Barkeep::Martini" do include AttributeMatchers subject { Barkeep::Martini.new } it "should have an attribute named booze" do subject.should have_attribute(:booze) end it "should have an attribute named garnish" do subject.should have_attribute(:garnish) end end subject()

Slide 15

Slide 15 text

martini_spec.rb describe "Barkeep::Martini" do include AttributeMatchers subject { Barkeep::Martini.new } it "should have an attribute named booze" do should have_attribute(:booze) end it "should have an attribute named garnish" do should have_attribute(:garnish) end end Implicit subject()

Slide 16

Slide 16 text

martini_spec.rb describe "Barkeep::Martini" do include AttributeMatchers subject { Barkeep::Martini.new } it { should have_attribute(:booze) } it { should have_attribute(:garnish) } end DRY Messages

Slide 17

Slide 17 text

martini_spec.rb describe Barkeep::Martini do include AttributeMatchers it { should have_attribute(:booze) } it { should have_attribute(:garnish) } end Derived subject()

Slide 18

Slide 18 text

support/configure.rb RSpec.configure do |config| config.include AttributeMatchers end ! config.include()

Slide 19

Slide 19 text

martini_spec.rb describe Barkeep::Martini do it { should have_attribute(:booze) } it { should have_attribute(:garnish) } end config.include()

Slide 20

Slide 20 text

martini_spec.rb describe "Barkeep::Martini" do before do @martini = Barkeep::Martini.new end it "should have an attribute named booze" do @martini.should respond_to(:booze) @martini.should respond_to(:booze=) end it "should have an attribute named garnish" do @martini.should respond_to(:garnish) @martini.should respond_to(:garnish=) end end Original Draft

Slide 21

Slide 21 text

whiskey_spec.rb describe Barkeep::Whiskey do it { should have_attribute(:booze) } it { should have_attribute(:glass) } end Whiskey Spec

Slide 22

Slide 22 text

martini_spec.rb describe Barkeep::Martini do it { should have_attribute(:booze) } it { should have_attribute(:glass) } it { should have_attribute(:garnish) } end Martini Spec

Slide 23

Slide 23 text

support/examples/drink.rb share_examples_for "a drink" do it { should have_attribute(:booze) } it { should have_attribute(:glass) } end Shared Example Group

Slide 24

Slide 24 text

whiskey_spec.rb describe Barkeep::Whiskey do it_should_behave_like "a drink" end Whiskey Spec

Slide 25

Slide 25 text

martini_spec.rb describe Barkeep::Martini do it_should_behave_like "a drink" it { should have_attribute(:garnish) } end Martini Spec

Slide 26

Slide 26 text

support/examples/drink.rb share_examples_for "a drink" do it { should have_attribute(:booze) } it { should have_attribute(:glass) } ! it "should have an ingredients Array" do subject.ingredients.should be_a Array end end Whiskey & Martini #ingredients

Slide 27

Slide 27 text

martini_spec.rb describe Barkeep::Martini do it_should_behave_like "a drink" it { should have_attribute(:garnish) } it { should have_attribute(:mixer) } context "with a mixer" do before do @mixer = 'vermouth' subject.mixer = @mixer end it "should include mixer in ingredients" do subject.ingredients.should include @mixer end end context()

Slide 28

Slide 28 text

martini_spec.rb describe Barkeep::Martini do it_should_behave_like "a drink" it { should have_attribute(:garnish) } it { should have_attribute(:mixer) } context "with a mixer" do let(:mixer) { 'vermouth' } before { subject.mixer = mixer } it "should include mixer in ingredients" do subject.ingredients.should include mixer end end end let()

Slide 29

Slide 29 text

martini_spec.rb describe Barkeep::Martini do it_should_behave_like "a drink" it { should have_attribute(:garnish) } it { should have_attribute(:mixer) } context "with a mixer" do let(:mixer) { 'vermouth' } before { subject.mixer = mixer } its(:ingredients) { should include mixer } end end its()

Slide 30

Slide 30 text

martini_spec.rb describe Barkeep::Martini do it_should_behave_like "a drink" it { should have_attribute(:garnish) } it { should have_attribute(:mixer) } end ! describe Barkeep::Martini, ".new with mixer" do let(:mixer) { 'vermouth' } subject { Barkeep::Martini.new(:mixer => mixer) } its(:ingredients) { should include mixer } end its()

Slide 31

Slide 31 text

martini_spec.rb describe Barkeep::Martini, ".new with mixer" do let(:mixer) { 'vermouth' } subject { Barkeep::Martini.new(:mixer => mixer) } its(:ingredients) { should include mixer } its(:ingredients) { should have(1).items } end have()

Slide 32

Slide 32 text

martini_spec.rb describe Barkeep::Martini, ".new with mixer" do let(:mixer) { 'vermouth' } subject { Barkeep::Martini.new(:mixer => mixer) } its(:ingredients) { should include mixer } it { should have(1).ingredients } end have()

Slide 33

Slide 33 text

martini_spec.rb describe Barkeep::Martini do let(:mixer) { 'vermouth' } it "should include mixer in ingredients" do expect { subject.mixer = mixer }. to change { subject.ingredients }. from( [] ). to [ mixer ] end end expect()

Slide 34

Slide 34 text

terminal_spec.rb describe Barkeep::Terminal, "#printer" do let(:ones) { "1.1.1.1" } let(:epson) { double("Espon 5000") } subject { Barkeep::Terminal.new(:ip => ones) } ! before do Printer.stub(:new) { epson } end ! it "should have a printer" do subject.printer.should eq epson end end stub()

Slide 35

Slide 35 text

terminal_spec.rb describe Barkeep::Terminal, "#printer" do let(:ones) { "1.1.1.1" } let(:epson) { double("Espon 5000") } subject { Barkeep::Terminal.new(:ip => ones) } ! it "should have a printer" do Printer.should_receive(:new). with(:ip => ones) { epson } subject.printer end end should_receive()

Slide 36

Slide 36 text

Configuration

Slide 37

Slide 37 text

support/configure.rb RSpec.configure do |config| config.include MyMartiniMatchers config.include ModelHelpers, :type => :model end ! ! # spec/model/martini_spec.rb ! describe Martini, :type => :model do … end RSpec.configure

Slide 38

Slide 38 text

support/configure.rb RSpec.configure do |config| config.before(:all) {} # run once config.before(:each) {} # run before each example config.after (:each) {} # run after each example config.after (:all) {} # run once ! # run before each example of type :model config.before(:each, :type => :model) {} end RSpec.configure

Slide 39

Slide 39 text

support/configure.rb RSpec.configure do |c| c.filter_run :focus => true c.run_all_when_everything_filtered = true end ! # in any spec file describe "something" do it "does something", :focus => true do # .... end end Inclusion

Slide 40

Slide 40 text

support/configure.rb RSpec.configure do |c| c.exclusion_filter = { :ruby => lambda {|version| !(RUBY_VERSION.to_s =~ /^#{version.to_s}/) }} end ! # in any spec file describe "something" do it "does something", :ruby => 1.8 do # .... end it "does something", :ruby => 1.9 do # .... Exclusion

Slide 41

Slide 41 text

Other Libraries

Slide 42

Slide 42 text

Rspec::Rails

Slide 43

Slide 43 text

response.should redirect_to("some/url") response.should be_success response.should have_tag("div", "some text")

Slide 44

Slide 44 text

Shoulda::Matchers

Slide 45

Slide 45 text

describe User do it { should belong_to(:account) } it { should have_many(:posts) } it { should validate_presence_of(:email) } it { should allow_value("f@b.com").for(:email) } it { should_not allow_value("test").for(:email) } end

Slide 46

Slide 46 text

CHEERS

Slide 47

Slide 47 text

spec/user_spec.rb describe User, ".admin_names" do let(:admin) { User.create!(:admin => true, :first => "Clark", :last => "Kent")} let(:avg_joe) { User.create!(:admin => false, :first => "Joe", :last => "Shmo")} subject { admin_names } ! it { should include "Clark Kent" } it { should_not include "Joe Shmo" } end let() gotcha

Slide 48

Slide 48 text

spec/user_spec.rb describe User, ".admin_names" do let(:admin) { User.create!(:admin => true, :first => "Clark", :last => "Kent")} let(:avg_joe) { User.create!(:admin => false, :first => "Joe", :last => "Shmo")} subject { User.admin_names } before { admin && avg_joe } ! it { should include "Clark Kent" } it { should_not include "Joe Shmo" } end let() work-around

Slide 49

Slide 49 text

spec/user_spec.rb describe User, ".admin_names" do let!(:admin) { User.create!(:admin => true, :first => "Clark", :last => "Kent")} let!(:avg_joe) { User.create!(:admin => false, :first => "Joe", :last => "Shmo")} subject { User.admin_names } ! it { should include "Clark Kent" } it { should_not include "Joe Shmo" } end let!()