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 Slide

  2. Minitest & Rails

    View Slide

  3. Minitest & Rails
    Total BFFs

    View Slide

  4. Let me tell
    you a story...

    View Slide

  5. View Slide

  6. View Slide

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

    View Slide

  8. View Slide

  9. How does
    minitest work?

    View Slide

  10. View Slide

  11. I’ll show you!

    View Slide

  12. Example Test

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View 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

    View 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
    $ 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 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 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 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 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 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 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

    View Slide

  24. 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 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 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 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 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
    $ 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 Slide

  28. But Pinkie!

    View Slide

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

    View Slide

  30. 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 Slide

  31. 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 Slide

  32. 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 Slide

  33. 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 Slide

  34. 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 Slide

  35. 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 Slide

  36. 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 Slide

  37. 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 Slide

  38. 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 Slide

  39. 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 Slide

  40. TDD Process

    View Slide

  41. TDD Process
    •Test Class

    View Slide

  42. TDD Process
    •Test Class
    •Test Method

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  48. Testing Models

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  53. 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 Slide

  54. 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 Slide

  55. ActiveSupport::TestCase

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  62. But Pinkie!

    View Slide

  63. But Pinkie!
    What are
    fixtures?

    View Slide

  64. 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 Slide

  65. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  69. 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 Slide

  70. 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 Slide

  71. 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 Slide

  72. 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 Slide

  73. Testing Controllers

    View Slide

  74. 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 Slide

  75. 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 Slide

  76. ActionController::TestCase

    View Slide

  77. ActionController::TestCase
    •request

    View Slide

  78. ActionController::TestCase
    •request
    •response

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  84. Testing Helpers

    View Slide

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

    View Slide

  86. 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 Slide

  87. 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 Slide

  88. 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 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
    $ 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 Slide

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

    View Slide

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

    View Slide

  92. 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 Slide

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

    View Slide

  94. 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 Slide

  95. 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 Slide

  96. 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 Slide

  97. 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 Slide

  98. 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 Slide

  99. Integration/Acceptance
    Tests

    View Slide

  100. View Slide

  101. But Pinkie!

    View Slide

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

    View Slide

  103. 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 Slide

  104. 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 Slide

  105. 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 Slide

  106. 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 Slide

  107. 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 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 Slide

  109. 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 Slide

  110. 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 Slide

  111. 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 Slide

  112. 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 Slide

  113. 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 Slide

  114. 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 Slide

  115. 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 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 Slide

  117. 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 Slide

  118. 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 Slide

  119. 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 Slide

  120. 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 Slide

  121. 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 Slide

  122. 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 Slide

  123. 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 Slide

  124. But Pinkie!

    View Slide

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

    View Slide

  126. 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 Slide

  127. 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 Slide

  128. 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 Slide

  129. 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 Slide

  130. 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 Slide

  131. 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 Slide

  132. 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 Slide

  133. 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 Slide

  134. But Pinkie!

    View Slide

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

    View Slide

  136. minitest-rails

    View Slide

  137. 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 Slide

  138. 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 Slide

  139. But Pinkie!

    View Slide

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

    View Slide

  141. 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 Slide

  142. 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 Slide

  143. 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 Slide

  144. 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 Slide

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

    View Slide

  146. 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 Slide

  147. But Pinkie!

    View Slide

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

    View Slide

  149. 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 Slide

  150. 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 Slide

  151. But Pinkie!

    View Slide

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

    View Slide

  153. minitest-rails-capybara

    View Slide

  154. 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 Slide

  155. 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 Slide

  156. 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 Slide

  157. 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 Slide

  158. 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 Slide

  159. 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 Slide

  160. 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 Slide

  161. 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 Slide

  162. 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 Slide

  163. 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 Slide

  164. 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 Slide

  165. 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 Slide

  166. 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 Slide

  167. But Pinkie!

    View Slide

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

    View Slide

  169. 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 Slide

  170. 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 Slide

  171. 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 Slide

  172. 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 Slide

  173. 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 Slide

  174. 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 Slide

  175. 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 Slide

  176. 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 Slide

  177. 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 Slide

  178. 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 Slide

  179. 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 Slide

  180. But Pinkie!

    View Slide

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

    View Slide

  182. View Slide

  183. View Slide

  184. View Slide

  185. View Slide

  186. I’m sorry

    View Slide

  187. View Slide

  188. Mike Moore
    @blowmage
    blowmage.com

    View Slide

  189. Questions/Comments?

    View Slide

  190. 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 Slide

  191. 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 Slide

  192. 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 Slide

  193. View Slide