Save 37% off PRO during our Black Friday Sale! »

Straight Up Rspec: A Neat Ruby BDD Tool

99e2a6afab542ba98a9f1d1cae6c9670?s=47 PromptWorks
February 21, 2014
10

Straight Up Rspec: A Neat Ruby BDD Tool

99e2a6afab542ba98a9f1d1cae6c9670?s=128

PromptWorks

February 21, 2014
Tweet

Transcript

  1. Straight Up Rspec a neat Ruby BDD tool

  2. Organization $0 Options $0 Refactoring Exercise $0 Configuration $0 Other

    Libraries $0 The Menu
  3. Organization

  4. .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

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

    file } spec_helper
  6. Options

  7. $ rspec spec -f documentation

  8. $ rspec spec/martini_spec.rb -l 16

  9. $ rspec spec -t slow

  10. Barkeep github.com/gsterndale/barkeep a refactoring exercise

  11. 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
  12. 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
  13. 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
  14. 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()
  15. 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()
  16. 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
  17. martini_spec.rb describe Barkeep::Martini do include AttributeMatchers it { should have_attribute(:booze)

    } it { should have_attribute(:garnish) } end Derived subject()
  18. support/configure.rb RSpec.configure do |config| config.include AttributeMatchers end ! config.include()

  19. martini_spec.rb describe Barkeep::Martini do it { should have_attribute(:booze) } it

    { should have_attribute(:garnish) } end config.include()
  20. 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
  21. whiskey_spec.rb describe Barkeep::Whiskey do it { should have_attribute(:booze) } it

    { should have_attribute(:glass) } end Whiskey Spec
  22. 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
  23. support/examples/drink.rb share_examples_for "a drink" do it { should have_attribute(:booze) }

    it { should have_attribute(:glass) } end Shared Example Group
  24. whiskey_spec.rb describe Barkeep::Whiskey do it_should_behave_like "a drink" end Whiskey Spec

  25. martini_spec.rb describe Barkeep::Martini do it_should_behave_like "a drink" it { should

    have_attribute(:garnish) } end Martini Spec
  26. 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
  27. 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()
  28. 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()
  29. 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()
  30. 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()
  31. 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()
  32. 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()
  33. 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()
  34. 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()
  35. 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()
  36. Configuration

  37. 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
  38. 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
  39. 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
  40. 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
  41. Other Libraries

  42. Rspec::Rails

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

  44. Shoulda::Matchers

  45. 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
  46. CHEERS

  47. 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
  48. 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
  49. 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!()