Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How I Learned to Stop Worrying and Like RSpec

How I Learned to Stop Worrying and Like RSpec

Miami Ruby Brigade, Sept. 15

Bryce "BonzoESC" Kerley

September 15, 2014
Tweet

More Decks by Bryce "BonzoESC" Kerley

Other Decks in Programming

Transcript

  1. How I Learned to Stop Worrying and Like RSpec Bryce

    Kerley Miami Ruby Brigade Sept. 15, 2014
  2. I Like RSpec • Testing, TDD, and Agile • Minitest

    features • How I got to RSpec • RSpec philosophy • RSpec practice
  3. Agile If you’re not sure what to do yet, do

    the simplest thing that could possibly work. http://www.artima.com/intv/simplest3.html
  4. Test-Driven Development 1. Write failing test for feature 2. Write

    code to pass the failing test 3. Write code to pass tests you broke 4. Clean up your mess
  5. Test-driven development is about not being afraid to try something.

    If you break it, you’ll know, and you’re a `git checkout` away from fixing it.
  6. I Like RSpec • Testing, TDD, and Agile • Minitest

    features • How I got to RSpec • RSpec philosophy • RSpec practice
  7. Conway's Game of Life • Grid of cells • Live

    cells with two or three neighbors stay alive • Dead cells with three neighbors come to life
  8. Five Minutes of Minitest require 'minitest/autorun' ! class CellTest <

    Minitest::Test def test_counts_neighbors c = Cell.new(0, 0) assert_equal 0, c.neighbors ! c2 = Cell.new(1, 0) assert_equal 1, c.neighbors end ! def test_comes_to_life end def test_stays_alive end end
  9. Minitest in Rails require 'test_helper' ! class PostTest < ActiveSupport::TestCase

    test 'a post has many comments' do p = Post.create assert_empty p.comments c = Comment.create post: p refute_empty p.comments end end
  10. I Like RSpec • Testing, TDD, and Agile • Minitest

    features • How I got to RSpec • RSpec philosophy • RSpec practice
  11. Riak Ruby Client • Started January 2010 • RSpec from

    the beginning • I took over May 2013 • 5833 lines of RSpec tests As of Thursday we have 5750 lines of tests, but we ripped out a bunch of complex systems.
  12. My Transition Copying and modifying existing specs My first commit

    on riak-ruby-client had a zillion assignments in a `before` block.
  13. My Transition Practice and review All my RSpec work was

    code-reviewed and commented on, which helped.
  14. My Transition Second nature Today, I’d rather write RSpec for

    new work even knowing my previous complaints about it.
  15. I Like RSpec • Testing, TDD, and Agile • Minitest

    features • How I got to RSpec • RSpec philosophy • RSpec practice
  16. RSpec Philosophy • Write yellow skeleton specs • Implement an

    expectation so it’s red • Fulfill an expectation to make it green
  17. Conway's Game with RSpec describe Cell do subject { described_class.new(0,

    0) } ! it 'comes to life appropriately' it 'stays alive appropriately’ ! it 'counts neighbors' do expect(subject.neighbors).to eq 0 ! c2 = described_class.new(1, 0) expect(subject.neighbors).to eq 1 end end Spec group Skeletons Spec Expectation
  18. RSpec in Rails require 'rails_helper' ! RSpec.describe Post, :type =>

    :model do subject{ described_class.create } ! it 'has many comments' do expect(subject.comments).to be_empty c = Comment.create post: subject expect(subject.comments).to_not be_empty end end
  19. I Like RSpec • Testing, TDD, and Agile • Minitest

    features • How I got to RSpec • RSpec philosophy • RSpec practice
  20. Easy to Install • Not Rails: rspec --init • Rails:

    gem 'rspec-rails' in your Gemfile
  21. The Syntax it{ is_expected.to be } subject(:post){ Post.new } expect(something.else).to

    eq 5 expect(somebody).to be_lovable allow(some_mock).to receive :method expect{ something.method }.to raise_error
  22. The Syntax • A confusing mish-mash of spaces, underscores, dots,

    parens, braces, symbols, strings • Oh, and words
  23. Let & Subject describe “CRDTs" do let(:bucket) { random_bucket }

    ! describe 'counters' do subject { Riak::Crdt::Counter.new bucket, random_key } ! it 'asks for and accepts a returned body' do other = Riak::Crdt::Counter.new(subject.bucket, subject.key) end end end
  24. Let & Subject class Turn def initialize puts "ACTUALLY BEING

    INITIALIZED" end end ! describe Turn do let(:turn){ Turn.new } ! it "might not get initialized" do expect(5).to eq 5 end ! it "is only initialized on use" do expect(turn).to be_a Turn end end
  25. Let & Subject • subject defines a variable named “subject”

    only when you need it • Is implicitly defined to described_class.new • Allows implicit usage with it { is_expected… }
  26. Let & Subject class Board def cromulent? true end end

    ! describe Board do it { is_expected.to be } it { is_expected.to be_a Board } it { is_expected.to be_cromulent } end
  27. Quick Boolean Matchers • Quickly verify any question? methods that

    take no arguments: • expect(my_object).to be_cromulent • Passes if cromulent? returns true-y
  28. Tagging & Focus describe 'Secure Protobuffs’ do ! describe 'without

    security enabled on Riak', no_security: true do it 'connects normally without authentication configured' do … ! describe 'with security enabled on Riak', yes_security: true do it 'connects normally with authentication configured' do These tests are mutually exclusive; they require server settings to be toggled and local configuration settings to match. I use tags to control which set runs.
  29. Tagging & Focus • focus is a tag with quick

    syntax • skip is metadata with quick syntax • “describe” to “fdescribe” or “xdescribe” • “it” to “fit” or “xit” • rspec ./spec/some_specs/… -t focus
  30. Customizing & Promode • Put a .rspec file in your

    project root --format documentation --color
  31. I Like RSpec • Testing, TDD, and Agile • Minitest

    features • How I got to RSpec • RSpec philosophy • RSpec practice
  32. Bryce and RSpec I started with RSpec because I had

    to I got good with RSpec because I enjoyed it
  33. RSpec Philosophy Everything you need to test behavior of objects

    If it’s hard to do with RSpec, consider if it’s the right thing to do.