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

TDD using Minitest

Avatar for diogenes diogenes
August 08, 2015
330

TDD using Minitest

Talk gave in the 1º Tech Day, GURU-PR 2015 @ EBANX Headquarters

Avatar for diogenes

diogenes

August 08, 2015
Tweet

Transcript

  1. Agenda • Test-Driven Development ◦ Overview ◦ Why to use

    • Minitest ◦ Overview ◦ How to use
  2. "... a software development process that relies on the repetition

    of a very short development cycle: first the developer writes an (initially failing) automated test case that defines a desired improvement, then produces the minimum amount of code to pass that test, and finally refactors the new code to acceptable standards." Wikipedia
  3. Better Code Design • Focus on How to use, its

    Interface/API "the expected behavior" rather than "how this is implemented"
  4. Better Code Design • Feedback from Test Smells ◦ Over-mocking

    ◦ Hard to write tests ◦ Too much responsibility ◦ Too many assertions
  5. Code Design Feedback - Example describe User do subject {

    User.new } describe "its registration process" do let(:address) { AnObject.new } let(:phone) { Another.new } let(:children) { OtherOne.new } let(:mailer) { AnyObject.new } # etc... it "saves the related address" do # Test saving of the address end it "saves the related children" do # Test saving of children end it "saves the related phones" ... it "saves the user" ... it "sends and email to the user" ... end end
  6. What's Minitest? • Replacement for Ruby 1.8's test/unit ◦ Originally

    90 lines of code • Available built-in with Ruby 1.9 • Available as a gem • Meant to be small, clean, and very fast
  7. What's Minitest? 6 parts • runner: The heart of the

    machine • minitest/unit: TDD API • minitest/spec: BDD API • minitest/mock: Simple mocking API • minitest/pride: IO pipelining example • minitest/bench: Abstract benchmark API
  8. Minitest Philosophy • Less is more ◦ Very small in

    comparison with RSpec ◦ Very Fast • Isolated Tests ◦ Test Randomization: Prevents order dependencies • Indirection is the Enemy ◦ Failures pointing to the failure
  9. minitest positive assertions assert assert_block * assert_empty assert_equal assert_in_delta assert_in_epsilon

    assert_includes assert_instance_of assert_kind_of assert_match assert_nil assert_operator assert_output * assert_predicate assert_raises * assert_respond_to assert_same assert_send * assert_silent * assert_throws *
  10. minitest negative assertions refute refute_empty refute_equal refute_in_delta refute_in_epsilon refute_includes refute_instance_of

    refute_kind_of refute_match refute_nil refute_operator refute_predicate refute_respond_to refute_same
  11. minitest expectations must_be must_be_close_to must_be_empty must_be_instance_of must_be_kind_of must_be_nil must_be_same_as must_be_silent

    * must_be_within_delta must_be_within_epsilon must_equal must_include must_match must_output * must_raise * must_respond_to must_send * must_throw *
  12. minitest negative expectations wont_be wont_be_close_to wont_be_empty wont_be_instance_of wont_be_kind_of wont_be_nil wont_be_same_as

    wont_be_within_delta wont_be_within_epsilon wont_equal wont_include wont_match wont_respond_to
  13. Minitest Ecosystem minitest-chef-handler minitest-reporters minitest-rails guard-minitest minitest-spec-rails minitest-capybara spork-minitest minitest-metadata

    minitest-rails-capybara minitest-matchers capybara_minitest_spec minitest-colorize minitest-rg minitest-ci (many more…)
  14. Red - Write the test require 'minitest/autorun' describe Article do

    subject { Article.new } it "can be posted on Twitter" do subject.post_on_twitter subject.twitted?.must_equal true end end
  15. Red - See it failing $ ruby -Ilib spec/article_spec.rb Run

    options: --seed 34214 1) Error: Article#test_0001_can be posted on Twitter: NoMethodError: undefined method `post_on_twitter' for #<Article:0x000000012c75d0> spec/article_spec.rb:8:in `block (2 levels) in <main>' 1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
  16. Red - See it failing $ ruby -Ilib spec/article_spec.rb Run

    options: --seed 47611 1) Error: Article#test_0001_can be posted on Twitter: NoMethodError: undefined method `twitted?' for #<Article: 0x00000002347130> spec/article_spec.rb:9:in `block (2 levels) in <main>' 1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
  17. Red - See it failing $ ruby -Ilib spec/article_spec.rb Run

    options: --seed 19132 # Running: F... 1) Failure: Article#test_0001_can be posted on Twitter [spec/article_spec. rb:9]: Expected: true Actual: nil
  18. Green - Implements the code class Article def post_on_twitter #

    Logic to post the article (...) @twitted = true end end
  19. Green - See it passing % ruby -Ilib spec/article_spec.rb Run

    options: --seed 37685 # Running: ......................................................... ............. (etc) Finished in 0.107130s, 1446.8403 runs/s, 2959.0217 assertions/s. 155 runs, 317 assertions, 0 failures, 0 errors, 0 skips
  20. Green - See it passing % ruby -Ilib spec/article_spec.rb Run

    options: --seed 37685 # Running: ......................................................... ............. (etc) Finished in 0.107130s, 1446.8403 runs/s, 2959.0217 assertions/s. 155 runs, 317 assertions, 0 failures, 0 errors, 0 skips