Your SlideShare is downloading. ×
0
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Test::Base
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Test::Base

4,511

Published on

Shibuya.pm tech talk #6

Shibuya.pm tech talk #6

Published in: Technology
1 Comment
1 Like
Statistics
Notes
No Downloads
Views
Total Views
4,511
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
71
Comments
1
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. use Test::Base; Tatsuhiko Miyagawa [email_address] Six Apart, Ltd. / Shibuya Perl Mongers Shibuya.pm Tech Talks #7
  • 2. <ul><li>Test::Base </li></ul><ul><li>とは </li></ul>
  • 3. <ul><li>データドリブン </li></ul><ul><li>テストベースクラス </li></ul>
  • 4. <ul><li>by Ingy döt Net </li></ul>
  • 5. <ul><li>use Test::More? </li></ul>
  • 6. <ul><li>use Test::Base! </li></ul><ul><li>Test::More と互換のあるインターフェース </li></ul>
  • 7. Test::More compatible <ul><li>use Test::More; </li></ul><ul><li>plan tests => 2; </li></ul><ul><li>sub camelize { </li></ul><ul><li>local $_ = shift; </li></ul><ul><li>s/_(w)/uc($1)/eg; </li></ul><ul><li>$_; </li></ul><ul><li>} </li></ul><ul><li>is camelize(&quot;foo_bar&quot;), &quot;fooBar&quot;; </li></ul><ul><li>is camelize(&quot;foo_bar_baz&quot;), &quot;fooBarBaz&quot;; </li></ul>
  • 8. Test::More compatible <ul><li>use Test::Base; </li></ul><ul><li>plan tests => 2; </li></ul><ul><li>sub camelize { </li></ul><ul><li>local $_ = shift; </li></ul><ul><li>s/_(w)/uc($1)/eg; </li></ul><ul><li>$_; </li></ul><ul><li>} </li></ul><ul><li>is camelize(&quot;foo_bar&quot;), &quot;fooBar&quot;; </li></ul><ul><li>is camelize(&quot;foo_bar_baz&quot;), &quot;fooBarBaz&quot;; </li></ul>
  • 9. Test::Base-y code <ul><li>use Test::Base; </li></ul><ul><li>sub camelize { </li></ul><ul><li>local $_ = shift; </li></ul><ul><li>s/_(w)/uc($1)/eg; </li></ul><ul><li>$_; </li></ul><ul><li>} </li></ul><ul><li>filters { input => 'camelize' } </li></ul><ul><li>__DATA__ </li></ul><ul><li>=== </li></ul><ul><li>--- input: foo_bar </li></ul><ul><li>--- expected: fooBar </li></ul><ul><li>=== </li></ul><ul><li>--- input: foo_bar_baz </li></ul><ul><li>--- expected: fooBarBaz </li></ul>
  • 10. Test::Base code <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is 'input' => 'expected'; </li></ul><ul><li>__END__ </li></ul><ul><li>=== Simple JSON Test </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 11. TAP compatible <ul><li>% prove –l 01-json.t </li></ul><ul><li>01-json....ok </li></ul><ul><li>All tests successful. </li></ul><ul><li>Files=1, Tests=1, 0 wallclock secs ( 0.10 cusr + 0.02 csys = 0.12 CPU) </li></ul>
  • 12. use Test::Base <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is 'input' => 'expected'; </li></ul><ul><li>__END__ </li></ul><ul><li>=== Simple JSON Test </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 13. Block names <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is ' input ' => ' expected '; </li></ul><ul><li>__END__ </li></ul><ul><li>=== Simple JSON Test </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 14. Filters <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is 'input' => 'expected'; </li></ul><ul><li>__END__ </li></ul><ul><li>=== Simple JSON Test </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 15. <ul><li>perldoc Test::Base::Filter </li></ul>
  • 16. Define Filters <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is 'input' => 'expected'; </li></ul><ul><li>__END__ </li></ul><ul><li>=== Simple JSON Test </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 17. Filter arguments === filter args --- input lines array tail=2 Join foo Bar baz --- expected chomp regexp=xis bar.*baz
  • 18. filters __DATA__ === test 1 --- input foo bar baz xxx --- expected quox yyy === test 2 --- input foo bar baz xxx --- expected quox yyy === test 3 --- input foo bar baz xxx --- expected quox yyy
  • 19. filters filters { input => [ 'foo', 'bar', 'baz' ], expected => 'quox' }; __DATA__ === test 1 --- input xxx --- expected yyy === test 2 --- input xxx --- expected yyy === test 3 --- input xxx --- expected yyy
  • 20. run_is <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is 'input' => 'expected'; </li></ul><ul><li>__END__ </li></ul><ul><li>=== </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 21. Auto-diff 01-json....NOK 1 # Failed test ' # @@ -1,2 +1,2 @@ # -{&quot;foo&quot;:&quot;bar&quot;} # +{ foo => &quot;bar&quot; } # xxx # ' Requires Algorithm::Diff Turn off with no_diff()
  • 22. <ul><li>run_is </li></ul><ul><li>run_like </li></ul><ul><li>run_unlike </li></ul><ul><li>run_is_deeply </li></ul><ul><li>run_compare </li></ul>
  • 23. run_is default blocks <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is; </li></ul><ul><li>__END__ </li></ul><ul><li>=== </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 24. run_is default blocks <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_is; </li></ul><ul><li>__END__ </li></ul><ul><li>=== </li></ul><ul><li>--- xxx eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- yyy chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul>
  • 25. run_compare <ul><li># 01-json.t </li></ul><ul><li>use Test::Base; </li></ul><ul><li>use JSON::Syck; </li></ul><ul><li>sub json { JSON::Syck::Dump($_[0]) } </li></ul><ul><li>run_compare; </li></ul><ul><li>__END__ </li></ul><ul><li>=== </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => &quot;bar&quot; } </li></ul><ul><li>--- expected chomp </li></ul><ul><li>{&quot;foo&quot;:&quot;bar&quot;} </li></ul><ul><li>=== </li></ul><ul><li>--- input eval json </li></ul><ul><li>{ foo => [ &quot;bar&quot;, &quot;baz&quot; ] } </li></ul><ul><li>--- expected regexp </li></ul><ul><li>bar.*baz </li></ul>
  • 26. run_compare is default! # 01-json.t use Test::Base; use JSON::Syck; sub json { JSON::Syck::Dump($_[0]) } __END__ === --- input eval json { foo => &quot;bar&quot; } --- expected chomp {&quot;foo&quot;:&quot;bar&quot;} === --- input eval json { foo => [ &quot;bar&quot;, &quot;baz&quot; ] } --- expected regexp bar.*baz
  • 27. run # 01-json.t use Test::Base; use JSON::Syck; plan tests => 1 * blocks; run { my $block = shift; is JSON::Syck::Dump($block->input), $block->expected, $block->name; }; __END__ === --- input eval { foo => &quot;bar&quot; } --- expected chomp {&quot;foo&quot;:&quot;bar&quot;}
  • 28. blocks() # 01-json.t use Test::Base; use JSON::Syck; plan tests => 1 * blocks; for my $block (blocks) { is JSON::Syck::Dump($block->input), $block->expected, $block->name; } __END__ === --- input eval { foo => &quot;bar&quot; } --- expected chomp {&quot;foo&quot;:&quot;bar&quot;}
  • 29. Block specific use Test::Base; run_compare; __END__ === --- ONLY --- input eval json { foo => &quot;bar&quot; } --- expected chomp {&quot;foo&quot;:&quot;bar&quot;} === --- input eval json { foo => [ &quot;bar&quot;, &quot;baz&quot; ] } --- expected regexp bar.*baz
  • 30. Block specific use Test::Base; run_compare; __END__ === --- SKIP --- input eval json { foo => &quot;bar&quot; } --- expected chomp {&quot;foo&quot;:&quot;bar&quot;} === --- input eval json { foo => [ &quot;bar&quot;, &quot;baz&quot; ] } --- expected regexp bar.*baz
  • 31. Subclassing Test::Base # t/TestJSON.pm package t::TestJSON; use Test::Base -Base; use JSON::Syck; package t::TestJSON::Filter; use Test::Base::Filter –base; sub json { JSON::Syck::Dump($_[0]) } # t/01-json.t use t::TestJSON; __END__ === --- input eval json { foo => &quot;bar&quot; } --- expected …
  • 32. In your CPAN modules use inc::Module::Install; name 'Foo-Bar'; all_from 'lib/Foo/Bar.pm'; use_test_base; WriteAll;
  • 33. <ul><li>Tips </li></ul>
  • 34. Spiffy XXX XXX $foo = $bar; WWW $bar; YYY $baz; ZZZ $quox;
  • 35. no chomp filters use Test::Base; filters { input => 'chomp', expected => 'chomp' } __END__ === --- input foo --- expected bar === --- input fooaba --- expected bzaahiepa
  • 36. no chomp filters use Test::Base; __END__ === --- input: foo --- expected: bar === --- input: fooaba --- expected: bzaahiepa
  • 37. success tests vs. error tests # t/01-success.t run_is 'input' => 'expected'; # t/02-failure.t run { my $block = shift; eval { … }; run_like $@, $block->expected; } ;
  • 38. Test::Base に向かないテスト <ul><li>複雑な API </li></ul><ul><li>オブジェクト状態が変化 </li></ul>
  • 39. <ul><li>Test::Base で </li></ul><ul><li>うまくテストできない </li></ul><ul><li>= 複雑な API </li></ul>
  • 40. <ul><li>Design your API </li></ul><ul><li>Sufficiently </li></ul><ul><li>Advanced. </li></ul><ul><li>© Damian Conway </li></ul>
  • 41. <ul><li>References </li></ul><ul><li>perldoc Test::Base </li></ul><ul><li>http://search.cpan.org/~miyagawa/?R=D </li></ul>
  • 42. <ul><li>JSAN </li></ul><ul><li>Test.Base.js </li></ul><ul><li>(PMConnect?) </li></ul>
  • 43. <ul><li>Refactoring Example </li></ul><ul><li>http://yapc.kwiki.org/data-driven-testing/slide10.html </li></ul>

×