ϥڥåΥ 1 RSpec γפȡRSpec on Rails (ǥ)
: ˡϤ
- ϢܤˤĤ
- RSpec Ȥϲ
- ʤRSpec ʤΤ
- RSpec δñʻȤ
- ڥåեι¤
- ڥåե̿̾
- (Behaviour)
- ¹Բǽʥץ (example)
- before / after å
- ڥơ (expectation)
- üʥڥơ
- ޤǤΤޤȤ
- RSpec on Rails
- Rails ץȤκ
- RSpec on Rails Υȡ
- RSpec on Rails ѥե
- RSpec on Rails Υƥѥǥ쥯ȥ깽
- RSpec on Rails ϰϤŪ
- ֥ץꥱΥǥ
- Blog ǥκ
- Entry ǥκ
- ͽ
- ԤˤĤ
- ХåʥС
ϢܤˤĤ
ϢܤǤ Test::Unit ؤե졼Ǥ RSpecλȤ䡢ظˤͤʬϢܷǤϤޤ ϢΤ̤ơʲΤ褦ƤҲ𤷤ȹͤƤޤ
- RSpec ȤϲRSpec λȤä Rspec on Rails Ȥä Rails ץ곫ȯؤŬ
- ƥȶưȯοʤȡƥȶưȯŪ߷ץץ
- RSpec λȤߤȳĥˡ
FAQ:RSpec äơפ Test::Unit ǤäƤ뤳Ȥ̤νˤǤϡ
ꤷ FAQ Ǥ FAQ ؤûϥǤ ΡֽפͤλͤѤƤޤȤRubyist γϤ褯ΤäƤ Ȼפޤ Ϣܤϡ FAQ ؤĹǤڤߤйǤ
ʤ䤿
RSpec ˤ̴!!סϻ䤿(ˤ) RSpec å (?) Ǥ䤿ˤȤä RSpec ȤϡMartin Fowler RailsConf2007 Ruby ߥ˥ƥФ ɤˤߤǤRSpec ϡWard ( Cunningham) Kent ( Beck) 줫顢쥤ʥɡޤ줿֥Ȼظ߷סơƥȤ䤹ˤĤƤ٤Ƥοͤβ͡פ褦ȤƤޤ
Ϣܤ̤Ƥͤ餫ǤɼԤγ줿ȻפȤˤޤ
оɼ
Ruby ɸźդΥƥƥե졼Ǥ Test::Unit ¿ϻȤä Ȥ뤳ȤȤƤޤ
ƥȶưȯƥȥեȤȤäץൻˡ ηиȤƤޤ
оݤȤС
ɮǤκǿСоݤȤޤĤޤꡢ 1.0.8 Ǥ
RSpec 0.8.x 1.0.x Ȥδ֤ API ѹޤϢ ǤϿ API ȵ API Ȥб API ΰܹԤˤĤƤϴŪ˸ڤޤ (ץΰƤ줿 RSpec ϻ!)
0.8.x 1.0x ϤؤΰܹԤˤĤƤϡRSpec ΥץȤΥɥȤ Upgrading from RSpec 0.8.x or earlier id:moro εͤˤƤ
ϰ
ϢܤνǤ뺣ϡ 4 Ȼפޤ
- RSpec Ȥϲ
- RSpec δñʻȤ
- ڥåեι¤
- RSpec on Rails (ޤ)
RSpec on Rails ˤĤƤϡǤޤΤǡ ʹߤ³ޤʲǽ֤ƤޤRSpec Ȥϲ Ǥ RSpec ŪˤĤƾܤޤRSpec ŪϤ⤦ΤäƤ롢ȤͤϡRSpec δñʻȤפɤ߿ʤƤ
RSpec Ȥϲ
RSpec ȤϡˤС֥ץο (behaviour)פҤ뤿Υɥᥤò (DomainSpecific Language:DSL) ե졼Ǥ
ץο ɥᥤò졩ġĽ֤Ƥ
ץο (behaviour)
֥ץοפȤϥץΤ뤤͡ʥ٥Ǥʬ ( 塼䥯饹å) ФƴԤ뿶 (behaviour:ӥإӥ) ȤǤȤäƤⲿ̤ʤΤǤϤޤ
ޤ礦㤨С Array ξ˴Ԥ 뿶ϼΤ褦ʤΤǤ
arr = [] arr.empty? #=> Ȥ true ֤ȤԤ arr.size #=> Ȥ 0 ֤ȤԤ
Test::Unit ȤäƼΤ褦˽ޤ
require 'test/unit'
class ArrayTest < Test::Unit::TestCase
def setup
@empty_array = []
end
def test_empty?
assert(@empty_array.empty?)
end
def test_size
assert_equal(0, @empty_array.size)
end
def teardown
@empty_array = nil
end
end
Ĥޤ֥ץοפȤäƤⲿΤǤϤޤ֤ޤ Test::Unit ǸڤƤΡפỌ̇̄ȤƱǤ
ʤΤ褦ʥƥȥ teardown åɤѤ뤳ȤϵǤ θ RSpec ǤεҤ椵뤿ˡƵҤƤޤ
ɥᥤò (DSL)
ɥᥤò (Domain Specific Language:DSL) Ȥϡΰ (ɥ ) Ҥ뤿߷פ줿ָפǤRSpec òƤɥᥤ ϡֳȯоݤΥץοҤפȤΰǤ
RSpec ϥץοҤȤơRuby ĥ뤳ȤӤ Τ褦ʡDSL DSL ¹Ԥ (ۥȸ) Ȥ ƱǤ DSL μץָ (internal) DSLפȸƤӤޤ
ʤߤˡDSL θȥۥȸȤۤʤΤ쳰 (external) DSL ȸ Ӥޤ쳰 DSL ȤƤϡJava Ǥ褯ȤƤӥɥġ Ant ޤAnt ϡDSL XML Ǥꡢۥȸ줬 Java Ǥ쳰 DSL ȹ ޤ
äŪˤʤäƤΤǡŪ RSpec εҤ DSL ɤΤ褦ʤ ΤҲ𤷤ޤӤΤˡۤɾҲ𤷤 Test::Unit ˤ Array Υƥȥ RSpec ǵҤȡΤ褦ˤʤޤ
describe Array, "when empty" do
before do
@empty_array = []
end
it "should be empty" do
@empty_array.should be_empty
end
it "should size 0" do
@empty_array.size.should == 0
end
after do
@empty_array = nil
end
end
ɤˤĤƤɡƤޤǤϡRSpec Ruby ĥ DSL ȤƥץοҤפȤȤμºݤʷϵ Ƥ
Test::Unit RSpec ȤǺǤ礭ۤʤϡTest::Unit Ǥϥ饹 ɤΤФRSpec Ǥϥ֥åդåɸƤӽФ䡢å άѤƵҤ Ruby ץȤˤʤäƤ뤳ȤǤ
ǵǤ after åɤȤäƤޤϡTest::Unit teardown åɤбΤ RSpec ˤѰդƤ뤳Ȥ ̤˸դɬפǤϤʤγ虜虜 after å ǵҤɬפϤޤ
ʤRSpec ʤΤ
Ǥϡʤ Test::Unit ǤϤʤRSpec ֤ΤǤ礦Ƭ FAQ Ƥӡ RSpec äơפ Test::Unit ǤäƤ뤳Ȥ̤νˤǤϡ Τˤ̤ʤΤǤΡֽפפȤΤ䤿λפǤ
RSpec ֿѤ DSLפơץޤ Test::Unit Ȥϰۤʤ ƤΤϡͤ䤿뤿ǤιͤȤϡ ƥȶưȯ (Test Driven Development:TDD) Ǥ
ƥȶưȯ (TDD)
RSpec ġ̤ƻ䤿褦ȤƤΤϡäˡTDD Ԥ Kent Beck إƥȶưȯǽҤ٤Τ褦ʹͤǤ
TDD 1 ĤϡTDD ƥȵˡǤϤʤ (˥ιͰ) Ǥ롣TDD ʬϼˡ߷ˡǤꡢºݤˤϳȯΤ٤ƤΥƥӥƥ¤뤿εˡǤ롣
TDD Ǥϡץ (ץȥ) ˤäơޤƥȥ ޤơƥȤμ¹ԤԤ뤳ȤǧƤ顢ƥȥ ɤѥ褦˥ץȥɤȤץߥοʤ Ǥ
RSpec ΥץߥФͤȡե졼Ȥƻٱ礹ץ ߥοʤ TDD ΤΤǤ
TDD οʤȸ§
TDD οʤϤäƴñǤTDD ϰʲ 3 ĤΥƥåפ鹽ޤ
- ץȥɤ˥ƥȥɤ줬Ԥ뤳Ȥǧ (å)
- ƥȤ褦˥ץȥɤ ()
- ץοѤʤ褦ˡץȥɤνʣʤɤ (ե)
- (ǽ)
֥åɡפ֥פȤäɽϡ xUnit*1 μ¹ԷɽСŪʿŤͳ褷ƤޤRSpec Ǥå/ ȤäȤƧƤޤ
TDD ˴Ϣ뵻ˡˤ͡ʤΤޤTDD θ§ϼ 3 ĤˤޤȤޤ
- ƥȤ˼Ԥʤ¤ꡢץȥɤƤϤʤ
- ץȥɤϥƥȤ̤褦˽
- ƥȤϾĽʤƤ
ϢܤǤ⡢RSpec on Rails Ȥä Rails ץꥱȯϤ §˽äƿʤƤޤ
եȥ߷פȤϲ
ޡTDD ˤĤƤǡ߷ספȸä֥ץߥפȸä ޤǤϢܤǤιͤƤޤ䤿ϡJack Reeves εեȥ߷פȤϲ פƤͤٻޤ
եȥ߷פȤϡեȥ˴Ԥ뿶褦˥ 뤳ȤǤեȥ߷פȤϡŪˤϥ饹 åɡ⥸塼뤳ȤǤꡢʪϥɤǤ Ĥޤꡢեȥ߷פȤϥץߥǤꡢץߥȤϥ եȥ߷פʤΤǤ
߷פʪϥɤǤ
ʤեȥ߷ (ץߥ) ʪɤʤΤ ϡ߷פʪϡ줬ư뤳ȤڲǽǤʤФʤʤǤ եȥˤơư뤳ȤڲǽʤΤ (ΤȤ) ɤǤ
Ǥ顢̩ˤСɡʤեȥ߷פȤϼ 2 ĤǤ鹽ޤ
- ƥȥ: ץबɤΤ褦˿٤
- ץȥ ƥȥɤ줿
RSpec ǤϡTDD ʸ̮dzȯư֥ƥȡפեȥ߷פ ǤȰդƤޤġȤƤιͤΤˤ뤿 ˡRSpec Test::Unit Ȥϰۤʤ뵭ˡѤTest::Unit ȤϰۤʤäƳ ޤ
Test::Unit RSpec θäΰ㤤
RSpec ϡTDD ֥ץȥɤˡޤƥȤפȤ̤褦Ȥͤ ʤץȥɤˡޤץοưǽʥץȤƽ ¸ xUnit ե졼٤ơ̤˲ФƤޤ
Ȥ RSpec ǤϡTest::Unit Ǥϡ֥ƥȥפȸƤФƤƥȥåɤΤȤ¹Բǽʥץ (example)פȸƤǤޤּ¹ԲǽʥץפΤĹɤΤΤǡϢܤǤ exampleפɽޤ
¾ˤ⡢RSpecϡTest::Unit ǡ֥ƥȥ饹פȸƤǤ롢ƥȥŪʤޤȤޤ (behaviour)פȸƤӡTest::Unit Ǥϡ֥ (assert)פȸƤǤ륳ɤθڤڥơ (expectation)פȸƤӤޤڥơȤϡ¹ԲǽʥץȤƥץοԤ뤳Ȥ̣Ǥ
Τ褦ˡTDD ǻȤƤ֥ƥȡפˤޤĤäưǽʥ ץȤƥץοҤפȤ TDD Υץߥοʤ֥ƥȤȤ߷פǤפȤȤ Ĵͤưȯ (Behaviour Driven Development:BDD)ȸƤ֤Ȥ ޤ*2
¤ˤ BDD Ϥޤåե졼ʾ¸ߴϼȤǤƤޤ ߤΤȤBDD ȤѸϡTDD Ԥδ֤ǤƤȤϸǤ
䤿Ūˡֿפ֥ӥإӥפȯΤϤޤäΤǡ ΤȤϡ֥ڥåפȸƤ֥ƥȡפȸƤȡ롼˻ȤäƤޤ
ϢܤǤ֥ƥȡפ֥ƥȥɡפȤս꤬ĤǤƤޤ ΤȤ˻ؤƤΤϡäǤ̵꤬¤ RSpec ץοΤȤȹͤƤ
ƥƥĶȤƤ RSpec
ޤǤϡRSpec ġȤɽ褦ȤƤͤ濴ˡʤ Test::Unit ǤϤʤ Rspec ʤΤȤȤҲ𤷤ޤ
RSpec ϡطʤˤͤʳˤ⡢Ūʴ Test::Unit RSpec ΤۤޤΤǾҲ𤷤ƤޤϡTest::Unit ֥ƥƥե졼פǤΤФơRspec ƥƥ ĶפǤ뤳ȤܻؤƤȤǤ
ŪˤСRSpec ϡѤ DSL ˲äơ͡ʥƥȴ Ϣ饤֥եġ礷ꡢɸॵݡȤȤäߤ ѶŪ³ƤޤʲˤɽŪʤΤꥹȤˤƤߤޤ
- RSpec ¹Է̤οդ (åɥС/ Сɽ) ɸॵݡ
- å Ȥäƥȵˡλٱ硢Ϣ饤֥Ȥ
- α (pending) Υݡ
- Rake RCovHeckleAutoTest (ZenTest) ȤäեġȤ
- Ruby on Rails Υݡ
- ͡ʷˤ¹Է̥ݡ (:HTML )
- TextMate Ȥ
- ʤɤʤ
ġζŪʹܤˤĤƤϡϢܤ̤ƾҲ𤹤Τ⤢Сʤ Τ⤢ޤ˵ˤʤäƻΤʤϡ줾ιܤ RSpec ȤγڡإĥäƤޤΤǡȤƤ
եġȤطʤˤϡRSpec ñʤ Test::Unit ֤ؤʾ¸ߤˤ褦ȤޤץޤΥƥȤεҡ¹ԴĶΤȤ¤ƤȤƥƥĶפȤǤƤ٤ʻ (ߤ) Test::Unit ˤ̵ΤǤ
ޤǤΤޤȤ
öޤǤޤȤƤޤ
Rspec ϥץޤ˥ƥȥɤ߷פǤ뤳ȤΤ˰ռ뤳Ȥȡץޤƥȥɤࡼ˵Ҥ¹ԤǤ褦ˤʤ뤳ȤǤ
ΤˡRSpec ϿѤ DSL ͡ʥƥȴϢ饤֥եġȤϢȤѶŪ˹ԤƥƥĶפȤʤ뤳ȤܻؤƤޤ
ơ֤ĹʤäƤޤޤºݤ RSpec ȡ뤷ƻȤäƤߤޤ礦
RSpec δñʻȤ
ȡ
RSpec ΥС RubyGems Ƥޤrubygems ޤ ȡ뤷Ƥʤ RubyGems Υޥ˥奢 ʤɤͤˤƥȡ뤷ƤƤʲΥޥɤǺǿǤ Rspec gem ѥåȤƥȡǤޤ
$ gem install rspec
RSpec ̵˥ȡ뤵ơ¹ԤǤ뤳Ȥǧޤ礦
$ spec -v RSpec-1.0.8 (r2338) - BDD for Ruby http://rspec.rubyforge.org/
ޤСֹ椬ɽʤϡȡ˼ԤƤ뤫 $GEM_HOME/bin ˥ѥ̤äƤʤȤͤޤ
spec ޥɤRSpec μ¹ԤδܥޥɤǤ
Ūʼ¹ˡ
ǤϡRSpec ¹ԤƤߤޤspec ޥɤΰȤƿڥåեͿ RSpec ¹ԤǤޤ
ǽˤϡƬǾҲ𤷤Ȥ߹ߥ饹 Array Ф뿶 Ѥޤ礦ŪʿεˡϡɡƤޤ
ޤϡºݤưƤߤ RSpec ʷϵϤǤ
ڥåեѰ
Ŭʥǥ쥯ȥ array_spec.rb Ȥ̾ΥեѰդޤ RSpec ˤƥȥɤΥե̾ (ΤȤ) _spec Ȥ ΤŪǤʤϢܤǤ RSpec ǿҤեΤȤ ڥåեȸƤӤޤ
ڥåեˤϡΤ褦˥ڥåޤϢܤǤϡڥ եȤΤȤڥåȸƤӤޤ
array_spec.rb
describe Array, "when empty" do
before do
@empty_array = []
end
it "should be empty" do
@empty_array.should be_empty
end
it "should size 0" do
@empty_array.size.should == 0
end
after do
@empty_array = nil
end
end
RSpec μ¹
spec ޥɤˡۤɺ array_spec.rb ȤϤȤ RSpec ¹ԤǤޤ
$ spec array_spec.rb .. Finished in 0.047857 seconds 2 examples, 0 failures
Test::Unit Ȥ褯Ǽ¹Է̤ϤޤTest::Unit Ʊ͡ ɥå (.) οϥƥȤ example οƤޤexample Ȥ϶ Ūˤ it åɤθƤӽФοǤ
嵭νϤϡ2 Ĥ example ¹Ԥ졢failure () 0 Ǥ𤷤 ޤĤޤꡢƥȤȤȤǤ
spec ޥɤˤ͡ʼ¹ԥץѰդƤޤ ǤϡŪˤ褯Ȥץ 2 ĤҲ𤷤ޤ
- ¹Է̤˿Ť
- specdoc եޥåȤǤμ¹
ʲǽ֤Ƥޤ¾ˤ⤿ spec ޥɤμ¹ԥץξܺ٤ϡ$ spec --helpפ ȤΥɥ ȤƤɬפ˱ơϢܤǤ¾ΥץͽǤ
¹Է̤˿Ť
RSpec ϡ¹Է̤οŤɸǥݡȤƤޤRSpec ʤ饿ߥʥǤΥСɽ뤳ȤǤޤʤΤΥץ-c (--color, --colour) ץǤ
Windows ĶǤϡ--color ץѤ뤿ˤϡ win32console gem ѥåɬפǤ
$ gem install win32console
ġĤǤϡºݤ˼¹ԤƤߤޤ礦
٤ƤΥƥȼ¹ԤΤǡФˤʤäƤޤƥȤ˼ԤСɽ֤ʤޤ虜Ȥ餷ǻƤߤޤ礦ۤɤ array_spec.rb ˡɲäޤ
array_spec.rb
...
describe Array, "when initialized with object" do
before do
@array = Array.new(3, Hash.new) # ϴ㤤
@array[0][:cat] = "Nuko"
end
it "should not affect others" do
@array.should == [{:cat => "Nuko"}, {}, {}]
end
end
¹ԤƤߤޤ
ͽ̤꼺Ԥޤ'F' example μ¹Ԥ˼ԤȤƤޤ'F' Test::Unit ƱFailure ()פƬʸǤ
顼åɤ
顼åϤ줿ĤǤˡƥȤμ¹Ԥ˼ԤΥ顼 åɤˤĤƴñƤޤ礦
1: 1)
2: 'Array when initialized with object should not affect others' FAILED
3: expected: [{:cat=>"Nuko"}, {}, {}],
4: got: [{:cat=>"Nuko"}, {:cat=>"Nuko"}, {:cat=>"Nuko"}] (using ==)
5: ./array_spec.rb:26:
- 1: ܤμԤɽ (Ǥ 1 )
- 2: describe åɤ it åɤΰ鼫ưŪ줿å
- 3: example Ǥ [{:cat => "Nuko"], {}, {}] Ȥ Hash Ԥ (expected) Τˡ
- 4: 줿 (got) [{:cat => "Nuko"}, {:cat => "Nuko"}, {:cat => "Nuko"}] Ȥäusing Ϸ̤Ӥ˻ȤäåɤǤ (Ǥ ==)
- 5: ¹Ԥ˼ԤԿ (Ǥ 26 )
2 ܤμư줿å RSpec ʤǤϤεǽǤåϡ describe åɤ it åɤϤ饹ʸѤƺ ƤޤڥåˤϡμԥåԤ ȤƤɽ褦˹ΤĤǤŪʥĤˤĤƤŬ ڤƤޤ
μԤڥå֤ޤޡΥץޤ
specdoc եޥåȤǤμ¹
specdoc ȤϡΥ顼åǤѤƤdescribe åɤ it åɤΰѤơ RSpec μ¹Էֻ̤ͽפ˽ϤΤǤ¹ԥץϡ--format specdoc (-fs) Ǥ
μԤ֤Τޤ array_spec.rb ¹ԤƤߤޤ礦:
spec -fs array_spec.rb
Array when empty
- should be empty
- should size 0
Array when initialized with object
- should not affect others (FAILED - 1)
1)
'Array when initialized with object should not affect others' FAILED
expected: [{:cat=>"Nuko"}, {}, {}],
got: [{:cat=>"Nuko"}, {:cat=>"Nuko"}, {:cat=>"Nuko"}] (using ==)
./array_spec.rb:26:
Finished in 0.009107 seconds
3 examples, 1 failure
example Τ줾ʸǥȤ줿վΤ褦ˤʤäƽϤޤ -c ץȤ߹碌뤳ȤǤޤ¹ԤƤߤޤ礦
Ԥ example ɽ֤ʤꡢ顼åɽޤ
ΤޤޤǤ褯ʤΤǡ̤ư褦˽ޤ礦
array_spec.rb
...
describe Array, "when initialized with object" do
before do
@array = Array.new(3){ Hash.new } # 줬
@array[0][:cat] = "Nuko"
end
it "should not affect others" do
@array.should == [{:cat => "Nuko"}, {}, {}]
end
end
¹Ԥޤ
٤ƥˤʤޤФβ̤夭ޤ͡
spec եʸܸȤ
ޤǤǤϡdescribe it Ϥʸ˱ѸȤäƤޤ åʸɬѸǤɬפϤޤ ȤСΤ褦ܸȤäƤޤ
array_spec_ja.rb
describe Array, "ξ:" do
before do
@empty_array = []
end
it "#empty? true Ǥ뤳" do
@empty_array.should be_empty
end
it "#size 0 Ǥ뤳" do
@empty_array.size.should == 0
end
after do
@empty_array = nil
end
end
it ȤηҤ꤬줷ǤܸȤǤʤʤǤ ˼¹ԤƤߤޤ礦
ΤǤСܸƤޤäƤ褤Ȼפޤ åܸȤự̤褦˹פɬפ ޤ
ڥåܸǵҤ뤿ιפˤĤƤϡ֥ʥޥפΡRSpec ܸ˻ͤäݤˤפͤˤʤޤ
ڥåեι¤
ޤǡڥåեι¤ˤĤƤƤޤǤǤޤȤޤ
˽Ҥ٤褦ˡRSpec ¸褦ȤƤ뤳Ȥ Test::Unit ǤƱͤ˼¸ǽǤ Test::Unit ȥڥåեȤ礭ʰ㤤ϡTest::Unit::TestCase Υ֥饹Ȥ ΤФڥåեϡRSpec API Ѥ Ruby ץȤȤƵҤ뤳ȤǤ
ڥåեˤϥץο (Behaviour) ҤޤȤ϶ Ūˤϡdescribe do ... endפȤΥ֥åդåɸƤӽФ Ǥ1 ĤΥڥåեˤʣοҤǤޤѤ СŪʤޤȤޤ꤬ڥåեǤ롢Ȥ⤤Ǥ礦
֥ڥåեι¤פȤƾҲ𤹤ƤñʿޤˤޤȤƤ ڥåե뤽줾ǤŪʴطȻפäį Ƥ
ޤλǡ٤ƤɬפϤޤɤäƤ줫 ΤȤͤˤƤʲҤ̤ɤȤ˺ įƤߤΤ褤⤷ޤ
ڥåե̿̾
ڥåե̿̾ˤϡƥȥɤФˤʤץȥɤΥ 饹⥸塼̾Ȥ뤳Ȥ¿Ǥ (array_spec.rb ⤽ ʤäƤޤ)1 ĤΥ饹 (⥸塼) Фɬ 1 ĤΥڥåե Ȥ롼ޤ
ŪʤޤȤޤɽΤŬڤ spec ե֤̾ 褤Ǥ礦
ȤСRspec Τ˴ޤޤƤ ProgressBarFormatter 饹 spec ϡΤ褦 3 Ĥʬ䤵Ƥޤ
- progress_bar_formatter_dry_run_spec.rb
- progress_bar_formatter_failure_dump_spec.rb
- progress_bar_formatter_spec.rb
ޤڥåե Ruby ץȤǤ顢εҤɬפʥإѥ åɡ饹⥸塼̾ Ruby ץȤƱ͡ͳǤޤ ̤νޤȤꡢ뤿ѶŪѤȤ褤Ǥ礦
(Behaviour)
ϡTest::Unit ˤե (ƥȥ饹) Τǡ֤륳 ƥȤˤץμ¹Բǽʥץ (example) Ūʤޤ ޤפǤexample ˤĤƤϸۤޤ
ۤɤμ¹ǻѤarray_spec.rb ƷǤޤ
array_spec.rb
describe Array, "when empty" do
before do
@empty_array = []
end
it "should be empty" do
@empty_array.should be_empty
end
it "should size 0" do
@empty_array.size.should == 0
end
after do
@empty_array = nil
end
end
describe åɤθƤӽФȤƵҤޤ
describe å
ϡdescribe åɤθƤӽФȤƵҤޤarray_spec.rb Ǽ Ƥ褦ˡ1 Ĥοˤʣ example ޤ뤳ȤǤޤ
describe åɤΰˤϤοʸ䥯饹 ꤷޤνˤढޤ
1 Ĥϡ array_spec.rb ѤƤֿҤоݤȤʤ륯饹ȡ ƥȤʸפꤹΤǤΤ褦ʽǤ
describe Array, "when empty" do ...
Array Ҥ饹"when empty"ƥȤʸǤ
⤦ 1 ĤνϡʸꤹˡǤΤ褦ʽǤ
describe "An empty array" do ...
ޤdescribe åɤˤϡHash ˤ륪ץϤȤǤޤ ץζŪʻˡϡϾάޤϢܤǵ ޤ
¹Բǽʥץ (example)
¹Բǽʥץ (example) ϡTest::Unit ˤƥȥåɤ Τǡdescribe åɤΥ֥å˵Ҥޤ
example ȤϡŪˤϡit "should ..." do ... endפηǤΥ֥å դåɸƤӽФǤexample ˤϡ֥ڥơ (expectation)פҤޤ
ڥơȤϡ֥ץ˴Ԥưư̡פΤȤ Ūˤϡ"it" ³֥åǡshould be_emptyפȤäǵ ҤƤʬڥơǤڥơˤĤƤϸޤ äƤϡTest::Unit assert_XXX RSpec ǡ٤˹ͤƤƤ
example ˤϥڥơʳˤ⡢˱ơƥȤɬԤåɤ䡢Ū˥ڥơɾαåɤѤǤޤ üʥڥơˤĤƤ⡢ޤ
it å
it åɤϡڥơʸȡڥơ Ҥ֥å˼ޤڥơˤĤƤϤ θޤ
array_spec.rb Ǥ:
describe Array, "when empty" do
...
it "should be empty" do
@empty_array.should be_empty
end
...
end
it "should be empty" do...endפʬ 1 Ĥ example Ǥڥơ ʸϡ"should ..."ǻϤޤѸǤ뤳ȤԤ ƤޤϡRuby ɤץޤˡit should be emptyפ ɤǤ餦Ǥ줬itפʤɤȤͤä褦ʥå̾ѤƤͳǤ
ʤߤˡΡitפؤƤϡdescribe ΰ˽줿Ǥ Ǥϡ Array it λؤƤΤǤʤߤˡ itץåɤϤĤƤϡspecifyפȤäȲ̾Ǥ
RSpec ȯλǤˤ!פȤ櫓ǤϤޤǤ顢
it "#empty? true Ǥ뤳" do...
ܸǽƤ RSpec ¹ԤǤꤢޤܸǽ "it" ̣ǤɤƤⵤפȻפϡ ߴΤ˻ĤƤ API ȤȤǤޤ
specify "#empty? true Ǥ뤳" do ...
ϢܤǤϳڤä "it" ȤȤˤޤ
before / after å
ˤϡexample / Ҥ뤿ΥեåȤ before ɤ after åɤѰդƤޤbefore åɤ after åɤϤ 줾졢Test::Unit ˤ setup åɤ teardown åɤޤ
before/after Ϥ줾졢ǥեȤǤϳ example ¹Ԥ뤿Ӥ˸ƤӽФ ޤ (Test::Unit ƱưǤ)
before/after 1 ٤¹Ԥ
before/after Υ٥ 1 ٤¹Ԥ礬ޤȤС ǡ١³ dRuby ץεưȤä˳ޤ
Τ褦ʾϡbefore/after åɤΰ˥ܥ:allפϤޤ RSpec ΥȤ˻ȤƤ Ѥޤ:
describe "ο" do
before(:all) do
# ٥ǰ٤¹Ԥ
end
before(:each) do
# exampleˤĤƤ
end
before do
# Ϥʤϡ:eachϤΤƱ
end
it "should do stuff" do
...
end
it "should do more stuff" do
...
end
after(:each) do
# exampleˤĤƤθ
end
after do
# Ϥʤϡ:eachϤΤƱ
end
after(:all) do
# ٥ǰ٤¹Ԥ
end
end
Υڥå¹Ԥϡʲν֤˥åɤƤӽФޤ:
- before(:all)
- before(:each)
- before
- it "should do stuff"
- after
- after(:each)
- before(:each)
- before
- it "should do more stuff"
- after
- after(:each)
- after(:all)
before/after ˰Ϥʤäεưϡ:eachפϤƱǤ
ޤbefore/after ϡ:each :all Τ褦˼¹ñ̤ۤʤϤǤ Ʊ¹ñ̤ǤäƤʣҤ뤳ȤǤޤ
ǤСbefore(:each)פȡbeforeפ 2 սƤޤ ΤȤbefore ξȤƤӽФޤΤȤμ¹Խϡbefore ϸƤӽФ˽ޤ
after ˤĤƤƱͤǤ¹Խ before ȤϰۤʤꡢƤӽФ սǸƤӽФޤ
ڥơ (expectation)
ڥơ (expectation) Ȥϡexample Υ֥å˵Ҥ 롢֥ץ˴Ԥưư̡פΤȤǤŪˤϡ ڥơϿ륪֥ȤФåɸƤӽФ ȤƵҤޤ
ڥơҤ뤿ˡRSpec Object ĥƼ 2 Ĥ åɤƤޤ
- Object#should(matcher=nil)
- Object#should_not(matcher=nil)
Object#should ϡ쥷Фޥå (matcher) ǵҤ δ (expectation) 뤿˻Ѥޤshould_not ϤεդǤ ʤ쥷Фޥå (matcher) ξʤȤδ 뤿˻Ѥޤڥơ̤Ǥʤä 硢Spec::Expectations::ExpectationNotMetError 㳰Фޤ
should/should_not åɤ˥ޥåꤷơץοؤδ Ԥ路ΤڥơǤڥơ Test::Unit ˤ assert_XXX åɤޤ
ޥåˤĤƤϸҤȤơʲ should/should_not ȥޥåȤ߹ 碌Ĥޤ
result.should == 37
false.should_not be_nil
['A','B','C'].should_not include('D')
lambda { [1,2,3] + 4 }.should raise_error(TypeError)
should/should_not ϡObject ФĥʤΤǡClass ޤ륪 ֥ȤѤǤޤ
˽ˤޤȤȡRSpec ˤ륨ڥơεҤϡ
actual.should matcher(expected) actual.should_not matcher(expected)
ܤǤǡִܤǤפâƤΤϡޥåΤʤ ˤϡexpected ˲äŪʰϤΤ䡢åɥΤ¸ߤ뤫Ǥ
Test::Unit assert_XXX ȤϰۤʤꡢڥơΤΤˤϥ å (Ȥ˼Ԥɽå) ¸ߤ ޤRSpec Ǥϡexample ʸ Test::Unit Υå ޤ
ڥơˤĤƤξܺ٤ (ѸǤ) Spec::Expectations RDoc ȤƤ
ޥå (matcher)
ڥơޥåϡ͡ʼΤΤɸѰ ƤޤŪϡSpec::Matchers RDoc ȤƤ ϱѸǤȶ˼ƤΤǡRuby ΥɤɤǤȻפޤ
ޤTest::Unit Ȥб Test::Unit Cheat Sheet ȤƤޤȤƤΤǡ⻲ͤˤƤ
Ǥϡshould 뤤 shuuld_not Υ쥷Ф actual Ȥơ ɤΤ褦ʥޥå㤬ѰդƤ뤫ñ˾Ҳ𤷤ޤ
黻ҥޥå
RSpec Ǥϡα黻ҤޥåȤѤǤޤ
- <
- <=
- ==
- ===
- =~
- >
- >=
٤ƤˤĤƤǤϤޤñƤޤʷϵϤǤ:
(1 + 1).should == 2 10.should < 11 "apple".should_not =~ /orange/
ʤ!=פ!~פȤä黻ҤݡȤƤޤ ֡ǤϤʤȡפҤϡactual.should_not == valפηѤƤ
ӥȥΥޥå
黻Ұʳˤ⡢餫 RSpec ѰդƤޥå㤬ޤ ϡѰդƤޥåΰȴñˤȤɤޤ֤ ˤʤޤŪʻȤ Spec::Matchers RDoc Ūʥɥ ȤˤʤäƤޤʻ (ȤѶŪ) ͤˤƤ
- be_close(expected, delta)
- Test::Unit assert_in_delta ƱǤ(actual - expected).abs < deltaפΩ뤳ȤԤޤ
- change
- actual Proc ǤѤǤޤchange ΰȤäơԤ륪֥Ⱦ֤ѲҤޤۤޤRDocεҤ⻲ȤƤ
- eql(expected)
- actual expected ƱͤǤ뤳ȤԤޤƱ (object_id Ʊ) ǤɬפϤޤObject#eql? ȤäӤޤ
- equal(expected)
- actual expected Ʊ (object_id Ʊ) Ǥ뤳ȤԤޤObject#equal? ȤäӤޤ
- have(number).items
- actual.items 쥯 (size length ˱Ǥ) Ǥˡǿ number Ǥ뤳ȤԤޤ
- have_at_least(number).items
- have() ƱǤǿӤ actual.items >= number Ѥޤshould_not have_at_least() ϥݡȤƤޤ
- have_at_most(number).items
- have() ƱǤǿӤ actual.items <= number Ѥޤshould_not have_at_most() ϥݡȤƤޤ
- have_exactly
- have() alias Ǥ
- include(expected)
- actual String Array Ǥˡactual.include?(expected) Ԥޤ
- match(regexp)
- actial =~ regexp Ǥ뤳ȤԤޤ
- raise_error(expected)
- actual Proc ǤˡProc Ǽ¹Ԥ³㳰ȯ뤳ȤԤޤexpected ˤϡ 1 㳰饹 2 ˤϥץȤơ㳰˴ޤޤåʸޤ㳰Υåʸ˥ޥåɽǤޤܤ RDoc ΥץȤƤ
- respond_to(*names)
- actual.respond_to?(name) Ω뤳ȤԤޤnames ˤ String ޤ Symbol Ǥޤ
- satisfy{}
- actual satisfy ΰȤͿ줿 Proc ȤԤޤ֥åˤ actual Ϥޤ㤨С(2 + 3).should satisfy {|n| n > 4}פǤ
- throw_symbol(:expected=nil)
- actual Proc ǤˡProc Ǽ¹Ԥ³ expeced ǻꤵ줿 Symbol throw 뤳ȤԤޤexpected ꤷʤϡ餫 Symbol throw 뤳ȤԤޤ
be_XXX(expected) Υޥå
array_spec.rb ǽФƤ@empty_array.should be_emptyפ褦ʥޥåˤĤƴñƤޤ be_XXX ȤΥޥåϡRSpec ¹ԻˡXXXפʬXXX?פȤ䤤碌åɤȲᤷƼ¹ԤޤĤޤꡢ
@empty_array.should be_empty
ϡ
@empty_array.empty?
true ˤʤ뤳ȤԤƤޤ¾ˤȡbe_nilפϡnil?סbe_instance_ofפ instance_of?פȲᤷƼ¹ԤޤŪʥڥơȤƤϼΤ褦ˤʤޤ
"a string".should be_an_instance_of(String) => "a string".instance_of?(String) 3.should be_a_kind_of(Numeric) => 3.kind_of?(Numeric) 3.should_not be_an_instance_of(String) => 3.instance_of?(String)
be_XXXסbe_a_XXXסbe_an_XXXפϤƱΤǤXXX ȷҤ ݤ (ѸȤ) ʵҤˤʤΤ٤Ф褤Ǥ礦ޤ 狼褦ˡbe_XXXΥޥåˤϴͤȤϤޤ
be_XXX ΥޥåϡRSpec RDocǤϡPredicateפȤƤޤ
be_true be_false
ͤȽϤ褯ѤΤǡRSpec true false Ƚ̰ƤޤΤ:
- be_true
- be_false
2 ĤΥޥåϡactual true? åɤ false? åɤäƤʤƤ ѤǤޤ
have_XXX(expected) Υޥå
RSpec ϡbe_XXXΥޥåƱ褦ʻȤߤǡhave_XXXפȤΥޥ Ƥޤhave_XXXץޥåϡRSpec μ¹Իˤ has_XXX?ץåɤθƤӽФȤƲᤵޤϡshould ¤ Ȥλ̤ (ѸȤ) ʵҤ뤿֤Ǥ
Hash#has_key? оݤˤ㤬RSpecRDoc ˺ܤäƤΤǰѤޤ
{:a => "A"}.should have_key(:a) => {:a => "A"}.has_key?(:a) #
{:a => "A"}.should have_key(:b) => {:a => "A"}.has_key?(:b) #
桼ȼޥå
桼ȼ˥ޥåơRSpec ȥ쥹礵뤳 ȤǤޤ桼ȼޥåޥåȸƤӤޤ ޥåˡϡʹߤϢܤǸڤޤ
ޤԤڤʤϡRSpec ΥȤˤ RDoc ʤɤͤ˼ȤǤߤƤ ΥåɤĤ饹ơäȤ ʤΤǡۤʤȻפޤ
üʥڥơ
ޤǤ̾ΥڥơȤϾۤʤäŪѤüʥڥơ2ľҲ𤷤ޤ
violated(message=nil) å
violated åɤ example ֥åǻѤǤåɤǤƥȤμ¹ ˾˼ԤޤTest::Unit ǡȤƥȤޤǤδ֥ƥȤԤ뤿˻ȤTest::Unit::Assertions#flunk(message="Flunked") ƱŪΤѰդƤޤ
describe "violated" do
it "should fail" do
violated "always fail!" # ɬ¹Ԥ˼Ԥ
end
end
Test::Unit Ǥ flunk åɤȤƥȤޤǤδ֡ƥ ԤŪʤɤ˻ȤޤRSpec ˤϥƥȤαƤפ տޤɽǤȤߤѰդƤޤΤ褦Ӥˤϡ violated åɤǤϤʤ Pending ȤȤߤȤޤ
example α (pending)
RSpec ϡֻͤϷɥƥȤϤޤƤʤס֥ƥȤμ¹Ԥ ŪαƤפȤäƥȤαƤ (Pending) Ȥ ޤΰտޤٱ礹ȤߤƤޤ
example pending ˤ硢¹ԥݡȤǤ pending failure () Ȥ ̤ɽޤ
ֻͤϷɥƥȤϤޤƤʤ(Not Yet Implemented)
it åɤ˥֥åͿʤä硢 example pending ˤʤޤ
it "should do something" # ֥åͿƤʤ
pending(message){||...}åɤȤä example ɾα
pending ϡ֥ƥȤμ¹ԤŪαƤפȤտޤɽ뤿˻Ȥ message ˤαƤͳʸϤƤΥѥɬܤǤ
it "pending() with message" do
pending("some reason")
true.should be_true # ɾоݤȤʤʤ
end
exampleΤʬɾоݤ鳰ϡ֥åȤޤ pendingåɤ˥֥åϤޤ
it "pending() with block." do
(1 + 1).should == 2
pending("for obvious reason") do
true.should be_false # αɾ
end
nil.should_not be_true
end
֥åɾ̡㳰ȯƤ⤽ pending Ȥưޤ
pending Ϳ֥å㳰Фʤä ϡpending ֥å Spec::Expectations::ExpectationNotMetError 㳰 ޤĤޤꡢ¹Է̤ pending Ǥʤ failure ˤʤޤ
ExpectationNotMetError ϡpending ֥åФԤΩʤäȤɽƤޤ ּ¹Ԥ˼Ԥ㤦ɡޤϤɤȤ뤳ȡפԤ pending ȤäƤˤ⤫餺pending ֥å㳰ȯƤʤ (=¹ԤƤޤä) ΤԤ ȿ롽äơExpectationNotMetError Ф롢ȤˤʤäƤޤ
üʥڥơ¹ԤƤߤ
ޤǤ˾Ҳ𤷤 pending ڥåեˤޤȤȼΤ褦ˤʤޤ
pending_spec.rb
describe "Pending Examples" do
it "should do something" # ֥åͿƤʤ
it "pending() with message" do
pending("some reason")
true.should be_true # ɾоݤȤʤʤ
end
it "pending() with block" do
(1 + 1).should == 2
pending("for obvious reason.") do
true.should be_false # αɾ
end
nil.should_not be_true
end
end
¹Է
¹ԤƤߤޤ礦
'P' Pending P Ǥ1 (it "should do something") ϡNot Yet Implemented (̤)פȤƥݡȤ졢 2 Ĥ Pending 줿Ȥ ͳʸȤȤ˥ݡȤƤ뤳ȤǧǤޤ
-c ץꤷƤΤǡ'P' ϲǿŤޤ
ޤǤΤޤȤ
RSpec δܤ(Ǥ) ޤƤʤս ¿ΤǡϼʹߤŬäƤȻפޤ֤狼ˤ 衪ס֤äȤ路פȤäեɥХå紿ޤǤ Ϣ륢ɥ쥹ϡRubiMa-rspec at quickml.atdot.net Ǥ
ʹߤǤϡRuby ȤäץꥱȯǶŪˤɤäƻȤäƤΤ ߤ繥 Ruby on Rails ˤ Web ץꥱȻפޤ
RSpec on Rails
RSpec on Rails ϡRSpec Rails ǻȤ Rails ץ饰ǤRSpec on Rails ȤȤǡRails ɸ Test::Unit ١ΥƥƥĶ ä (뤤ϡȤ߹碌)RSpec ѤǤޤ
RSpec on Rails Rails Ǥ RSpec Ѥٱ礹뤿ˡƥѤΥꥯ / 쥹ݥRails òޥå㡢ӥ塼إѤΥƥȤٱ礹 ȤߡRSpec ¹Ԥ뤿 Rake ʤɤƤޤ
ϢܤǤϤʹߡ(餯) δ֡RSpec on Rails Ȥä Rails ץꥱΥץߥοʤ̤ơRSpec λȤȡRSpec on Rails εǽҲ𤷤Ƥޤ
ϡñʥ֥ץꥱǤץߥοʤ TDD Ԥޤ륢ץꥱϡʹߤϢܤǤѤޤ
ǤϡRspec on Rails ȡ뤷ơRuby on Rails ˤ Web ץꥱ Rspec ǥƥȤʤäƤޤ礦
Rails ץȤκ
ʤˤϤȤ⤢졢Rails ץȤޤϢܤǤϥǡ١ SQLite3 Ѥ ޤMySQL PostgreSQL ʤɡ¾ RDBMS Ȥϡǡ١ ʤɤŬɤؤƤ
ǤϡRails ץꥱޤ
$ rails -d sqlite3 myblog ...(ά) $ cd myblog
RSpec on Rails Υȡ
RSpec ץȤΥǤϡ RSpec on Rails ȡ뤹ݤˤϡRSpec Τ Rails ץ饰Ȥƥ ȡ뤹뤳Ȥ侩Ƥޤ
ȤΤ⡢RSpec on Rails ϡѲǽ RSpec ΥСå ꤷƤСǤϤʤ硢ƥȤ¹Ԥޤ Rspec on Rails ֤Ǥưΰ㤤ˤԶ뤿Ǥ
RSpec ץ饰Ȥƥȡ뤹뤳ȤǡRSpec RSpec on Rails Сȯоݤ Rails ץꥱǸǤޤ
RSpec on Rails ϡ¹Իˤϡgem ѥåǥȡ뤵Ƥ RSpec ⡢ץ饰Ȥƥȡ뤵줿 RSpec ͥ褷ƻѤ Τǡgem ѥå RSpec ȯоݤ Rails ץꥱ ȤΩƥСåפǤޤ
ϢܤǤ RSpec RSpec on Rails ξ Rails ץ饰Ȥƥȡ 뤷ޤ
# RSpecΤץ饰Ȥƥȡ뤹 $ ruby script/plugin install http://rubyforge.org/var/svn/rspec/tags/REL_1_0_8/rspec # RSpec on Railsȡ뤹 $ ruby script/plugin install http://rubyforge.org/var/svn/rspec/tags/REL_1_0_8/rspec_on_rails
RSpec on Rails ѥե
RSpec on Rails ( Rspec) ץ饰Υȡ뤬ƤС script/generate ޥɤ rspec ѤΥͥ졼Ȥ褦ˤʤäƤϤǤ
script/generate ȤäơRSpec on Rails ɬפʥեޤ
$ ruby script/generate rspec create spec create spec/spec_helper.rb create spec/spec.opts create previous_failures.txt create script/spec_server create script/spec
եȥǥ쥯ȥñƤޤ
- spec/
- ڥåե֤롼ȥǥ쥯ȥǤRails ɸΥƥƥĶ test/ ǥ쥯ȥޤ
- spec/spec_helper.rb
- RSpec Rails ǻѤ뤿ΥإѤǤץꥱ˶̤ RSpec ϢνҤޤRails ɸΥƥƥĶ test/test_helper.rb ޤ
- sepc/spec.opts
- Rake ͳ RSpec ¹Ԥݤˡspec ޥɤϤץꤷޤ
- script/spec_server
- Rails ĶɤƥѤ dRuby ФưޤƥȤμ¹Ԥ®뤳ȤŪǤʹߤϢܤǸڤޤ
- script/spec
- ȯоݤ Rails ץꥱѤ spec ޥɤǤڥåեꤷƼ¹Ԥ˻Ѥޤ
Υե뤬ǤСRSpec on Rails ȤϴλǤ
:RSpec on Rails ǥȡ뤵 rake
RSpec on Rails ȡ뤹ȡRails ɸΥƥƥĶƱ ˡrake ˤ¹Ԥٱ礹뤿ΥɲäޤʲǼפʤ Τñ˾Ҳ𤷤Ƥޤ
| rake spec | spec ǥ쥯ȥʲˤ뤹٤Ƥ spec ¹Ԥޤ |
| rake spec:models | spec/modles ǥ쥯ȥʲˤǥ spec ¹Ԥޤ |
| rake spec:controllers | spec/controllers ǥ쥯ȥʲˤ롢ȥ spec ¹Ԥޤ |
| rake spec:helpers | spec/helpers ǥ쥯ȥʲˤ롢إѡ spec ¹Ԥޤ |
| rake spec:views | spec/views ǥ쥯ȥʲˤ롢ӥ塼 spec ¹Ԥޤ |
| rake spec:db:fixtures:load | spec/fixtures ǥ쥯ȥ fixture ե DB ɤ߹ߤޤɸ db:fixtures:load ƱǽǤ |
| rake spec:doc | Specdoc (spec νϡdescribe it ) Ϥޤ |
| rake spec:plugins | vendor/plugin ʲˤ spec ¹Ԥޤ |
| rake spec:plugin_doc | vendor/plugin ʲˤ spec Specdoc Ϥޤ |
| rake spec:rcov | spec ǥ쥯ȥʲˤ뤹٤Ƥ spec ¹Ԥrcov Ǽ¹Ψ¬ޤ |
| rake spec:clobber_rcov: | rcov νϤޤ |
rake spec Ǽ¹Ԥ spec ޥɤΥץϡspec/spec.opts ǥޥǤޤ
RSpec on Rails Υƥѥǥ쥯ȥ깽
ºݤ RSpec on Rails ȤäƥڥåƤˡRSpec on Rails ΥƥƥĶΥǥ쥯ȥ깽ˤĤƤޤ
Rspec on Rails ΥƥƥĶΥǥ쥯ȥϡRails ɸΤΤ ⡢Rails ƥݡͥȤФ뿶Ȥ ĥʤäƤޤȤСRails ɸΥƥƥĶΥǥ쥯 깽ϼΤ褦ʤΤˤʤäƤޤ:
test/ |-- fixtures/ ......... ƥȥǡ |-- unit/ ............. "˥å"ƥ (Model) |-- functional/ ....... "ǽ"ƥ (Controller + Model) |-- integration/ ...... ""ƥ (routes.rb + Controller + Model) |-- mocks/ ...... ƥѤ"" | |-- development/ RAILS_ENV ˥֥ǥ쥯ȥ꤬ѰդƤ | +-- test/ +-- test_helper.rb ... ƥΤѤإ
üŪ˸äơƥȶưȯԤǤλǤϡRails Υƥƥ ǤѸλȤϤޤunit/functional/integration Ȥۣ ϡ줾ˤɤޤǽФ褤ΤἡǤå (mock) ȤդλȤ⺮θǤ
Rails test/mocks ǥ쥯ȥϡȯƥȻˡƥ䥵ӥʤɤθƤӽФȯѤΥ֥Ȥ˺ؤȤߤƤޤRails Ƥ뤳Υåεǽϡ֤ȸƤ֤ۤդ路Ǥå䥹֤ΰ㤤ˤĤƤ Test Double (ƥȱ) Mocks Aren't Stubs(Ǥ) ȤƤ
RSpec Ǥ Rails ɸΥǥ쥯ȥ깽ȤϰۤʤäƤޤλʲ˼ޤ:
spec/ |-- fixtures/ ..... ƥȥǡ |-- models/ ..... Model Υڥåե |-- controllers/ ..... Controller Υڥåե |-- helpers/ ..... helper Υڥåե |-- views/ ........... View Υڥåե | +-- (app/views Υ֥ǥ쥯ȥƱ¤ʲ) | |-- edit.rhtml_spec.rb | |-- index.rhtml_spec.rb | |-- new.rhtml_spec.rb | +-- show.rhtml_spec.rb |-- spec.opts ..... Rake Ѥ륪ץ |-- spec_helper.rb ... RSpec ΤѤإ
RSpec on Rails Υǥ쥯ȥ깽ϡڥåñ̤ Rails ιǤǤǥ롢ȥ顢ӥ塼ƥإѤΤ줾ФƤǤ뤳ȤƤޤ
ޤRSpec ϥåȥ֤ Test Double (ƥȱ) ʬ˱äƶ̤饤֥ƤޤRSpec Ǥϡå䥹֤ϳƥڥåƻѤΤܤǤå䥹֤λȤˤĤƤϡʹߤϢܤޤޤԤڤʤϡRSpec ΥȤΥɥ 䡢RSpec gem ѥåȰ˥ȡ뤵Ƥ examples ǥ쥯ȥ ($GEM_HOME/gems/rspec-1.0.8/examples) ˤ륵ץͤˤƤ
ʤRSpec on Rails ǤϺΤȤ Rails ɸ integration ƥȤؤȤߤˤѰդƤޤ(ߡ͡ʻԺ³Ƥޤ) ǤϡRails ɸ integration ʻѤΤȻפޤѲСϢܤǥեƤȻפޤ
RSpec on Rails ϰϤŪ
RSpec on Rails Ǥϥǥ롢ȥ顢ӥ塼ƥإѤФƥ ڥåǤޤ٤Τϻ䤿ĥ Τ:-)ϥǥΥڥåĤȤȤޤ
ʤ Rails ץꥱȯ RSpec ŬѤγȯ οʤˤƤޤΤᡢץ륳ɤȤƼ ȤȥץȥɤΤۤȤɤ¼Ūˤ ActiveRecord 餫 Ƥ뵡ǽƥȤƤ褦ʤΤˤʤäƤޤ
֥ץꥱѤ饤֥ե졼ΥƥȤΤפȤ⤤ȻפޤεФ䤿Ω֤ưΤ¤ˤʤäȤΤǤХФݤˤ⡢ΥХƸ뤿ΥƥȤɲäޤ
֥ץꥱΥǥ
֥ץꥱΥǥϼΤ褦ʤΤȤޤ
+------+ has_many +-------+ | Blog |1 --------------> *| Entry | +------+ belongs_to +-------+
RSpec on Rails 뤳ȤʤΤǡǴۤƤ :-)
ץꥱʣ Blog ݡȤ뤳Ȥˤޤ礦֥ Ƥ뵭ɽΤ Entry Ǥ
Blog ǥκ
ͥ졼 Blog ǥ
ޤ Blog 饹뤳ȤϤޤ礦RSpec on Rails ǥǥˤϡscript/generate Υ֥ޥɤ rspec_model ꤷޤŪʻȤϡmodel ֥ޥɤƱͤǤ
$ script/generate rspec_model Usage: script/generate generate ModelName [field:type, field:type] ...
Ǥϡscript/generate ȤäƤߤޤեɤϤäƤϥ֥̾ɤǤ礦
$ ruby script/generate rspec_model Blog name:string
exists app/models/
create spec/models/
create spec/fixtures/
create app/models/blog.rb
create spec/fixtures/blogs.yml
create spec/models/blog_spec.rb
create db/migrate
create db/migrate/001_create_blogs.rb
test/unit/blog_test.rb ǤϤʤ spec/models/blog_spec.rb test/fixtures/blogs.yml ǤϤʤ spec/fixtures/blogs.yml Ƥޤ
ޥ졼եԽ
̵֥̾ȺΤɬܹܤˤƤޤ礦blogs ơ֥ name ° null ԲĤˤޤ
db/migrate/001_create_blogs.rb
class CreateBlogs < ActiveRecord::Migration
def self.up
create_table :blogs do |t|
t.column :name, :string, :null => false # null ԲĤˤ
end
end
def self.down
drop_table :blogs
end
end
ǡ١
sqlite3 ȥեʤΤǥǡ١νȤϴñǤ
$ rake db:migrate
եԽ
ꤷơñˤǤեԽƤޤ礦 Խоݤ spec/fixtures/blogs.yml Ǥ
spec/fixtures/blogs.yml
kakutani: id: 1 name: ëHTMLײ moro: id: 2 name: moro
Blog ΥХǡΥڥå
äȽλޤǥΥХǡΥڥåޤ礦 ư줿ȡΤ褦ˤʤäƤޤ
spec/models/blog_spec.rb
require File.dirname(__FILE__) + '/../spec_helper'
describe Blog do
before(:each) do
@blog = Blog.new
end
it "should be valid" do
@blog.should be_valid
end
end
ܤ spec_helper ɤ߹Ǥޤspec_helper.rb Rails ĶΥ ɤ䡢app/*ʲΥեǡ١ɤ߹ߤʤɡRails ץꥱΥƥȤɬפʺȤԤäƤޤ
spec_helper ɤ߹ߤϡRspec on Rails ǥƥȤ¹ԤˤɬܤǤ ڥåեʬǺʤɤ˺ʤ褦˵ĤƤ
ǤϡοԽƺǽΥڥåޤ礦
Blog ǥǤ name °ɬܤǤñ Blog.new ֤ name ͤꤵƤޤ顢ActiveRecord::Base#valid? Ω ϤǤäơڥơϡ@blog.should_not be_validפǤ
blog_spec.rb ޤ
spec/models/blog_spec.rb
require File.dirname(__FILE__) + '/../spec_helper'
describe Blog, "#name ꤵƤʤ:" do
before(:each) do
@blog = Blog.new
end
it "Хǡ˼Ԥ뤳" do
@blog.should_not be_valid
end
end
̴ܸ example Ƥߤޤ
spec ¹Ԥޤ˾Ҳ𤷤褦ˡrake ͳ RSpec ¹Ԥ뤳ȤǤޤϢܤǤ script/spec ñΥڥåեꤷƼ¹Ԥ뤳Ȥˤޤ
script/spec ͳǼ¹Ԥϡƥѥǡ١νưǹԤɬפޤ
Ԥޤ
'Blog#name ꤵƤʤ: Хǡ˼Ԥ뤳' FAILED
ܸȤƲǤޤ :-)
expected valid? to return false, got true ./spec/models/blog_spec.rb:9:
9 ܤΥڥơǥХǡ˼Ԥ뤳ȡʤ Blog#valid? false ˤʤ뤳ȤԤΤˡtrue ֤äƤƤޤޤ
ƥȥɤԤ뤳ȤǧǤޤ ΥƥȤ褦˼ޤ礦
Blog 饹˴Ԥ뿶
ƥȤ褦˥ץȥɤޤ
name °¸ߤڤ褦 Blog 饹ޤ
app/models/blog.rb
class Blog < ActiveRecord::Base validates_presence_of :name end
blog.rb ν¸ơ spec ¹Ԥޤǡ١ѹ̵ΤǡΤޤ script/spec ޥɤѤǤޤ
ޤ
äȺŪǤexample ɲäƤߤޤ礦 valid? false ΤȤname °Υ顼ϤꤵƤΤǤ礦
app/model/blog_spec.rb
describe Blog, "#name ꤵƤʤ:" do
...
it ":name ˥顼ꤵƤ뤳" do
@blog.should have(1).errors_on(:name)
end
...
end
ڥơǤϡhave(number).items RSpec ӥȥΥޥåѤƤޤ
@blog.should have(1).errors_on(:name)
ϡ@blog.errors_on(:name)פǿ 1 Ǥ뤳ȡ ʤ @blog name ° 1 Ĥ顼뤳ȤԤƤޤ
̤ǤСActiveRecord ȥ顼ꤷƤƤϤ Ǥ顢ΥƥȤϤǤ
Ǥϡ-fs ץĤƼ¹ԤƤߤޤ礦example ǵҤʸܸȤự̤ΤˤʤäƤ뤳Ȥǧ뤿Ǥ
ActiveRecord ϤȻŻƤƤޤ
Entry ǥκ
Blog Ƥ줿ɽ Entry ǥޤ ͥ졼ѤեޤǤ Blog 饹ξƱͤǤ øȿʤޤ
ͥ졼 Entry ǥ
script/generate ޥɤȤä Entry ǥޤ礦
Entry °ˤϥȥ롢ʸѰդޤBlog ȴϢŤ뤿 γȥ䡢Ѥ°Ȥơॹפޤ
$ ruby script/generate rspec_model entry \
title:string body:text posted_on:date \
created_at:timestamp updated_at:timestamp blog_id:integer
exists app/models/
exists spec/models/
create spec/fixtures/
create app/models/entry.rb
create spec/fixtures/entries.yml
create spec/models/entry_spec.rb
exists db/migrate
create db/migrate/002_create_entries.rb
ޥ졼եԽ
ɬ° null ԲĤˤޤ
db/migrate/002_create_entries.rb
class CreateEntries < ActiveRecord::Migration
def self.up
create_table :entries do |t|
t.column :title, :string, :null => false # Υȥ
t.column :body, :text, :null => false # ʸ
t.column :posted_on, :date #
t.column :created_at, :timestamp # ॿ
t.column :updated_at, :timestamp # ॹ
t.column :blog_id, :integer, :null => false # ȥ
end
end
def self.down
drop_table :entries
end
end
(posted_on) created_at updated_at Ȥä Rails ɸǥݡ 륿ॹפѤΩƤޤ
ϡBlog εפȤưդɬǡ١ ɤκॹפƱȤϸ¤ʤǤ
ǡ١ܹԤ
developmentĶΥǡ١ѹޤ礦
$ rake db:migrate
եԽ
ƥѤƵѰդƤޤ
spec/fixtures/entries.yml
kakutani_earliest: id: 1 blog_id: 1 title: "tDiary ˤƤߤ롣" body: "֤˥ϥѡϥСڥåʤΤФ餯äǤäƤߤ褦Ȼפ" posted_on: 2001-07-06 kakutani_latest: id: 2 blog_id: 1 title: "Re:autotest ߤޤʤ" body: "ⵤĤ AutoTest::Screen Ctrl+C 2 ǻߤޤʤʤޤ..." posted_on: 2007-09-12 moro_rspec_upgrading: id: 3 blog_id: 2 title: "[rspec] RSpec 0.8.x 1.0.x ˤݤΥݥȥ" body: " RSpec Ĺ餯 0.X ³ƤꡢAPI ѹʤƤޤ..." posted_on: 2007-06-24
Entry Blog δϢΥڥå
Ǥϼޤ礦⤦١֥ץꥱ ΥǥǧƤޤ
+------+ has_many +-------+ | Blog |1 --------------> *| Entry | +------+ belongs_to +-------+
ξԤδϢǧƤ:
- Blog ʣ Entry ͭ (Blog has_many Entry)
- Entry Blog ° (Entry belongs_to Blog)
Ȥʤޤ 2 ĤڥåȤƵҤޤ
ä Entry ǥΤǡޤ Entry ¦δϢ饹ڥå ޤ礦
Entry Blog °뤳ȡפڥåȤ
Entry Blog ȤǤȤԤڥåȤƵҤޤ
spec/models/entry_spec.rb
require File.dirname(__FILE__) + '/../spec_helper'
describe Entry do
fixtures :entries, :blogs
before(:each) do
@entry = entries(:kakutani_earliest)
end
it "Υ֥°뤳" do
@entry.blog.should == blogs(:kakutani)
end
end
RSpec on Rails ǤϿҤݤˡRails ɸΥƥƥĶƱ fixtures åɤѤǤޤRspec on Rails fixtures Rails ɸ fixtures Ȥΰ㤤ϡRspec on Rails Ǥϡfixture_pathפ $RAILS_APP/spec/fixturesפꤵƤ뤳ȤǤ
ʤߤˡit "..."פȤ example ʸνϡʥޥפͤˤƤޤ
spec ¹Ԥˡrake db:test:prepare ¹Ԥޤ entries ơ֥ݤˡdevelopment ĶΥǡ١ޤ ѹޤѹޤ test ĶΥǡ١ˤȿǤƤʤ Ǥ
ƥȤ˼Ԥޤ֤ǤϤʤʤΤϡRSpecڥơΩ (ExpectationNotMetError) ȥץߥ顼 (NoMethodError) Ȥ̤뤫Ǥ
ԤåɤȡEntry#blog Ƥʤ褦ǤΤˡʤФϤޤ
Entry belongs_to
δ̤ Entry ޤ礦
app/models/entry.rb
class Entry < ActiveRecord::Base belongs_to :blog end
spec ¹Ԥޤ
٤ޤActiveRecord ΤǤ͡
Blog ʣ Entry ͭƤ뤳ȡפڥåȤ
٤ϡBlog Entry ؤδϢԤ뿶Ȥޤ ֥ʣεͭǤϤǤɲäޤȤäƤ⡢ ActiveRecord ǥݡȤƤ뵡ǽǤ
spec/models/blog_spec.rb
...
describe Blog do
fixtures :blogs, :entries
before do
@blog = blogs(:kakutani)
end
it "ʣεͭǤ뤳" do
@blog.should have_at_least(2).entries
end
end
ʳǥƥȤ¹ԤƤ⼺ԤϤǤ ȤΤ⡢ޤ Blog Entry ؤδϢꤷƤʤǤ
ͽ̤ NoMethodError ȯƼԤޤ
Blog has_many
δԤ˱褦褦 Blog has_many ɲäޤ礦
app/models/blog.rb
class Blog < ActiveRecord::Base validates_presence_of :name has_many :entries end
٤ϥƥȤϤǤ
ͽ̤Ǥ褫ä
Blog Entry ɲäǤ뤳ȡפڥåȤ
Blog Entry has_many ϢǤޤȤȤϡ֥ص ƤǤϤǤĤޤ Blog ¦ Entry ɲäǤϤǤεǽޤ ActiveRecord äƤ櫓Ǥġġ
Ȥ⤢졢οؤδԤȡʤޤ
Blog ˿ Entry ɲäȡEntry η 1 뤳
RSpec example Ȥɽˤϡchange ޥå㤬Ȥޤ
spec/models/blog_spec.rb
...
describe Blog, "˵ƤǤ:" do
fixtures :blogs, :entries
before do
@blog = blogs(:kakutani)
end
it "η1뤳" do
lambda {
@blog.entries.create(
:title => 'new_post', :body => 'hello',
:posted_on => Date.today)
}.should change(Entry, :count).by(1)
end
end
ΥڥơɤϤǤ Blog ˿ Entry ɲä (@blog.entries.create) (lambda ֥å) η̡ Entry η (Entry.count) 1 (.by(1)) ȡס
by åɤɽƤΤϡlambda ֥åɾɾ Entry.count κʬǤ
change ޥåϤʳˤʣνݡȤƤޤchange ޥ Ͻ˴ʤȡǤȤ⤢ȻפޤΤǡǤޤȤ ޤ
change ޥå
change ޥåϡֽη̡פˤ֤ѲؤδԤɽ뤿 ޥåǤֽפɽˤϡ̾ Proc ֥ȤȤޤ( Τˤϡ#call() ˱Ǥ륪֥ȤǤСɬ Proc ǤʤƤޤ) RSpec Ǥϡlambda {...}פȤȤ¿Ǥ
change ޥå㤬ݡȤϰʲΥѥǤ
- proc.should change(receiver, message, &block)
- proc.should change(receiver, message, &block).by(value)
- proc.should change(receiver, message, &block).from(old).to(new)
- proc.should_not change(receiver, message, &block)
change ޥåǤ proc νɾ줿 receiver.send(message) ޤ &block ɾޤ
change ޥåľܸƤӽФΰ change(receiver, message) change(&block) Τɤ餫Ǥreceiver/message ȥ֥åλȤʬΥݥȤϡѲƤ뤳(ޤѲƤʤ)Ԥͤμˡΰ㤤ˤޤ
֥ȤؤΥåѥåǼͤȤˤ receiver/message ηͤΤΤȤˤϥ֥åȤޤ
ʤreceiver/message ȥ֥åξȤꤷϡ֥åɾޤ
åɥ
change ޥåǤͤѹӤåɤǤޤǤåɤμȡ줾ΰ̣ϼ̤Ǥ
- åɥʤ
- receiver.send(message)פɾȤˤѤ뤳Ԥޤ (should_notξѤʤԤޤ)
- by(value)
- receiver.send(message)פɾɾǤͤΰ㤤ؤδԤʬ value ǤȴԤޤ
- from(old).to(new)
- ɾˤ old äreceiver.send(message)פͤɾ new ؤѲƤ뤳Ԥޤ
- to(new)
- ɾͤǤ졢receiver.send(message)פͤɾ new ؤѲƤ뤳Ԥޤ
åɥݤˤϡfromtoν֤ؤƤޤĤޤto(new).from(old)פȤǤޤͤޤǤ RDoc ΥץѤޤѤޤ
lambda {
team.add_player(player)
}.should change(roster, :count)
lambda {
team.add_player(player)
}.should change(roster, :count).by(1)
string = "string"
lambda {
string.reverse
}.should change { string }.from("string").to("gnirts")
# change ޥå ֥åϤˤϡ{} ηϤƤ
# do...endϥݡȤޤ
lambda {
person.happy_birthday
}.should change(person, :age).from(32).to(33)
lambda {
employee.develop_great_new_social_networking_app
}.should change(employee, :title).to("CEO").from("Mail Clerk")
դ⡢ɤۤ狼䤹Ǥ͡
blog_spec.rb¹Ԥ
äᤷơblog_spec.rb ¹ԤƤߤޤ
ʸܸȤΩ뤫ǧΤǡ-fs ץĤƼ¹Ԥޤ
˴Ԥ뿶
ơޤǤ˼Ƥǽϡ¼Ūˤ ActiveRecord Ƥ ΤǤҤȤĤ餤ϼʬãΥץꥱʤǤϤν Ȼפޤ
٤ϵ (Entry#posted_on) ˴Ԥ뿶Ƥߤޤ礦 Ԥ뿶ϼΤ褦ˤȻפޤ:
- Ϥ줺¸줿:
- κˤʤäƤ뤳
- դ¸줿:
- Ϥ줿դˤʤäƤ뤳
ǤС֤ȤǽפȤǤ롢Ũʥ֥ץꥱˤʤꤽǤ
֤˼ȤǤޤ礦
entry_spec.rb ơɲäޤ
spec/models/entry_spec.rb
...
describe Entry, "#posted_on Ϥ줺¸줿:" do
fixtures :blogs
before do
@entry = Entry.new(:blog => blogs(:kakutani),
:title => "ȥ", :body => "ʸ")
@entry.save!
@entry.reload
end
it "Entry κǤ뤳" do
@entry.posted_on.should == Date.today
end
end
ϤƤʤäˤĤƤϡޤƤޤƥȤϼԤϤǤ
쥤ȡԤޤ
ǤϡԤ뿶ޤ
Entry ¸ˡƤ줿դꤹɤǤ
app/models/entry.rb
class Entry < ActiveRecord::Base
belongs_to :blog
def before_save
self.posted_on = Date.today
end
end
before_save åɤ ActiveRecord εǽǡ¸˼ưŪ˸ƤӽФ륳ХååɤǤ ٤ϥƥȤϤǤ
̤ޤ
ʤߤˡΥڥåˤϥХǤޤȤΤ⡢ƥȤ¹ Ƥ뤽νִ֤ˤ礦դѤäˡDate.today ͤ ޤäƥƥȤԤƤޤޤΥХ긷̩ʥƥ Ȥˡϼޤ
³ơ˴Ԥ뿶ɲäޤΤ褦ʻͤǤ
- դ¸줿:
- Ϥ줿դˤʤäƤ뤳
ͤɽ뿶ɲäޤ礦
spec/models/entry_spec.rb
...
describe Entry, "#posted_on ¸줿:" do
fixtures :blogs
before do
@posted_on = Date.today - 10
@entry = Entry.new(:blog => blogs(:kakutani),
:title => "ȥ", :body => "ʸ",
:posted_on => @posted_on)
@entry.save!
@entry.reload
end
it "Ϥ줿դǤ뤳" do
@entry.posted_on.should == @posted_on
end
end
Ǥ before_save ̵Ѥ Date.today ꤷƤޤ
μ¹ԤϼԤϤǤ
ͽ̤μ!! Ф餷Ǥ͡
Entry#before_save Ԥ˱褦褦˽ޤ礦
app/models/entry.rb
class Entry < ActiveRecord::Base
belongs_to :blog
def before_save
self.posted_on ||= Date.today # ||=פȤ褦ˤ
end
end
٤ϤǤ
ޤǤڥåޤȤƼ¹ԤơɤƤʤȤǧƤޤ礦
פǤɤƤޤǤ
ǥΥƥȤ˸¤äƤϤޤޤΤǤϤϿԤޤġġ̤ơRSpec on Rails Ȥä Rails ץꥱȯʷϵƤ館ȴǤ
ԤˤĤ
kakutani.com Ruby β() ¥ƥޥͥ ӥץХǥեץޡJava Ruby ءʥåɤ Object#extend ʥɥϽ鲻ߥ
Rubyist Magazine ĥǡˡRSpec ΤȤƤפȽƤȾǯФäƤޤޤ (⺣Rubyist Magazine ĥǡ٤ξҲ!) ġIJ٤⸶ƤȤƤӤԽγޤˤϤǤޤ(εפȸƤФƤȤΤȤǡġ)줫ϿԤޤ³ȻפäƤޤꤤޤ
Ϥ
moro Rails ٶ@ΰ뷸() ¥ƥޥͥ ӥץХǥ°
žޤĥƤ˸äơ֥졢ƥȽʤͤȤϰ˻ŻǤʤפȸäբΤ TDD RSpec Τޤ衢Rails ٶ@ǤޤƤ⤤ʤΤ RSpec åäꤷƤޤ
ХåʥС
- ϥڥåΥ 1 RSpec γפȡRSpec on Rails (ǥ)
- ϥڥåΥ 2 RSpec on Rails (ȥȥӥ塼)


References:[Rubyist Magazine 0021 ] [ڻǯǰ Rubyist Magazine ؤΤ] [0021 Ƭ] [Rubyist Hotlinks 29 ] [ƹܼ] [ 3 ܤȯɽҲ]