미니테스트
AGAIN 2011 RAILS WORKSHOP
2016-07-24

미니테스트 개요
- 테스트 프레임워크가 필요한 이유
- LESS Bugs vs MORE Lines of Code
- Test-First 테스트 코드부터 작성하는 습관
-
RED, GREEN, REFACTOR
- red 코드를 작성하기 전에 테스트 코드 실행하면 실패
- green 테스트 코드가 통과하도록 실제 코드를 작성함.
- refactor 작성한 코드를 개선
- 부정적 이미지 Over-engineering
테스트에 대한 의견 참고
미니테스트 장점
-
미니테스트 장점
-
알스펙보다 빠르고 가볍다.
참고: 알스펙(RSpec)은 2015년 5월까지 1위 (ruby-toolbox) 그 이후 2016년 7월 현재 미니테스트 1위 -
이해하기 쉽고 확장하기 좋다.
-
순서와 무관하게 실행할 수 있고 동시에 여러개를 실행할 수 있다.
-
루비 1.9+ 테스트 유닛을 대체함
미니테스트 사례
# string_digit_test.rb
require 'minitest/autorun'
require 'string_digit'
# ruby -I . string_digit_test.rb
class StringDigitTest < MiniTest::Unit::TestCase
def test_is_digit
assert "5".is_digit?
end
def test_is_not_digit
assert !"five".is_digit?
end
end# string_digit.rb
class String
# FIRST CODE
def is_digit?
if self =~ /^\d+$/
true
else
false
end
end
# REFACTOR
# def is_digit?
# self =~ /^\d+$/
# end
endMiniTest::Unit::TestCase is now Minitest::Test. From string_digit_test.rb:4:in `<main>'
Run options: --seed 4697
# Running:
EE
Finished in 0.001373s, 1456.7863 runs/s, 0.0000 assertions/s.
1) Error:
StringDigitTest#test_is_not_digit:
NoMethodError: undefined method `is_digit?' for "five":String
string_digit_test.rb:10:in `test_is_not_digit'
2) Error:
StringDigitTest#test_is_digit:
NoMethodError: undefined method `is_digit?' for "5":String
string_digit_test.rb:6:in `test_is_digit'
2 runs, 0 assertions, 0 failures, 2 errors, 0 skipsRun options: --seed 23319
# Running:
..
Finished in 0.001428s, 1400.2582 runs/s, 1400.2582 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skipsassertions
- 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
assertions
- assert <condtional>
- assert_equal <expected>, <actual>
- assert_not_equal
- assert_respond_to <object>, :method
- assert_nil <object>
- assert_match <pattern>, <string>
- assert_raise(<error>) { <code> }
- assert_kind_of(<Class>, <object>)
spec-style
describe Something do
subject { Something.new(name: 'Widget') }
context 'something else' do
it 'does something' do
subject.name.must_equal 'Widget'
end
end
end
class MiniTest::Spec
class << self
alias :context, :describe
end
enddescribe 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
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
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_within_epsilon
- must_be
-
must_equal
-
must_include
-
must_match
-
must_output
-
must_respond_to
-
must_raise
-
must_send
-
must_throw
must_ <=> wont_
custom assertion
module MiniTst::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_to
Numeric.infect_an_assertion :refute_equals_rounded, :wont_round_to
decribe Something do
it "does something" do
1.2.must_round_to 1
1.7.wont_round_to 1
end
endrails testing with minitest
#Gemfile
group :test do
gem 'minitest'
gem 'capybara'
end
#test/minitest_helper.rb
ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "minitest/autorun"
require "capybara/rails"
require "active_support/testing/setup_and_teardown"
class IntegrationTest < MiniTest::Spec
include Rails.application.routes.url_helpers
include Capybara::DSL
register_spec_type(/integration$/, self)
end
class HelperTest < MiniTest::Spec
include ActiveSupport::Testing::SetupAndTeardown
include ActionView::TestCase::Behavior
register_spec_type(/Helper$/, self)
end
#lib/tasks/minitest.rake
require "rake/testtask"
Rake::TestTask.new(:test => "db:test:prepare") do |t|
t.libs << "test"
t.pattern = "test/**/*_test.rb"
end
task :default => :test
rails new store -T
rails g scaffold product name price:decimal released_on:date#Gemfile
group :test do
minitest-rails
minitest-rails-capybara
end
rails testing with minitest
/test/model/product_test.rb
require "minitest_helper"
class ProductTest < MiniTest::Unit::TestCase
def test_to_param
product = Product.create!(name: "Hello World")
assert_equal "#{product.id}-hello-world", product.to_param
end
end#test/integration/products_integration_test.rb
require "minitest_helper"
describe "Products integration" do
it "shows product's name" do
product = Product.create!(name: "Tofu")
visit product_path(product)
page.text.must_include "Tofu"
end
end#test/helpers/product_helper_test.rb
require "minitest_helper"
describe ProductsHelper do
it "converts number to currency" do
number_to_currency(5).must_equal "$5.00"
end
end
railscast https://www.youtube.com/watch?v=T3rCJftb7aY
참고 자료
https://www.facebook.com/seongjun.p.kim/posts/1058363404212697
Minitest Insights with Ryan Davis https://vimeo.com/75833835
RailsConf 2015 - Ruby on Rails on Minitest
https://www.youtube.com/watch?v=MA4jJNUG_dI
How to Use MiniTest
http://blog.teamtreehouse.com/short-introduction-minitest
railscast how i test
https://www.youtube.com/watch?v=AQ-Vf157Ju8
감사합니다.
Welcome to minitest
By wagurano
Welcome to minitest
again2011 rails workshop
- 1,423