RSpec functions

7cca11c5257fda526eeb4b1ada28f904?s=47 Kenta Murata
September 21, 2012

RSpec functions

Introduction RSpec functions for my coworkers.

7cca11c5257fda526eeb4b1ada28f904?s=128

Kenta Murata

September 21, 2012
Tweet

Transcript

  1. RSpec functions Kenta Murata 2012.09.21 12೥9݄21೔༵ۚ೔

  2. Only about 2.11.x 12೥9݄21೔༵ۚ೔

  3. Core 12೥9݄21೔༵ۚ೔

  4. Terms require ‘spec_helper’ describe Account do context ‘when the subject

    is an admin’ do subject { described_class.make(:admin => true) } it { should be_admin } end context ‘when the subject is not an admin’ do subject { described_class.make(:admin => false) } it { should_not be_admin } end end 12೥9݄21೔༵ۚ೔
  5. Terms require ‘spec_helper’ describe Account do context ‘when the subject

    is an admin’ do subject { described_class.make(:admin => true) } it { should be_admin } end context ‘when the subject is not an admin’ do subject { described_class.make(:admin => false) } it { should_not be_admin } end end Example group 12೥9݄21೔༵ۚ೔
  6. Terms require ‘spec_helper’ describe Account do context ‘when the subject

    is an admin’ do subject { described_class.make(:admin => true) } it { should be_admin } end context ‘when the subject is not an admin’ do subject { described_class.make(:admin => false) } it { should_not be_admin } end end Example group Example group 12೥9݄21೔༵ۚ೔
  7. Terms require ‘spec_helper’ describe Account do context ‘when the subject

    is an admin’ do subject { described_class.make(:admin => true) } it { should be_admin } end context ‘when the subject is not an admin’ do subject { described_class.make(:admin => false) } it { should_not be_admin } end end Code example Code example 12೥9݄21೔༵ۚ೔
  8. Terms require ‘spec_helper’ describe Account do context ‘when the subject

    is an admin’ do subject { described_class.make(:admin => true) } it { should be_admin } end context ‘when the subject is not an admin’ do subject { described_class.make(:admin => false) } it { should_not be_admin } end end Expectation Expectation 12೥9݄21೔༵ۚ೔
  9. Terms require ‘spec_helper’ describe Account do context ‘when the subject

    is an admin’ do subject { described_class.make(:admin => true) } it { should be_admin } end context ‘when the subject is not an admin’ do subject { described_class.make(:admin => false) } it { should_not be_admin } end end Spec file 12೥9݄21೔༵ۚ೔
  10. Terms BDD TDD Expectations Assertions Code examples Tests Example groups

    Test cases 12೥9݄21೔༵ۚ೔
  11. Shared example shared_examples “a collection” do # assumes the described

    class can be initialized with an Array let(:collection) { described_class.new([7, 2, 4]) } context “initialized with 3 items” do it “says it has three items” do collection.size.should eq(3) end end describe “#include?” do context “with an item that is in the collection” do it “returns true” do collection.should be_include(7) end end end end 12೥9݄21೔༵ۚ೔
  12. Using shared example require ‘set’ describe Array do it_behaves_like “a

    collection” end describe Set do it_behaves_like “a collection” end 12೥9݄21೔༵ۚ೔
  13. Shared example with parameters shared_examples “a measurable object” do |measurement,

    measurement_methods| measurement_methods.each do |measurement_method| describe “##{measurement_method}“ do it “should return #{measurement}” do subject.send(measurement_method).should eq(measurement) end end end end describe Array, “with 3 items” do subject { [1, 2, 3] } it_behaves_like “a measurable object”, 3, [:size, :length] end describe String, “of 6 ASCII-chars” do subject { “FooBar” } it_behaves_like “a measurable object”, 6, [:bytesize, :size, :length] end 12೥9݄21೔༵ۚ೔
  14. Shared example with parameters shared_examples “a measurable object” do |measurement,

    measurement_methods| measurement_methods.each do |measurement_method| describe “##{measurement_method}“ do it “should return #{measurement}” do subject.send(measurement_method).should eq(measurement) end end end end describe Array, “with 3 items” do subject { [1, 2, 3] } it_behaves_like “a measurable object”, 3, [:size, :length] end describe String, “of 6 ASCII-chars” do subject { “FooBar” } it_behaves_like “a measurable object”, 6, [:bytesize, :size, :length] end 12೥9݄21೔༵ۚ೔
  15. Shared example with parameters shared_examples “a measurable object” do |measurement,

    measurement_methods| measurement_methods.each do |measurement_method| describe “##{measurement_method}“ do it “should return #{measurement}” do subject.send(measurement_method).should eq(measurement) end end end end describe Array, “with 3 items” do subject { [1, 2, 3] } it_behaves_like “a measurable object”, 3, [:size, :length] end describe String, “of 6 ASCII-chars” do subject { “FooBar” } it_behaves_like “a measurable object”, 6, [:bytesize, :size, :length] end 12೥9݄21೔༵ۚ೔
  16. shared context shared_context “shared stuff” do before { @some_var =

    :some_value } def shared_method “it works” end let(:shared_let) { { ‘arbitrary’ => ‘object’ } } subject { ‘this is the subject’ } end 12೥9݄21೔༵ۚ೔
  17. include shared context describe ‘group that includes a shared context

    using ‘include_context’” do include_context ‘shared stuff’ specify ‘access things defined in the included shared context’ do shared_method.should eq(‘it works’) shared_let[‘arbitrary’].should eq(‘object’) @some_var.should be(:some_value) subject.should eq(‘this is the subject’) end end 12೥9݄21೔༵ۚ೔
  18. shared context with metadata shared_context “shared stuff”, :foo => :bar

    do before { @some_var = :some_value } def shared_method “it works” end let(:shared_let) { { ‘arbitrary’ => ‘object’ } } subject { ‘this is the subject’ } end 12೥9݄21೔༵ۚ೔
  19. shared context with metadata shared_context “shared stuff”, :foo => :bar

    do before { @some_var = :some_value } def shared_method “it works” end let(:shared_let) { { ‘arbitrary’ => ‘object’ } } subject { ‘this is the subject’ } end 12೥9݄21೔༵ۚ೔
  20. include shared context by metadata describe ‘group that includes a

    shared context by metadata”, :foo => :bar do specify ‘access things defined in the included shared context’ do shared_method.should eq(‘it works’) shared_let[‘arbitrary’].should eq(‘object’) @some_var.should be(:some_value) subject.should eq(‘this is the subject’) end end 12೥9݄21೔༵ۚ೔
  21. include shared context by metadata describe ‘group that includes a

    shared context by metadata”, :foo => :bar do specify ‘access things defined in the included shared context’ do shared_method.should eq(‘it works’) shared_let[‘arbitrary’].should eq(‘object’) @some_var.should be(:some_value) subject.should eq(‘this is the subject’) end end 12೥9݄21೔༵ۚ೔
  22. pending with condition pending(“reason”, :if => true) { expectations }

    # this is pending pending(“reason”, :if => false) { expectations } # this is not pending pending(“reason”, :unless => true) { expectations } # this is not pending pending(“reason”, :unless => false) { expectations } # this is pending 12೥9݄21೔༵ۚ೔
  23. around hook describe “...” do around(:each) do |ex| before preparation

    ex.run ensure finalization end end ... end 12೥9݄21೔༵ۚ೔
  24. example usage of around hook # examples are run in

    temporary directries around(:each) do |ex| Dir.mktmpdir do |tmpdir| Dir.chdir tmpdir do ex.run end end end 12೥9݄21೔༵ۚ೔
  25. example usage of around hook # with Timecop around(:each) do

    |ex| Timecop.travel(Time.local(2012, 7, 20, 12, 34, 56)) do ex.run end end 12೥9݄21೔༵ۚ೔
  26. let and let! • helper method for memoization • let(:name)

    { ... } • is not called automatically • let!(:name) { ... } • is called automatically in a before hook 12೥9݄21೔༵ۚ೔
  27. metadata describe “with metadata”, :foo, :bar, :baz => 42 do

    it ‘has `:fast => true` metadata’ do example.metadata[:fast].should eq(true) end it ‘has `:bar => true` metadata’ do example.metadata[:bar].should eq(true) end it ‘has `:baz => 42` metadata’ do example.metadata[:baz].should eq(42) end it ‘has `:hoge => true` metadata’, :hoge do example.metadata[:hoge].should eq(true) end end 12೥9݄21೔༵ۚ೔
  28. metadata describe “with metadata”, :foo, :bar, :baz => 42 do

    it ‘has `:fast => true` metadata’ do example.metadata[:fast].should eq(true) end it ‘has `:bar => true` metadata’ do example.metadata[:bar].should eq(true) end it ‘has `:baz => 42` metadata’ do example.metadata[:baz].should eq(42) end it ‘has `:hoge => true` metadata’, :hoge do example.metadata[:hoge].should eq(true) end end 12೥9݄21೔༵ۚ೔
  29. :focus • If examples with :focus metadata, rspec evaluates only

    these examples. 12೥9݄21೔༵ۚ೔
  30. fail fast • Use fail_fast option to tell RSpec to

    abort the run on first failure. 12೥9݄21೔༵ۚ೔
  31. fail fast # write the following configuration in spec_helper.rb RSpec.configure

    do |config| config.fail_fast = true end # or use --fail-fast command line option $ rspec --fail-fast 12೥9݄21೔༵ۚ೔
  32. Expectations 12೥9݄21೔༵ۚ೔

  33. The basic structure •actual.should matcher(expected) •actual.should_not matcher(expected) 12೥9݄21೔༵ۚ೔

  34. Built-in matchers 12೥9݄21೔༵ۚ೔

  35. identity actual.should be(expected) it is same as: (actual.equal? expected).should be_true

    12೥9݄21೔༵ۚ೔
  36. equivalence actual.should eq(expected) it is same as: (actual == expected).should

    be_true actual.should eql(expected) it is same as: (actual.eql? expected).should be_true actual.should equal(expected) it is same as: (actual.equal? expected).should be_true 12೥9݄21೔༵ۚ೔
  37. Comparisons actual.should be > expected actual.should be >= expected actual.should

    be < expected actual.should be <= expected actual.should =~ /expression/ actual.should match(/expression/) actual.should be_within(delta).of(expected) it is same as: (actual - expected).abs.should be <= delta 12೥9݄21೔༵ۚ೔
  38. errors and throws expect { ... }.to raise_error expect {

    ... }.to raise_error(ExceptionClass) expect { ... }.to raise_error(/pattern matches to message/) expect { ... }.to raise_error(ExcpetionClass, /pattern/) expect { ... }.to throw_symbol expect { ... }.to throw_symbol(:symbol) expect { ... }.to throw_symbol(:symbol, value) 12೥9݄21೔༵ۚ೔
  39. predicates actual.should be_xxx # maps to actual.xxx? actual.should have_xxx(:arg) #

    maps to actual.has_xxx?(:arg) e.g.) [].should be_empty? {:foo => :bar}.should have_key(:foo) 12೥9݄21೔༵ۚ೔
  40. collection membership [1, 2, 3].should include(1) [1, 2, 3].should include(1,

    2) {:a => :b}.should include(:a => :b) “this string”.should include(“is str”) (1..10).should cover(3) # only >1.9 12೥9݄21೔༵ۚ೔
  41. yield module Foo def self.foo(*args) yield *args end def self.bar(*args)

    end end expect {|blk| Foo.foo(1, &blk) }.to yield_control expect {|blk| Foo.bar(1, &blk) }.not_to yield_control 12೥9݄21೔༵ۚ೔
  42. yield with args module Foo def self.foo(*args) yield *args end

    def self.bar(*args) end def self.baz(*args) yield end end expect {|blk| Foo.foo(1, &blk) }.to yield_with_args expect {|blk| Foo.bar(1, &blk) }.not_to yield_with_args expect {|blk| Foo.baz(1, &blk) }.not_to yield_with_args 12೥9݄21೔༵ۚ೔
  43. yield with args module Foo def self.foo(*args) yield *args end

    def self.bar(*args) end def self.baz(*args) yield end end expect {|blk| Foo.foo(‘abc’, ‘xyz’, &blk) }.to yield_with_args(‘abc’, ‘xyz’) expect {|blk| Foo.foo(‘abc’, ‘xyz’, &blk) }.to yield_with_args(/bc/, /xy/) Use == or === to compare arguments 12೥9݄21೔༵ۚ೔
  44. yield with no args module Foo def self.foo(*args) yield *args

    end def self.bar(*args) end def self.baz(*args) yield end end expect {|blk| Foo.foo(‘abc’, ‘xyz’, &blk) }.not_to yield_with_no_args expect {|blk| Foo.bar(‘abc’, ‘xyz’, &blk) }.not_to yield_with_no_args expect {|blk| Foo.baz(‘abc’, ‘xyz’, &blk) }.to yield_with_no_args 12೥9݄21೔༵ۚ೔
  45. yield successive args expect {|blk| [1, 2, 3].each(&blk) }.to yield_successive_args(1,

    2, 3) expect {|blk| [1, 2, 3].each(&blk) }.to yield_successive_args(Fixnum, Fixnum, Fixnum) expect {|blk| {:a => 1, :b => 2}.each(&blk) }.to yield_successive_args([:a, 1], [:b, 2]) expect {|blk| {:a => 1, :b => 2}.each(&blk) }.to yield_successive_args( lambda {|x| x.last == 1 }, lambda {|x| x.last == 2 } ) Use == or === to compare arguments 12೥9݄21೔༵ۚ೔
  46. Custom matcher RSpec::Matchers.define :be_a_multiple_of do |expected| match do |actual| actual

    % expected == 0 end failure_message_for_should do |actual| “expected that #{actual} would be a multiple of #{expected}” end failure_message_for_should_not do |actual| “expected that #{actual} wouldn’t be a multiple of #{expected}” end description do “be multiple of #{expected}” # used for auto-generated description end end 12೥9݄21೔༵ۚ೔
  47. Custom matcher describe 9 do it { should be_a_multiple_of(3) }

    # pass end describe 9 do it { should_not be_a_multiple_of(4) } # pass end describe 9 do it { should be_a_multiple_of(4) } #=> “expected that 9 would be a multiple of 4” end describe 9 do it { should_not be_a_multiple_of(3) } #=> “expected that 9 wouldn’t be a multiple of 3” end 12೥9݄21೔༵ۚ೔
  48. References • https://www.relishapp.com/rspec/rspec-core/ v/2-11/docs • https://www.relishapp.com/rspec/rspec- expectations/v/2-11/docs • https://www.relishapp.com/rspec/rspec- mocks/v/2-11/docs

    • https://www.relishapp.com/rspec/rspec-rails/ v/2-11/docs 12೥9݄21೔༵ۚ೔