a big look at minitest
DESCRIPTION
Presented at ArrrrCamp.be on October 4th, 2013TRANSCRIPT
@markbates
Friday, October 4, 13
good morningbonjour
goedemorgen
Friday, October 4, 13
after last night...
Friday, October 4, 13
a change of topic...
Friday, October 4, 13
watch mark sleep...
Friday, October 4, 13
isn’t this nice?
Friday, October 4, 13
do not disturb
Friday, October 4, 13
shh...
Friday, October 4, 13
fine, i’ll get up!
Friday, October 4, 13
@markbates
Friday, October 4, 13
hire me*(consulting only)
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
PIRATE13www.metacasts.tv
Friday, October 4, 13
Friday, October 4, 13
A
Friday, October 4, 13
BIGFriday, October 4, 13
look at
Friday, October 4, 13
MiniTest
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 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
Friday, October 4, 13
Step 1: Setup Testing Framework
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
• RSpec
• MiniTest
• test-unit
• Bacon
• Riot
• Wrong
• Shindo
• testrocket
• rubydoctest
• Testy
• Micronaut
• Kintama
• dtf
• assert
• test_inline
• Lemon
• Detest
Friday, October 4, 13
MiniTest
Friday, October 4, 13
Good Things Come in Small Packages
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 13
Friday, October 4, 13
IT SHIPS WITH RUBY!!!
Friday, October 4, 13
>= 1.9
Friday, October 4, 13
also available as a gem
Friday, October 4, 13
Familiar Syntax to RSpec or Test::Unit
Friday, October 4, 13
MiniTest replaced Test::Unit in 1.9
Friday, October 4, 13
The Basics
Friday, October 4, 13
MiniTest::Spec
Friday, October 4, 13
describe Something do
end
Friday, October 4, 13
describe Something do it "does something" do # tests go here end end
Friday, October 4, 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
Friday, October 4, 13
describe Something do describe 'something else' do it "does something" do # tests go here end end end
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 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>'
Friday, October 4, 13
class MiniTest::Spec
end
Friday, October 4, 13
class MiniTest::Spec class << self alias :context :describe end end
Friday, October 4, 13
Pending
Friday, October 4, 13
describe Something do end
Friday, October 4, 13
describe Something do it 'does something' end
Friday, October 4, 13
describe Something do it 'does something' it 'does something else' do skip end end
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 13
Expectations
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 13
MiniTest::Unit
Friday, October 4, 13
class TestSomething < MiniTest::Unit::TestCase end
Friday, October 4, 13
class TestSomething < MiniTest::Unit::TestCase def test_something #tests go here end end
Friday, October 4, 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
Friday, October 4, 13
class TestSomething < MiniTest::Unit::TestCase def test_something assert true end end
Friday, October 4, 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
Friday, October 4, 13
No let
Friday, October 4, 13
No subject
Friday, October 4, 13
Pending
Friday, October 4, 13
class SomethingTest < MiniTest::Unit::TestCase end
Friday, October 4, 13
class SomethingTest < MiniTest::Unit::TestCase def test_something skip end end
Friday, October 4, 13
class SomethingTest < MiniTest::Unit::TestCase def test_something skip end def test_something_else skip "here's some reason why" end end
Friday, October 4, 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
Friday, October 4, 13
Assertions
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 13
Mocking/Stubbing
Friday, October 4, 13
Very Basic
Friday, October 4, 13
describe Something do let(:something) { MiniTest::Mock.new } it "does something" do end end
Friday, October 4, 13
describe Something do let(:something) { MiniTest::Mock.new } it "does something" do something.expect(:name, 'Widget') end end
Friday, October 4, 13
describe Something do let(:something) { MiniTest::Mock.new } it "does something" do something.expect(:name, 'Widget') something.name.must_equal 'Widget' end end
Friday, October 4, 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
Friday, October 4, 13
describe Something do let(:something) { MiniTest::Mock.new } it "does something" do something.expect(:name, 'Widget') something.verify end end
Friday, October 4, 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
Friday, October 4, 13
describe Something do let(:something) { Something.new(name: 'Widget') } it "does something" do end end
Friday, October 4, 13
describe Something do let(:something) { Something.new(name: 'Widget') } it "does something" do something.stub(:name, 'Thingy') do end end end
Friday, October 4, 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
Friday, October 4, 13
Struct, OpenStruct
Friday, October 4, 13
describe "Something" do let(:something) { OpenStruct.new(name: 'Widget') } it "does something" do something.name.must_equal 'Widget' end end
Friday, October 4, 13
describe Something do let(:something) { Something.new(name: 'Widget') } it "does something" do something.name.must_equal 'Thingy' end end
Friday, October 4, 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
Friday, October 4, 13
Mocha, RR, FlexMock
Friday, October 4, 13
CustomAssertions
Friday, October 4, 13
describe Something do it "does something" do 1.2.must_round_to 1 1.7.wont_round_to 1 end end
Friday, October 4, 13
module MiniTest::Assertions end
Friday, October 4, 13
module MiniTest::Assertions def assert_equals_rounded(rounded, decimal) end end
Friday, October 4, 13
module MiniTest::Assertions def assert_equals_rounded(rounded, decimal) assert rounded == decimal.round, "Expected #{decimal} to round to #{rounded}" end end
Friday, October 4, 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) end end
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 13
describe Something do it "does something" do 1.2.must_round_to 1 1.7.wont_round_to 1 end end
Friday, October 4, 13
Rails
Friday, October 4, 13
gem “minitest-rails”
Friday, October 4, 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"
Friday, October 4, 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"
class ActiveSupport::TestCase # Add more helper methods to be used by all tests here... before do end after do end end
Friday, October 4, 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
Friday, October 4, 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
Friday, October 4, 13
task :mt => 'minitest:all:quick'Rake::Task["default"].cleartask :default => :mt
Friday, October 4, 13
ruby -‐I test test/models/user_test.rb
Friday, October 4, 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
Friday, October 4, 13
gem “guard-minitest”
Friday, October 4, 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
Friday, October 4, 13
gem “m”
Friday, October 4, 13
m test/models/user_test.rb:37
Friday, October 4, 13
gem “minitest-rails-capybara”
Friday, October 4, 13
feature "Can Access Home" do scenario "has content" do visit root_path assert page.has_content?("Home#index") end end
Friday, October 4, 13
Wrapping Up
Friday, October 4, 13
familiar syntax
Friday, October 4, 13
95% of RSpec
Friday, October 4, 13
lightweight
Friday, October 4, 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)
Friday, October 4, 13
Ships with Ruby!
Friday, October 4, 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
Friday, October 4, 13
Thanks!@markbates
www.metacasts.tv
Friday, October 4, 13