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

Minitest & Rails: Total BFFs

Minitest & Rails: Total BFFs

Rails 4 is switching to MiniTest from Test::Unit. What does this mean for you? MiniTest is more than an exercise in minimalism, it’s a full-featured testing framework. Using MiniTest, we can change our approach to application design and build Rails apps that are more flexible, easier to refactor, and more maintainable.

We’ll get straight to the good stuff: How to test validations. When to stub and when to mock. How to use fixtures, and when you should skip them. Can your model tests be faster? What about controller tests? And why you’d choose it over RSpec.

Have you worked on apps where the tests are mocked to the hilt and impossible to change when refactoring? Or wasted time hunting through dozens of files to find all the downstream methods called from one controller action? Or simply thrown tests away because your team can no longer maintain them? Then this session is for you.

blowmage

May 13, 2013
Tweet

More Decks by blowmage

Other Decks in Technology

Transcript

  1. Minitest & Rails

    View full-size slide

  2. Minitest & Rails

    View full-size slide

  3. Minitest & Rails
    Total BFFs

    View full-size slide

  4. Let me tell
    you a story...

    View full-size slide

  5. Minitest is replacing
    Test::Unit in Rails 4

    View full-size slide

  6. How does
    minitest work?

    View full-size slide

  7. I’ll show you!

    View full-size slide

  8. Example Test

    View full-size slide

  9. class Pony
    def friendship
    "magic"
    end
    end
    test/pony_test.rb

    View full-size slide

  10. # class Pony
    # def friendship
    # "magic"
    # end
    # end
    test/pony_test.rb

    View full-size slide

  11. require "minitest/autorun"
    # class Pony
    # def friendship
    # "magic"
    # end
    # end
    test/pony_test.rb

    View full-size slide

  12. require "minitest/autorun"
    # class Pony
    # def friendship
    # "magic"
    # end
    # end
    class PonyTest < Minitest::Test
    end
    test/pony_test.rb

    View full-size slide

  13. require "minitest/autorun"
    # class Pony
    # def friendship
    # "magic"
    # end
    # end
    class PonyTest < Minitest::Test
    def test_friendship
    end
    end
    test/pony_test.rb

    View full-size slide

  14. require "minitest/autorun"
    # class Pony
    # def friendship
    # "magic"
    # end
    # end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb

    View full-size slide

  15. require "minitest/autorun"
    # class Pony
    # def friendship
    # "magic"
    # end
    # end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 49523
    # Running:
    E
    Finished in 0.000875s, 1142.8571 runs/s, 0.0000 assertions/s.
    1) Error:
    PonyTest#test_friendship:
    NameError: uninitialized constant PonyTest::Pony
    test/pony_test.rb:11:in `test_friendship'
    1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

    View full-size slide

  16. require "minitest/autorun"
    # class Pony
    # def friendship
    # "magic"
    # end
    # end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 49523
    # Running:
    E
    Finished in 0.000875s, 1142.8571 runs/s, 0.0000 assertions/s.
    1) Error:
    PonyTest#test_friendship:
    NameError: uninitialized constant PonyTest::Pony
    test/pony_test.rb:11:in `test_friendship'
    1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

    View full-size slide

  17. require "minitest/autorun"
    class Pony
    # def friendship
    # "magic"
    # end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb

    View full-size slide

  18. require "minitest/autorun"
    class Pony
    # def friendship
    # "magic"
    # end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 58892
    # Running:
    E
    Finished in 0.000793s, 1261.0340 runs/s, 0.0000 assertions/s.
    1) Error:
    PonyTest#test_friendship:
    NoMethodError: undefined method `friendship' for #
    test/pony_test.rb:11:in `test_friendship'
    1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

    View full-size slide

  19. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb

    View full-size slide

  20. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 17894
    # Running:
    F
    Finished in 0.000805s, 1242.2360 runs/s, 1242.2360 assertions/s.
    1) Failure:
    PonyTest#test_friendship [test/pony_test.rb:11]:
    Failed assertion, no message given.
    1 runs, 1 assertions, 1 failures, 0 errors, 0 skips

    View full-size slide

  21. require "minitest/autorun"
    class Pony
    def friendship
    "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb

    View full-size slide

  22. require "minitest/autorun"
    class Pony
    def friendship
    "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 3512
    # Running:
    .
    Finished in 0.000799s, 1251.5645 runs/s, 1251.5645 assertions/s.
    1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  23. require "minitest/autorun"
    class Pony
    def friendship
    "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 3512
    # Running:
    .
    Finished in 0.000799s, 1251.5645 runs/s, 1251.5645 assertions/s.
    1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  24. But Pinkie!
    That assertion
    message was
    kinda ugly, right?

    View full-size slide

  25. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb

    View full-size slide

  26. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 17894
    # Running:
    F
    Finished in 0.000805s, 1242.2360 runs/s, 1242.2360 assertions/s.
    1) Failure:
    PonyTest#test_friendship [test/pony_test.rb:11]:
    Failed assertion, no message given.
    1 runs, 1 assertions, 1 failures, 0 errors, 0 skips

    View full-size slide

  27. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert(Pony.new.friendship == "magic")
    end
    end
    test/pony_test.rb

    View full-size slide

  28. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert((Pony.new.friendship == "magic"),
    "Friendship expected to be magic")
    end
    end
    test/pony_test.rb

    View full-size slide

  29. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert((Pony.new.friendship == "magic"),
    "Friendship expected to be magic")
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 28853
    # Running:
    F
    Finished in 0.000787s, 1270.6480 runs/s, 1270.6480 assertions/s.
    1) Failure:
    PonyTest#test_friendship [test/pony_test.rb:11]:
    Friendship expected to be magic
    1 runs, 1 assertions, 1 failures, 0 errors, 0 skips

    View full-size slide

  30. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert_equal "magic", Pony.new.friendship
    end
    end
    test/pony_test.rb

    View full-size slide

  31. require "minitest/autorun"
    class Pony
    def friendship
    # "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert_equal "magic", Pony.new.friendship
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 53489
    # Running:
    F
    Finished in 0.028344s, 35.2808 runs/s, 35.2808 assertions/s.
    1) Failure:
    PonyTest#test_friendship [test/pony_test.rb:11]:
    Expected: "magic"
    Actual: nil
    1 runs, 1 assertions, 1 failures, 0 errors, 0 skips

    View full-size slide

  32. require "minitest/autorun"
    class Pony
    def friendship
    "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert_equal "magic", Pony.new.friendship
    end
    end
    test/pony_test.rb

    View full-size slide

  33. require "minitest/autorun"
    class Pony
    def friendship
    "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert_equal "magic", Pony.new.friendship
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 13305
    # Running:
    .
    Finished in 0.000884s, 1131.2217 runs/s, 1131.2217 assertions/s.
    1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  34. require "minitest/autorun"
    class Pony
    def friendship
    "magic"
    end
    end
    class PonyTest < Minitest::Test
    def test_friendship
    assert_equal "magic", Pony.new.friendship
    end
    end
    test/pony_test.rb
    $ ruby test/pony_test.rb
    Run options: --seed 13305
    # Running:
    .
    Finished in 0.000884s, 1131.2217 runs/s, 1131.2217 assertions/s.
    1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  35. TDD Process
    •Test Class

    View full-size slide

  36. TDD Process
    •Test Class
    •Test Method

    View full-size slide

  37. TDD Process
    •Test Class
    •Test Method
    •Assertion

    View full-size slide

  38. TDD Process
    •Test Class
    •Test Method
    •Assertion
    •Error

    View full-size slide

  39. TDD Process
    •Test Class
    •Test Method
    •Assertion
    •Error
    •Failure

    View full-size slide

  40. TDD Process
    •Test Class
    •Test Method
    •Assertion
    •Error
    •Failure
    •Pass

    View full-size slide

  41. TDD Process
    •Test Class
    •Test Method
    •Assertion
    •Error
    •Failure
    •Pass
    •Refactor

    View full-size slide

  42. Testing Models

    View full-size slide

  43. class Pony
    def friendship
    "magic"
    end
    end
    app/models/pony.rb

    View full-size slide

  44. class Pony < ActiveRecord::Base
    def friendship
    "magic"
    end
    end
    app/models/pony.rb

    View full-size slide

  45. require "minitest/autorun"
    class PonyTest < Minitest::Test
    def test_friendship
    assert_equal "magic", Pony.new.friendship
    end
    end
    test/pony_test.rb

    View full-size slide

  46. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def test_friendship
    assert_equal "magic", Pony.new.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  47. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  48. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  49. ActiveSupport::TestCase

    View full-size slide

  50. ActiveSupport::TestCase
    •Per-test
    database
    transactions

    View full-size slide

  51. ActiveSupport::TestCase
    •Per-test
    database
    transactions
    •Fixtures

    View full-size slide

  52. ActiveSupport::TestCase
    •Per-test
    database
    transactions
    •Fixtures
    •assert_blank

    View full-size slide

  53. ActiveSupport::TestCase
    •Per-test
    database
    transactions
    •Fixtures
    •assert_blank
    •assert_present

    View full-size slide

  54. ActiveSupport::TestCase
    •Per-test
    database
    transactions
    •Fixtures
    •assert_blank
    •assert_present
    •assert_difference

    View full-size slide

  55. ActiveSupport::TestCase
    •Per-test
    database
    transactions
    •Fixtures
    •assert_blank
    •assert_present
    •assert_difference
    •assert_no_difference

    View full-size slide

  56. But Pinkie!
    What are
    fixtures?

    View full-size slide

  57. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  58. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  59. twilight:
    name: Twilight Sparkle
    email: [email protected]
    pinkie:
    name: Pinkie Pie
    email: [email protected]
    test/fixtures/ponies.yml

    View full-size slide

  60. sprinkle:
    name: Twinkle Sprinkle
    fluffy:
    name: Fluffy Top
    test/fixtures/cupcakes.yml

    View full-size slide

  61. twilight_sprinkle:
    pony: twilight
    cupcake: sprinkle
    pinkie_fluffy:
    pony: pinkie
    cupcake: fluffy
    test/fixtures/favorites.yml

    View full-size slide

  62. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  63. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  64. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= ponies(:twilight)
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb

    View full-size slide

  65. require 'test_helper'
    class PonyTest < ActiveSupport::TestCase
    def twilight
    @twilight ||= ponies(:twilight)
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight.name
    end
    def test_friendship
    assert_equal "magic", twilight.friendship
    end
    end
    app/models/pony.rb
    $ ruby test/pony_test.rb
    Run options: --seed 13305
    # Running:
    .
    Finished in 0.000884s, 1131.2217 runs/s, 1131.2217 assertions/s.
    1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  66. Testing Controllers

    View full-size slide

  67. test/controllers/cupcakes_test.rb
    require "test_helper"
    class CupcakesControllerTest < ActionController::TestCase
    def test_index
    get :index
    assert_response :success
    end
    def test_show
    get :show, id: cupcakes(:sprinkle)
    assert_response :success
    end
    end

    View full-size slide

  68. test/controllers/cupcakes_test.rb
    require "test_helper"
    class CupcakesControllerTest < ActionController::TestCase
    def test_index
    get :index
    assert_response :success
    end
    def test_show
    get :show, id: cupcakes(:sprinkle)
    assert_response :success
    end
    end
    $ rake test:controllers
    Run options: --seed 22699
    # Running tests:
    ..
    Finished tests in 0.124348s, 16.0839 tests/s, 16.0839 assertions/s.
    2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  69. ActionController::TestCase

    View full-size slide

  70. ActionController::TestCase
    •request

    View full-size slide

  71. ActionController::TestCase
    •request
    •response

    View full-size slide

  72. ActionController::TestCase
    •request
    •response
    •session

    View full-size slide

  73. ActionController::TestCase
    •request
    •response
    •session
    •flash

    View full-size slide

  74. ActionController::TestCase
    •request
    •response
    •session
    •flash
    •assert_response

    View full-size slide

  75. ActionController::TestCase
    •request
    •response
    •session
    •flash
    •assert_response
    •assert_redirected_to

    View full-size slide

  76. ActionController::TestCase
    •request
    •response
    •session
    •flash
    •assert_response
    •assert_redirected_to
    •assert_template

    View full-size slide

  77. Testing Helpers

    View full-size slide

  78. module CupcakesHelper
    def cupcake_image_tag cupcake
    image_tag cupcake.image_url, alt: cupcake.name
    end
    end
    app/helpers/cupcakes_helper.rb

    View full-size slide

  79. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.name, image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.image_url, image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb

    View full-size slide

  80. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.name, image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.image_url, image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb
    $ rake test:helpers
    Run options: --seed 59089
    # Running tests:
    ..
    Finished tests in 0.051314s, 38.9757 tests/s, 77.9514 assertions/s.
    2 tests, 4 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  81. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.name, image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.image_url, image_tag_html
    end
    def test_blank_image_url
    @cupcake.image_url = nil
    image_tag_html = cupcake_image_tag @cupcake
    assert_match Cupcake::DEFAULT_IMAGE_URL, image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb

    View full-size slide

  82. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.name, image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.image_url, image_tag_html
    end
    def test_blank_image_url
    @cupcake.image_url = nil
    image_tag_html = cupcake_image_tag @cupcake
    assert_match Cupcake::DEFAULT_IMAGE_URL, image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb
    $ rake test:helpers
    Run options: --seed 23417
    # Running tests:
    .E.
    Finished tests in 0.050823s, 59.0284 tests/s, 78.7045 assertions/s.
    1) Error:
    CupcakesHelperTest#test_blank_image_url:
    NameError: uninitialized constant Cupcake::DEFAULT_IMAGE_URL
    app/helpers/cupcakes_helper.rb:5:in `cupcake_image_tag'
    test/helpers/cupcakes_helper_test.rb:22:in `test_blank_image_url'
    3 tests, 4 assertions, 0 failures, 1 errors, 0 skips

    View full-size slide

  83. class Cupcake < ActiveRecord::Base
    has_many :favorites
    has_many :ponies, through: :favorites
    end
    app/models/cupcake.rb

    View full-size slide

  84. class Cupcake < ActiveRecord::Base
    DEFAULT_IMAGE_URL = "/images/cupcake.png"
    has_many :favorites
    has_many :ponies, through: :favorites
    end
    app/models/cupcake.rb

    View full-size slide

  85. class Cupcake < ActiveRecord::Base
    DEFAULT_IMAGE_URL = "/images/cupcake.png"
    has_many :favorites
    has_many :ponies, through: :favorites
    end
    app/models/cupcake.rb
    $ rake test:helpers
    Run options: --seed 52680
    # Running tests:
    .F.
    Finished tests in 0.028242s, 106.2248 tests/s, 212.4495 assertions/s.
    1) Failure:
    CupcakesHelperTest#test_blank_image_url [~/pinkie_shop/test/helpers/
    cupcakes_helper_test.rb:23]:
    Expected /\/images\/cupcake\.png/ to match "\"\" />".
    3 tests, 6 assertions, 1 failures, 0 errors, 0 skips

    View full-size slide

  86. module CupcakesHelper
    def cupcake_image_tag cupcake
    image_tag cupcake.image_url, alt: cupcake.name
    end
    end
    app/helpers/cupcakes_helper.rb

    View full-size slide

  87. module CupcakesHelper
    def cupcake_image_tag cupcake
    url = cupcake.image_url
    url = Cupcake::DEFAULT_IMAGE_URL if url.blank?
    image_tag url, alt: cupcake.name
    end
    end
    app/helpers/

    View full-size slide

  88. module CupcakesHelper
    def cupcake_image_tag cupcake
    url = cupcake.image_url
    url = Cupcake::DEFAULT_IMAGE_URL if url.blank?
    image_tag url, alt: cupcake.name
    end
    end
    app/helpers/
    $ rake test:helpers
    Run options: --seed 32226
    # Running tests:
    ...
    Finished tests in 0.049226s, 60.9434 tests/s, 121.8868 assertions/s.
    3 tests, 6 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  89. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.name, image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match @cupcake.image_url, image_tag_html
    end
    def test_blank_image_url
    @cupcake.image_url = nil
    image_tag_html = cupcake_image_tag @cupcake
    assert_match Cupcake::DEFAULT_IMAGE_URL, image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb

    View full-size slide

  90. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "alt=\"#{@cupcake.name}\"", image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "src=\"#{@cupcake.image_url}\"", image_tag_html
    end
    def test_blank_image_url
    @cupcake.image_url = nil
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "src=\"#{Cupcake::DEFAULT_IMAGE_URL}\"", image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb

    View full-size slide

  91. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "alt=\"#{@cupcake.name}\"", image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "src=\"#{@cupcake.image_url}\"", image_tag_html
    end
    def test_blank_image_url
    @cupcake.image_url = nil
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "src=\"#{Cupcake::DEFAULT_IMAGE_URL}\"", image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb
    $ rake test:helpers
    Run options: --seed 63012
    # Running tests:
    ...
    Finished tests in 0.048934s, 61.3071 tests/s, 122.6141 assertions/s.
    3 tests, 6 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  92. Integration/Acceptance
    Tests

    View full-size slide

  93. But Pinkie!
    I really like the
    spec DSL...
    Can I still use it?

    View full-size slide

  94. app/models/pony.rb
    class Pony < ActiveRecord::Base
    has_many :favorites
    has_many :cupcakes, through: :favorites
    has_many :orders
    def friendship
    "magic"
    end
    end

    View full-size slide

  95. test/models/pony_test.rb
    require "test_helper"
    class PonyTest < ActiveSupport::TestCase
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    def test_friendship
    assert_equal "magic", twilight_sparkle.friendship
    end
    end

    View full-size slide

  96. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in...
    #
    # Note: You'll currently still have to declare fixtures explicitly...
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    end

    View full-size slide

  97. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/spec"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in...
    #
    # Note: You'll currently still have to declare fixtures explicitly...
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    extend Minitest::Spec::DSL
    register_spec_type(self) do |desc|
    desc < ActiveRecord::Base if desc.is_a?(Class)
    end
    end

    View full-size slide

  98. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/spec"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in...
    #
    # Note: You'll currently still have to declare fixtures explicitly...
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    extend Minitest::Spec::DSL
    register_spec_type(self) do |desc|
    desc < ActiveRecord::Base if desc.is_a?(Class)
    end
    end

    View full-size slide

  99. require "test_helper"
    class PonyTest < ActiveSupport::TestCase
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    def test_friendship
    assert_equal "magic", twilight_sparkle.friendship
    end
    end
    test/models/pony_test.rb

    View full-size slide

  100. require "test_helper"
    describe Pony do
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    def test_friendship
    assert_equal "magic", twilight_sparkle.friendship
    end
    end
    test/models/pony_test.rb

    View full-size slide

  101. require "test_helper"
    describe Pony do
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    def test_friendship
    assert_equal "magic", twilight_sparkle.friendship
    end
    end
    test/models/pony_test.rb

    View full-size slide

  102. require "test_helper"
    describe Pony do
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    it "knows it's name" do
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    it "knows about friendship" do
    assert_equal "magic", twilight_sparkle.friendship
    end
    end
    test/models/pony_test.rb

    View full-size slide

  103. require "test_helper"
    describe Pony do
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    it "knows it's name" do
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    it "knows about friendship" do
    assert_equal "magic", twilight_sparkle.friendship
    end
    end
    test/models/pony_test.rb

    View full-size slide

  104. require "test_helper"
    describe Pony do
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  105. require "test_helper"
    describe Pony do
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  106. require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  107. require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  108. require "test_helper"
    class PonyTest < ActiveSupport::TestCase
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    def test_friendship
    assert_equal "magic", twilight_sparkle.friendship
    end
    end
    test/models/pony_test.rb

    View full-size slide

  109. require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  110. require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  111. test/controllers/cupcakes_test.rb
    require "test_helper"
    class CupcakesControllerTest < ActionController::TestCase
    def test_index
    get :index
    assert_response :success
    end
    def test_show
    get :show, id: cupcakes(:sprinkle)
    assert_response :success
    end
    end

    View full-size slide

  112. test/controllers/cupcakes_test.rb
    require "test_helper"
    describe CupcakesController do
    it 'shows a list of cupcakes' do
    get :index
    assert_response :success
    end
    it 'shows a cupcake' do
    get :show, id: cupcakes(:sprinkle)
    assert_response :success
    end
    end

    View full-size slide

  113. require 'test_helper'
    class CupcakesHelperTest < ActionView::TestCase
    def setup
    @cupcake = Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png"
    end
    def test_alt_text
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "alt=\"#{@cupcake.name}\"", image_tag_html
    end
    def test_image_url
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "src=\"#{@cupcake.image_url}\"", image_tag_html
    end
    def test_blank_image_url
    @cupcake.image_url = nil
    image_tag_html = cupcake_image_tag @cupcake
    assert_match "src=\"#{Cupcake::DEFAULT_IMAGE_URL}\"", image_tag_html
    end
    end
    test/helpers/cupcakes_helper_test.rb

    View full-size slide

  114. require 'test_helper'
    describe CupcakeHelper do
    let(:cupcake) { Cupcake.new name: "Icy McIcerson",
    image_url: "http://i.imgur.com/mbWH1gM.png" }
    let(:image_tag_html) { cupcake_image_tag cupcake }
    it "sets the alt text" do
    image_tag_html.must_match "alt=\"#{cupcake.name}\""
    end
    it "uses the image_url" do
    image_tag_html.must_match "src=\"#{cupcake.image_url}\""
    end
    it "uses a default image url if needed" do
    cupcake.image_url = nil
    image_tag_html.must_match "src=\"#{Cupcake::DEFAULT_IMAGE_URL}\""
    end
    end
    test/helpers/cupcakes_helper_test.rb

    View full-size slide

  115. But Pinkie!
    Can I use nested
    context blocks?

    View full-size slide

  116. require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  117. require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb
    $ rake test:models
    Run options: --seed 43295
    # Running tests:
    ...
    Finished tests in 0.057017s, 52.6159 tests/s, 70.1545 assertions/s.
    3 tests, 4 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  118. test/models/pony_test.rb
    require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    context do
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    end

    View full-size slide

  119. test/models/pony_test.rb
    require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    context do
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    end
    $ rake test:models
    rake aborted!
    undefined method `context' for #
    ~/pinkie_shop/test/models/pony_test.rb:10:in `block in '
    ~/pinkie_shop/test/models/pony_test.rb:3:in `'
    Tasks: TOP => test:models
    (See full trace by running task with --trace)
    Run options: --seed 55683
    # Running tests:
    ..
    Finished tests in 0.057922s, 34.5292 tests/s, 51.7938 assertions/s.
    2 tests, 3 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  120. test/models/pony_test.rb
    require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    describe :friendship do
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    end

    View full-size slide

  121. test/models/pony_test.rb
    require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    describe :friendship do
    it "knows about friendship" do
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    end
    $ rake test:models
    Run options: --seed 31855
    # Running tests:
    ..
    Finished tests in 0.076128s, 26.2715 tests/s, 39.4073 assertions/s.
    2 tests, 3 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  122. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/spec"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in...
    #
    # Note: You'll currently still have to declare fixtures explicitly...
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    class << self
    remove_method :describe
    end if self.respond_to? :describe
    extend Minitest::Spec::DSL
    register_spec_type(self) do |desc|
    desc < ActiveRecord::Base if desc.is_a?(Class)
    end
    end

    View full-size slide

  123. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/spec"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in...
    #
    # Note: You'll currently still have to declare fixtures explicitly...
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    class << self
    remove_method :describe
    end if self.respond_to? :describe
    extend Minitest::Spec::DSL
    register_spec_type(self) do |desc|
    desc < ActiveRecord::Base if desc.is_a?(Class)
    end
    end
    $ rake test:models
    Run options: --seed 24
    # Running tests:
    ...
    Finished tests in 0.054639s, 54.9058 tests/s, 73.2078 assertions/s.
    3 tests, 4 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  124. But Pinkie!
    That’s a lot of
    test_helper config.
    Can it be simpler?

    View full-size slide

  125. minitest-rails

    View full-size slide

  126. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/spec"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in...
    #
    # Note: You'll currently still have to declare fixtures explicitly...
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    class << self
    remove_method :describe
    end if self.respond_to? :describe
    extend Minitest::Spec::DSL
    register_spec_type(self) do |desc|
    desc < ActiveRecord::Base if desc.is_a?(Class)
    end
    end

    View full-size slide

  127. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/rails"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in...
    #
    # Note: You'll currently still have to declare fixtures explicitly...
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    end

    View full-size slide

  128. But Pinkie!
    How do I turn my
    custom Assertions
    into Expectations?

    View full-size slide

  129. test/pony_assertions.rb
    module PonyAssertions
    def assert_favorite cupcake, pony
    assert pony.cupcakes.include?(cupcake),
    "Expected #{pony.name} to have favorited #{cupcake.name}"
    end
    end
    class ActiveSupport::TestCase
    include PonyAssertions
    end

    View full-size slide

  130. test/pony_expectations.rb
    module PonyExpectations
    # assert_favorite apple_cupcake, apple_jack
    # apple_jack.must_have_favorited apple_cupcake
    infect_an_assertion :assert_favorite, :must_have_favorited
    end
    class Object
    include PonyExpectations
    end

    View full-size slide

  131. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/rails"
    require "pony_assertions"
    require "pony_expectations"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in
    alphabetical order.
    #
    # Note: You'll currently still have to declare fixtures explicitly in
    integration tests
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    end

    View full-size slide

  132. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/rails"
    require "pony_assertions"
    require "pony_expectations"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in
    alphabetical order.
    #
    # Note: You'll currently still have to declare fixtures explicitly in
    integration tests
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    end

    View full-size slide

  133. test/models/favorite_test.rb
    require "test_helper"
    class FavoriteTest < ActiveSupport::TestCase
    def test_favorite
    assert_favorite cupcakes(:sprinkle), ponies(:twilight)
    end
    end

    View full-size slide

  134. test/models/favorite_test.rb
    require "test_helper"
    describe Favorite do
    it "allows ponies to favorite cupcakes" do
    ponies(:twilight).must_have_favorited cupcakes(:sprinkle)
    end
    end

    View full-size slide

  135. But Pinkie!
    Can I use
    describe/it blocks
    with assertions?

    View full-size slide

  136. require "test_helper"
    describe Pony do
    let(:twilight_sparkle) { Pony.new name: "Twilight Sparkle" }
    it "knows it's name" do
    assert_equal "Twilight Sparkle", twilight_sparkle.name
    end
    it "knows about friendship" do
    assert_equal "magic", twilight_sparkle.friendship
    end
    end
    test/models/pony_test.rb

    View full-size slide

  137. require "test_helper"
    class PonyTest < ActiveSupport::TestCase
    def twilight_sparkle
    @twilight_sparkle ||= Pony.new name: "Twilight Sparkle"
    end
    def test_name
    twilight_sparkle.name.must_equal "Twilight Sparkle"
    end
    def test_friendship
    twilight_sparkle.friendship.must_equal "magic"
    end
    end
    test/models/pony_test.rb

    View full-size slide

  138. But Pinkie!
    I want to test
    my app using
    Capybara. Can I?

    View full-size slide

  139. minitest-rails-capybara

    View full-size slide

  140. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/rails"
    require "minitest/rails/capybara"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in
    alphabetical order.
    #
    # Note: You'll currently still have to declare fixtures explicitly in
    integration tests
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    end

    View full-size slide

  141. test/test_helper.rb
    ENV["RAILS_ENV"] ||= "test"
    require File.expand_path('../../config/environment', __FILE__)
    require 'rails/test_help'
    require "minitest/rails"
    require "minitest/rails/capybara"
    class ActiveSupport::TestCase
    ActiveRecord::Migration.check_pending!
    # Setup all fixtures in test/fixtures/*.yml for all tests in
    alphabetical order.
    #
    # Note: You'll currently still have to declare fixtures explicitly in
    integration tests
    # -- they do not yet inherit this setting
    fixtures :all
    # Add more helper methods to be used by all tests here...
    end

    View full-size slide

  142. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup
    @pinkie_password = "pinkiepie"
    @pinkie = ponies :pinkie
    @pinkie.password = @pinkie_password
    @pinkie.save
    end
    end

    View full-size slide

  143. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup
    @pinkie_password = "pinkiepie"
    @pinkie = ponies :pinkie
    @pinkie.password = @pinkie_password
    @pinkie.save
    end
    end

    View full-size slide

  144. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    assert_have_content page, "login"
    assert_have_content page, "signup"
    refute_have_content page, "logout"
    end
    end
    $ rake minitest:features
    Run options: --seed 65422
    # Running tests:
    .
    Finished tests in 0.179815s, 5.5613 tests/s, 16.6838 assertions/s.
    1 tests, 3 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  145. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    assert_have_content page, "login"
    assert_have_content page, "signup"
    refute_have_content page, "logout"
    end
    end
    $ rake minitest:features
    Run options: --seed 65422
    # Running tests:
    .
    Finished tests in 0.179815s, 5.5613 tests/s, 16.6838 assertions/s.
    1 tests, 3 assertions, 0 failures, 0 errors, 0 skips
    $ rake minitest:features
    Run options: --seed 65422
    # Running tests:
    .
    Finished tests in 0.179815s, 5.5613 tests/s, 16.6838 assertions/s.
    1 tests, 3 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  146. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    assert_have_content page, "login"
    assert_have_content page, "signup"
    refute_have_content page, "logout"
    end
    end
    $ rake minitest:features
    Run options: --seed 65422
    # Running tests:
    .
    Finished tests in 0.179815s, 5.5613 tests/s, 16.6838 assertions/s.
    1 tests, 3 assertions, 0 failures, 0 errors, 0 skips
    $ rake minitest:features
    Run options: --seed 65422
    # Running tests:
    .
    Finished tests in 0.179815s, 5.5613 tests/s, 16.6838 assertions/s.
    1 tests, 3 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  147. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    assert_have_content page, "login"
    assert_have_content page, "signup"
    refute_have_content page, "logout"
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_have_content page, "logout"
    assert_have_content page, @pinkie.email
    refute_have_content page, "login"
    refute_have_content page, "signup"
    end
    end

    View full-size slide

  148. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    assert_have_content page, "login"
    assert_have_content page, "signup"
    refute_have_content page, "logout"
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_have_content page, "logout"
    assert_have_content page, @pinkie.email
    refute_have_content page, "login"
    refute_have_content page, "signup"
    end
    end
    $ rake minitest:features
    Run options: --seed 27176
    # Running tests:
    .
    Finished tests in 0.318181s, 3.1429 tests/s, 22.0001 assertions/s.
    1 tests, 7 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  149. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    end
    def test_login_as_pinkie_pie ...
    end
    def assert_nav_links_logged_in pony
    page.must_have_content "logout"
    page.must_have_content pony.email
    page.wont_have_content "login"
    page.wont_have_content "signup"
    end
    def refute_nav_links_logged_in pony = nil
    page.must_have_content "login"
    page.must_have_content "signup"
    page.wont_have_content "logout"
    end
    end

    View full-size slide

  150. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    end
    def test_login_as_pinkie_pie
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  151. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    end
    def test_login_as_pinkie_pie
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end
    $ rake minitest:features
    Run options: --seed 51819
    # Running tests:
    .
    Finished tests in 0.285183s, 3.5065 tests/s, 24.5456 assertions/s.
    1 tests, 7 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  152. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    end
    def test_login_as_pinkie_pie
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end
    $ rake minitest:features
    Run options: --seed 51819
    # Running tests:
    .
    Finished tests in 0.285183s, 3.5065 tests/s, 24.5456 assertions/s.
    1 tests, 7 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  153. But Pinkie!
    What about
    Capybara’s DSL?
    I really like it...

    View full-size slide

  154. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  155. test/features/login_test.rb
    require "test_helper"
    class LoginTest < Capybara::Rails::TestCase
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  156. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  157. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    def setup ...
    def test_login_as_pinkie_pie
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  158. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    def setup ...
    scenario "logging in as Pinkie Pie" do
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: @pinkie.email
    fill_in "Password", with: @pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in @pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  159. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    def setup
    @pinkie_password = "pinkiepie"
    @pinkie = ponies :pinkie
    @pinkie.password = @pinkie_password
    @pinkie.save
    end
    scenario "logging in as Pinkie Pie" do ...
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  160. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    given(:pinkie_password) { "pinkiepie" }
    def setup
    @pinkie = ponies :pinkie
    @pinkie.password = pinkie_password
    @pinkie.save
    end
    scenario "logging in as Pinkie Pie" do ...
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  161. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    given(:pinkie_password) { "pinkiepie" }
    given(:pinkie) { p = ponies :pinkie
    p.password = pinkie_password
    p.save
    p }
    scenario "logging in as Pinkie Pie" do ...
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  162. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    given(:pinkie_password) { "pinkiepie" }
    given(:pinkie) { p = ponies :pinkie ... }
    scenario "logging in as Pinkie Pie" do
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: pinkie.email
    fill_in "Password", with: pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end

    View full-size slide

  163. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    given(:pinkie_password) { "pinkiepie" }
    given(:pinkie) { p = ponies :pinkie ... }
    scenario "logging in as Pinkie Pie" do
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: pinkie.email
    fill_in "Password", with: pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end
    $ rake minitest:features
    Run options: --seed 51819
    # Running tests:
    .
    Finished tests in 0.285183s, 3.5065 tests/s, 24.5456 assertions/s.
    1 tests, 7 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  164. test/features/login_test.rb
    require "test_helper"
    feature "Login Feature" do
    given(:pinkie_password) { "pinkiepie" }
    given(:pinkie) { p = ponies :pinkie ... }
    scenario "logging in as Pinkie Pie" do
    visit root_path
    refute_nav_links_logged_in
    click_link "login"
    fill_in "Email", with: pinkie.email
    fill_in "Password", with: pinkie_password
    click_button "Sign in"
    assert_nav_links_logged_in pinkie
    end
    def assert_nav_links_logged_in pony ...
    def refute_nav_links_logged_in pony = nil ...
    end
    $ rake minitest:features
    Run options: --seed 51819
    # Running tests:
    .
    Finished tests in 0.285183s, 3.5065 tests/s, 24.5456 assertions/s.
    1 tests, 7 assertions, 0 failures, 0 errors, 0 skips

    View full-size slide

  165. But Pinkie!
    What about
    mocks?
    Or matchers?

    View full-size slide

  166. Mike Moore
    @blowmage
    blowmage.com

    View full-size slide

  167. Questions/Comments?

    View full-size slide

  168. Twilight Sparkle Image Credits
    • Twilight Sparkle is Curious by Alixey
    http://alixey.deviantart.com/art/Twilight-Sparkle-is-Curious-335163906
    • Skeptical, annoyed Twilight by MrHavre
    http://mrhavre.deviantart.com/art/Skeptical-annoyed-Twilight-333256895
    • Twilight memories by HankOfficer
    http://hankofficer.deviantart.com/art/Twilight-memories-316846734
    • Twilight Sparkle's Transformation by Sairoch
    http://sairoch.deviantart.com/art/Twilight-Sparkle-s-Transformation-356096575
    • Twilight Sparkle Alicorn Vector by Kamyk962
    http://kamyk962.deviantart.com/art/Twilight-Sparkle-Alicorn-Vector-355000137

    View full-size slide

  169. Pinkie Pie Image Credits
    •Pinkie Pie by KyssS by KyssS90
    http://kysss90.deviantart.com/art/Pinkie-Pie-by-KyssS-353498032
    •Sly Pinkie Pie by Sairoch
    http://sairoch.deviantart.com/art/Sly-Pinkie-Pie-353454194
    •Season 2 Poster Pinkie Pie by VladimirMacHolzraum
    http://vladimirmacholzraum.deviantart.com/art/Season-2-Poster-
    Pinkie-Pie-333531305
    •Pinkie Pie by CrusierPL
    http://crusierpl.deviantart.com/art/Pinkie-Pie-279503261

    View full-size slide

  170. Pinkie Pie Image Credits
    •Pinkie Glasses by J-Brony
    http://j-brony.deviantart.com/art/Pinkie-Glasses-264170145
    •Extremely Surprised Pinkie by IamthegreatLyra
    http://iamthegreatlyra.deviantart.com/art/Extremely-Surprised-
    Pinkie-279356130
    •Haters Gonna' Hate by binaryNinj4
    http://binaryninj4.deviantart.com/art/Haters-Gonna-Hate-201850847
    •Pinkie Pie Overwrought by Sairoch
    http://sairoch.deviantart.com/art/Pinkie-Pie-Overwrought-363028991

    View full-size slide