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

Bow Before MiniTest

Adam Hawkins
November 14, 2012

Bow Before MiniTest

Why MiniTest is the boss sauce

Adam Hawkins

November 14, 2012

Transcript

47 slides
  1. Forget Cucumber! • Long term cucumber use is detrimental to

    your brain • Makes you learn another syntax to write tests • Managing large test suites is painful • Small number of good use cases
  2. MiniTest & Test::Unit • Test::Unit is MiniTest in Ruby 1.9

    • Test::Unit is a compatibility layer around MiniTest • This is for backward compatibility • We can forget about Test::Unit too...
  3. Things a Test Framework Should Do • Make it easy

    to write and maintain tests • Run tests in random order • Believe me, this will find bugs in your code • Make you focus on testing your code and not learning the framework yourself
  4. Results # Tests MiniTest Rspec 1.000 0.069 0.428 10.000 0.730

    3.92 100.000 8.345 39.53 Times in Seconds
  5. Analysis • MiniTest is clearly faster on tremendously large test

    suites • MiniTest is notably faster on smaller tests suites • RSpec will continue to slow down rapidly because matchers create objects which trigger garbage collection • Developers may notice a difference in typical test suites
  6. # 1. describe Person detects that the described # object

    is a class so `Person.new` is called # implicitly before each test and assigned to # `subject` describe Person do its(:phone_number) { should =~ /^\d+$/ } end
  7. describe Person do # Call the `phone_number` method on subject

    # an assign it's return value to `subject` # inside the test block its(:phone_number) { should =~ /^\d+$/ } end
  8. describe Person do # Call should on the implicit subject

    # so it can be tested against the regex its(:phone_number) { should =~ /^\d+$/ } end
  9. # There is a large API for this! # This

    is the most simple case RSpec::Matchers.define :be_valid do match do |model| model.valid? end end
  10. def test_vendor_comes_before_app # do stuff to build a file content

    = read "site/application.js" assert_includes content, "APP" assert_includes content, "VENDOR" assert content.index("VENDOR") < content.index("APP"), "Vendor should come before App!" end
  11. def test_vendor_comes_before_app content = read "site/application.js" assert_before content, "VENDOR", "APP"

    end def assert_before(source, first, second) assert_includes content, first assert_includes content, second assert content.index(first) < content.index(source), "#{first} should be before #{second}" end
  12. Why? • Minimal feature set: focus on writing code •

    Removing a complex mocking/stubbing library makes you consider design • Run tests in random order--this will usually find bugs in your test suite or code • Can run your tests in parallel
  13. require 'minitest/unit' require 'minitest/hell' # put your tests through the

    ringer require 'minitest/autorun' class ParallelTests < MiniTest::Unit::TestCase def test_multi_threading # ... end end
  14. Why MiniTest? • Its faster and lighter than Rspec •

    Its much easier to understand and extend • Random & parallel tests out of the box • Its part of the standard library so it’s available everywhere • More stable and better supported than Rspec • It will make your test suite better!
  15. Why Rspec? • $ rspec foo_spec.rb • Running individual tests

    is trivially easy • You like DSL’s and complexity

More Decks by Adam Hawkins

Other Decks in Programming