A Big Look at MiniTest

Preview:

DESCRIPTION

Presented at BostonRB on September 10th, 2013

Citation preview

@markbates

Tuesday, September 10, 13

A

Tuesday, September 10, 13

BIGTuesday, September 10, 13

look at

Tuesday, September 10, 13

MiniTest

Tuesday, September 10, 13

Tuesday, September 10, 13

Tuesday, September 10, 13

#  Running  tests:  ...........................................  Finished  tests  in  1.851323s,  1.6014  tests/s,  6.7781  assertions/s.  43  tests,  182  assertions,  0  failures,  0  errors,  0  skips

Tuesday, September 10, 13

Step 1: Setup Testing Framework

Tuesday, September 10, 13

Tuesday, September 10, 13

Tuesday, September 10, 13

Tuesday, September 10, 13

Tuesday, September 10, 13

• RSpec

• MiniTest

• test-unit

• Bacon

• Riot

• Wrong

• Shindo

• testrocket

• rubydoctest

• Testy

• Micronaut

• Kintama

• dtf

• assert

• test_inline

• Lemon

• Detest

Tuesday, September 10, 13

MiniTest

Tuesday, September 10, 13

Good Things Come in Small Packages

Tuesday, September 10, 13

Tuesday, September 10, 13

Tuesday, September 10, 13

Tuesday, September 10, 13

Tuesday, September 10, 13

require  'minitest/autorun'  class  Foo    def  add(x,  y)        x  +  y    endend  describe  Foo  do    describe  '#add'  do        it  'adds  two  numbers'  do            Foo.new.add(4,  2).must_equal  6        end    endend

Tuesday, September 10, 13

require  'minitest/autorun'  class  Foo    def  add(x,  y)        x  +  y    endend  class  TestFoo  <  MiniTest::Unit::TestCase    def  test_add        assert_equal  6,  Foo.new.add(4,  2)    endend

Tuesday, September 10, 13

Tuesday, September 10, 13

IT SHIPS WITH RUBY!!!

Tuesday, September 10, 13

>= 1.9

Tuesday, September 10, 13

also available as a gem

Tuesday, September 10, 13

Familiar Syntax to RSpec or Test::Unit

Tuesday, September 10, 13

MiniTest replaced Test::Unit in 1.9

Tuesday, September 10, 13

The Basics

Tuesday, September 10, 13

MiniTest::Spec

Tuesday, September 10, 13

describe  Something  do      it  "does  something"  do          #  tests  go  here    end  end

Tuesday, September 10, 13

describe  Something  do      before  do          #  setup  code  goes  here    end      after  do          #  tear  down  code  goes  here    end      it  "does  something"  do          #  tests  go  here    end  end

Tuesday, September 10, 13

describe  Something  do      describe  'something  else'  do          it  "does  something"  do              #  tests  go  here        end      end  end

Tuesday, September 10, 13

describe  Something  do      let(:something)  {  Something.new(name:  'Widget')  }      describe  'something  else'  do          it  "does  something"  do            something.name.must_equal  'Widget'        end      end  end

Tuesday, September 10, 13

describe  Something  do      subject  {  Something.new(name:  'Widget')  }      describe  'something  else'  do          it  "does  something"  do            subject.name.must_equal  'Widget'        end      end  end

Tuesday, September 10, 13

describe  Something  do      subject  {  Something.new(name:  'Widget')  }      context  'something  else'  do          it  "does  something"  do            subject.name.must_equal  'Widget'        end      end  end

Tuesday, September 10, 13

scrap.rb:19:in  `block  in  <main>':  undefined  method  `context'  for  #<Class:0x007fce92074b40>  (NoMethodError)                from  /Users/markbates/.../lib/minitest/spec.rb:71:in  `class_eval'                from  /Users/markbates/.../lib/minitest/spec.rb:71:in  `describe'                from  scrap.rb:15:in  `<main>'

Tuesday, September 10, 13

class  MiniTest::Spec      class  <<  self        alias  :context  :describe    end  end

Tuesday, September 10, 13

Pending

Tuesday, September 10, 13

describe  Something  do      it  'does  something'      it  'does  something  else'  do        skip    end      it  'does  another  thing'  do        skip  "here's  some  reason  why"    end  end

Tuesday, September 10, 13

#  Running  tests:  SSS  Finished  tests  in  0.000912s,  3289.4737  tests/s,  0.0000  assertions/s.  3  tests,  0  assertions,  0  failures,  0  errors,  3  skips  

Tuesday, September 10, 13

Expectations

Tuesday, September 10, 13

• 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_epsilon

• must_equal

• must_include

• must_match

• must_output

• must_respond_to

• must_raise

• must_send

• must_throw

Tuesday, September 10, 13

• 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_silent

• wont_be_within_epsilon

• wont_equal

• wont_include

• wont_match

• wont_output

• wont_respond_to

• wont_raise

• wont_send

• wont_throw

Tuesday, September 10, 13

describe  Something  do      it  "does  something"  do        lambda  {nil  /  2}.must_raise  NoMethodError        ["one",  "two"].must_include  "one"        ["one",  "two"].wont_include  "three"        nil.must_be_nil        [].must_be  :empty?    end  end

Tuesday, September 10, 13

MiniTest::Unit

Tuesday, September 10, 13

class  TestSomething  <  MiniTest::Unit::TestCase      def  test_something        #tests  go  here    end  end

Tuesday, September 10, 13

class  TestSomething  <  MiniTest::Unit::TestCase      def  setup        #  setup  code  goes  here    end      def  teardown        #  tear  down  code  goes  here    end      def  test_something        #  tests  go  here    end  end

Tuesday, September 10, 13

class  TestSomething  <  MiniTest::Unit::TestCase      def  test_something        assert  true    end      class  TestSomethingElse  <  MiniTest::Unit::TestCase            def  test_something_else            assert  true        end            end  end

Tuesday, September 10, 13

No let

Tuesday, September 10, 13

No subject

Tuesday, September 10, 13

Pending

Tuesday, September 10, 13

class  SomethingTest  <  MiniTest::Unit::TestCase      def  test_something        skip    end      def  test_something_else        skip  "here's  some  reason  why"    end  end

Tuesday, September 10, 13

#  Running  tests:  SS  Finished  tests  in  0.000663s,  3016.5913  tests/s,  0.0000  assertions/s.  2  tests,  0  assertions,  0  failures,  0  errors,  2  skips

Tuesday, September 10, 13

Assertions

Tuesday, September 10, 13

• 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_raises

• assert_respond_to

• assert_same

• assert_send

• assert_silent

Tuesday, September 10, 13

• refute

• refute_block

• 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_output

• refute_raises

• refute_respond_to

• refute_same

• refute_send

• refute_silent

Tuesday, September 10, 13

Mocking/Stubbing

Tuesday, September 10, 13

Very Basic

Tuesday, September 10, 13

describe  Something  do      let(:something)  {  MiniTest::Mock.new  }      it  "does  something"  do        something.expect(:name,  'Widget')        something.name.must_equal  'Widget'        something.verify    end  end

Tuesday, September 10, 13

describe  Something  do      let(:something)  {  MiniTest::Mock.new  }      it  "does  something"  do        something.expect(:name,  'Widget')        something.verify    end  end

Tuesday, September 10, 13

#  Running  tests:  E  Finished  tests  in  0.000858s,  1165.5012  tests/s,  0.0000  assertions/s.      1)  Error:OpenStruct#test_0001_does  something:MockExpectationError:  expected  name()  =>  "Widget",  got  []        scrap.rb:22:in  `block  (2  levels)  in  <main>'  1  tests,  0  assertions,  0  failures,  1  errors,  0  skips  

Tuesday, September 10, 13

describe  Something  do      let(:something)  {  Something.new(name:  'Widget')  }      it  "does  something"  do        something.stub(:name,  'Thingy')  do            something.name.must_equal  'Thingy'        end    end  end

Tuesday, September 10, 13

Struct, OpenStruct

Tuesday, September 10, 13

describe  "Something"  do      let(:something)  {  OpenStruct.new(name:  'Widget')  }      it  "does  something"  do        something.name.must_equal  'Widget'    end  end

Tuesday, September 10, 13

describe  Something  do      let(:something)  {  Something.new(name:  'Widget')  }      it  "does  something"  do        def  something.name            "Thingy"        end        something.name.must_equal  'Thingy'    end  end

Tuesday, September 10, 13

Mocha, RR, FlexMock

Tuesday, September 10, 13

CustomAssertions

Tuesday, September 10, 13

describe  Something  do      it  "does  something"  do        1.2.must_round_to  1        1.7.wont_round_to  1    end  end

Tuesday, September 10, 13

module  MiniTest::Assertions      def  assert_equals_rounded(rounded,  decimal)        assert  rounded  ==  decimal.round,  "Expected  #{decimal}  to  round  to  #{rounded}"    end      def  refute_equals_rounded(rounded,  decimal)        assert  rounded  !=  decimal.round,  "Expected  #{decimal}  to  not  round  to  #{rounded}"    end  end  Numeric.infect_an_assertion  :assert_equals_rounded,  :must_round_toNumeric.infect_an_assertion  :refute_equals_rounded,  :wont_round_to

Tuesday, September 10, 13

describe  Something  do      it  "does  something"  do        1.2.must_round_to  1        1.7.wont_round_to  1    end  end

Tuesday, September 10, 13

Rails

Tuesday, September 10, 13

gem “minitest-rails”

Tuesday, September 10, 13

ENV["RAILS_ENV"]  =  "test"require  File.expand_path("../../config/environment",  __FILE__)require  "rails/test_help"require  "minitest/rails"  #  Add  `gem  "minitest-­‐rails-­‐capybara"`  to  the  test  group  of  your  Gemfile#  and  uncomment  the  following  if  you  want  Capybara  feature  tests#  require  "minitest/rails/capybara"  module  MiniTest::Expectations    infect_an_assertion  :assert_redirected_to,  :must_redirect_to    infect_an_assertion  :assert_template,  :must_render_template    infect_an_assertion  :assert_response,  :must_respond_withend  class  ActiveSupport::TestCase      #  Add  more  helper  methods  to  be  used  by  all  tests  here...    before  do    end      after  do    end  end

Tuesday, September 10, 13

rake  minitest                              #  Run  default  testsrake  minitest:all                      #  Run  all  testsrake  minitest:all:quick          #  Run  all  tests,  ungrouped  for  quicker  executionrake  minitest:controllers      #  Runs  tests  under  test/controllersrake  minitest:lib                      #  Runs  tests  under  test/librake  minitest:models                #  Runs  tests  under  test/models

Tuesday, September 10, 13

task  :mt  =>  'minitest:all:quick'Rake::Task["default"].cleartask  :default  =>  :mt

Tuesday, September 10, 13

ruby  -­‐I  test  test/models/user_test.rb

Tuesday, September 10, 13

describe  FeedController  do      describe  '#index'  do          it  'renders  an  atom  feed'  do            get  :index              must_render_template  :index        end          it  'redirects  from  an  RSS  feed'  do            get  :index,  format:  'rss'              must_redirect_to  feed_path(format:  :atom)        end      end  end

Tuesday, September 10, 13

gem “guard-minitest”

Tuesday, September 10, 13

guard  :minitest  do    watch(%r|^app/controllers/(.*)\.rb|)  {  |m|  "test/controllers/#{m[1]}_test.rb"  }    watch(%r|^app/helpers/(.*)\.rb|)          {  |m|  "test/helpers/#{m[1]}_test.rb"  }    watch(%r|^app/models/(.*)\.rb|)            {  |m|  "test/models/#{m[1]}_test.rb"  }    watch(%r{^test/test_helper\.rb})          {  'test'  }    watch(%r{^test/.+_test\.rb})    watch(%r{^app/(.+)\.rb})                                                              {  |m|  "test/#{m[1]}_test.rb"  }    watch(%r{^app/controllers/application_controller\.rb})  {  'test/controllers'  }    watch(%r{^lib/(.+)\.rb})                                                              {  |m|  "test/lib/#{m[1]}_test.rb"  }end

Tuesday, September 10, 13

gem “m”

Tuesday, September 10, 13

m  test/models/user_test.rb:37

Tuesday, September 10, 13

gem “minitest-rails-capybara”

Tuesday, September 10, 13

feature  "Can  Access  Home"  do      scenario  "has  content"  do        visit  root_path        assert  page.has_content?("Home#index")    end    end

Tuesday, September 10, 13

Wrapping Up

Tuesday, September 10, 13

familiar syntax

Tuesday, September 10, 13

95% of RSpec

Tuesday, September 10, 13

lightweight

Tuesday, September 10, 13

rspec  (2.14.1)    rspec-­‐core  (~>  2.14.0)    rspec-­‐expectations  (~>  2.14.0)    rspec-­‐mocks  (~>  2.14.0)rspec-­‐core  (2.14.5)rspec-­‐expectations  (2.14.2)    diff-­‐lcs  (>=  1.1.3,  <  2.0)

Tuesday, September 10, 13

Ships with Ruby!

Tuesday, September 10, 13

• https://github.com/seattlerb/minitest

• http://www.mattsears.com/articles/2011/12/10/minitest-quick-reference

• http://blog.arvidandersson.se/2012/03/28/minimalicous-testing-in-ruby-1-9

• https://github.com/blowmage/minitest-rails-capybara

• https://github.com/guard/guard-minitest

• https://github.com/qrush/m

• http://www.metacasts.tv/casts/minitest-spec

• http://www.metacasts.tv/casts/minitest-rails

• http://www.metacasts.tv/casts/testing-sinatra

Tuesday, September 10, 13

Thanks!@markbates

www.metacasts.tv

Tuesday, September 10, 13

Recommended