Slide 1

Slide 1 text

৽࣌୅ͷ ςετϑϨʔϜϫʔΫ 5FTU BLJZN :"1$'VLVPLB)","5"

Slide 2

Slide 2 text

BLJZN

Slide 3

Slide 3 text

ΞδΣϯμ w 1FSMͰςετΛॻ͘ w 5FTUͷ঺հ w 5FTUҠߦͷ஫ҙ఺ w 5FTUͰςετΛॻ͘ w ςετศར৘ใ

Slide 4

Slide 4 text

1FSMͰ ςετΛॻ͘

Slide 5

Slide 5 text

5FTU.PSF JT MJLF JT@EFFQMZ TVCUFTU EPOF@UFTUJOH

Slide 6

Slide 6 text

w JT஋ͷνΣοΫ w MJLFਖ਼نදݱύλʔϯʹϚον͢Δ͔ w JT@EFFQMZσʔλߏ଄ಉ࢜ͷൺֱ w 4,*1 50%0

Slide 7

Slide 7 text

w ಺෦Ͱ͸5FTU#VJMEFSΛར༻ sub ok ($;$) { my( $test, $name ) = @_; my $tb = Test::More->builder; return $tb->ok( $test, $name ); } 5FTU.PSFQN

Slide 8

Slide 8 text

5FTU%FFQ σΟʔϓͳൺֱ

Slide 9

Slide 9 text

w σʔλߏ଄TFU CBH TVQFSIBTIPG w ΦϒδΣΫτͷϝιουͷνΣοΫ w ֦ுੑ͕ߴ͍5FTU%FFQ use Test::Deep; cmp_deeply [[1,3,2], {a => 1, b => 2, c => 3}], [set(1,2,3), superhashof({a => 1})]; ॱෆಉ LFZBͷνΣοΫɺ΄͔͸ແࢹ

Slide 10

Slide 10 text

5FTU'BUBM ྫ֎

Slide 11

Slide 11 text

w ྫ֎͕ൃੜ͍ͨͯ͠͠ͳ͍νΣοΫ w ஥ؒ5FTU&YDFQUJPO use Test::Fatal; like exception { die "fatal" }, qr/fatal/; lives_ok { 'alive' };

Slide 12

Slide 12 text

5FTU.PDL(VBSE ͦͷείʔϓͷΈͰ ༗ޮͳϞοΫΛ࡞Δ

Slide 13

Slide 13 text

use Test::Mock::Guard; my $g = mock_guard 'ExternalAPI', { fetch => sub { 1 }, }; { my $g = mock_guard 'ExternalAPI', { fetch => sub { 0 }, }; ExternalAPI->fetch; #=> 0 } ExternalAPI->fetch; #=> 1 ͜ͷείʔϓ಺ͷΈͰ༗ޮ

Slide 14

Slide 14 text

5FTU8BSOJOHT ܯࠂ͕ग़͍ͯͳ͍͔ νΣοΫ

Slide 15

Slide 15 text

w ಛఆͷείʔϓͰXBSOJOHΛัଊ w ҙਤ͠ͳ͍XBSOJOH͕ग़ͯͳ͍͔ use Test::Warnings; like warning { warn 'test' }, qr/test/; warn 'debug'; done_testing; # fail!

Slide 16

Slide 16 text

5FTU$MBTT Y6OJUͬΆ͘ॻ͚Δ

Slide 17

Slide 17 text

w TFUVQUFBSEPXO TUBSUVQTIVUEPXO w ؀ڥม਺5&45@.&5)0%Λࢦఆͯ͠ ಛఆͷςετͷΈ࣮ߦ

Slide 18

Slide 18 text

package Foo; use parent qw/Test::Class/; sub setup : Test(setup) { $_[0]->{something} = 'init'; } sub foo : Tests { ... } sub bar : Tests { ... } __PACKAGE__->runtests; 5&45@.&5)0%GPPQSPWFUFTUU

Slide 19

Slide 19 text

ςετ͸ศརͰ
 ͋Ε͹͋Δ΄Ͳخ͍͠

Slide 20

Slide 20 text

ςετϑϨʔϜϫʔΫࣗମΛ ֦ுͨ͘͠ͳͬͯ͘Δ

Slide 21

Slide 21 text

UUFTUQNʹ ॻ͔ΕͨศརϋοΫ

Slide 22

Slide 22 text

ϞϯΩʔύον

Slide 23

Slide 23 text

5FTU#VJMEFSͷ֦ு͸େม

Slide 24

Slide 24 text

5FTUͷ
 ঺հ

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

5FTU#VJMEFSΛஔ͖׵͑Δ ৽͍͠ςετϑϨʔϜϫʔΫ

Slide 27

Slide 27 text

w 5FTU#VJMEFSΛϦϑΝΫλϦϯά w 5FTU4JNQMFEJTUSJCVUJPO
 όʔδϣϯҎ߱ w QFSM͔Β͸͕
 ඪ४Ϟδϡʔϧͱͯ͠ೖ͍ͬͯΔ

Slide 28

Slide 28 text

৽͍͠ͱ͸ w ςετͷςετ͕͠΍͍͢ w ֦ு͠΍͍͢ɺίʔυ͕੔ཧ͞Ε͍ͯΔ w Ҏલ͸5FTU#VJMEFSʹϞϯΩʔύον ͢Δ͔͠ͳ͔ͬͨ w ςετࣦഊ࣌ͷϨϙʔτ͕Θ͔Γ΍͍͢

Slide 29

Slide 29 text

5FTU#VJMEFSࣗମ͕ 5FTU"1*Ͱ
 ࣮૷͠௚͞Ε͍ͯΔ

Slide 30

Slide 30 text

5FTUҠߦͷ ஫ҙ఺

Slide 31

Slide 31 text

جຊతʹ͸Ҏલͷ 5FTU#VJMEFSͱͷޓ׵ੑ͕ ҡ࣋͞Ε͍ͯΔ

Slide 32

Slide 32 text

طଘͷςετ͕յΕΔ͔ʁ ˠେৎ෉

Slide 33

Slide 33 text

ͨͩ͠5FTU#VJMEFSʹ ϞϯΩʔύον Λ͍ͯ͠ΔͱյΕΔ

Slide 34

Slide 34 text

ؾ͍ͮͨΒ5FTUʹ
 ͳ͍ͬͯͨΒ

Slide 35

Slide 35 text

$BSUPOͰόʔδϣϯ
 ݻఆ͍ͯ͠ͳ͍ ґଘϞδϡʔϧ͕5FTUʹґଘ

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

ٸʹςετ͕յΕΔલʹ 5FTUҠߦ͠·͠ΐ͏

Slide 38

Slide 38 text

5FTUҠߦͷ஫ҙ఺Λ঺հ

Slide 39

Slide 39 text

ࣄྫ

Slide 40

Slide 40 text

VUGIBDLΛ΍ΊΔ

Slide 41

Slide 41 text

use utf8; use Test::More; pass 'ਖ਼͍͠'; done_testing; Wide character in print at /.../Test2/Formatter/ TAP.pm line 113. ok 1 - ਖ਼͍͠ 1..1

Slide 42

Slide 42 text

5FTU#VJMEFSʹϞϯΩʔύονͯ͠
 ग़ྗ࣌ʹVUGFODPEF

Slide 43

Slide 43 text

binmode Test::More->builder->$_, ":utf8" for qw/output failure_output todo_output/; no warnings 'redefine'; my $code = \&Test::Builder::child; *Test::Builder::child = sub { my $builder = $code->(@_); binmode $builder->$_, ":utf8" for qw/output failure_output todo_output/; return $builder; }; *__ORIGINAL::Test::Builder::_print_to_fh = \&Test::Builder::_print_to_fh; *Test::Builder::_print_to_fh = sub { my ($self, $fh, @args) = @_; binmode $fh, ':utf8'; goto \&__ORIGINAL::Test::Builder::_print_to_fh; }

Slide 44

Slide 44 text

5FTUͳΒ VTF5FTU1MVHJO65' ͢Δ͚ͩ

Slide 45

Slide 45 text

use utf8; use Test::More; use Test2::Plugin::UTF8; pass 'ਖ਼͍͠'; done_testing; ࣮ࡍ͸UUFTUQN಺ʹॻ͍͓͍ͯͯ ςετϑΝΠϧຖʹVTFUUFTU͢Δͱ ศར

Slide 46

Slide 46 text

ࣄྫ

Slide 47

Slide 47 text

&/%είʔϓ಺Ͱςετ͠ͳ͍

Slide 48

Slide 48 text

5FTU$MBTTͷSVOUFTUTΛ ࣗಈͰݺͿϋοΫ

Slide 49

Slide 49 text

package t::test; sub import { my $pkg = caller; eval qq{ package $pkg; use parent qw/Test::Class/; use Test::More; END { $pkg->runtests; } }; } package Foo; use t::test; sub foo : Tests { fail; } # __PACKAGE__->runtests; # ෆཁ ऴྃ࣌ʹSVOUFTUT͕ݺ͹ΕΔ ςετ

Slide 50

Slide 50 text

not ok 1 - foo # Failed test 'foo' # at /.../Test/Builder.pm line 135. # (in main->foo) 1..1 # Looks like you failed 1 test of 1. τϨʔε͕յΕΔ ςετग़ྗ

Slide 51

Slide 51 text

ͳͥʁ

Slide 52

Slide 52 text

5FTU"1*QN &/%ͷͱ͖͸ৗʹDBMMFS ʹͳΔ

Slide 53

Slide 53 text

5FTU"1*QN

Slide 54

Slide 54 text

w ͦ΋ͦ΋&/%ͷڍಈ͸೉͍͠ w &/%Λར༻ͯ͠ςετΛݺΜͰ͍Δ έʔε͸ผͷํ๏Λར༻͢Δ

Slide 55

Slide 55 text

package t::test; use Hook::AfterRuntime (); sub import { my $pkg = caller; eval qq{ package $pkg; use parent qw/Test::Class/; use Test::More; }; Hook::AfterRuntime::after_runtime { $pkg->runtests; }; }

Slide 56

Slide 56 text

package Foo; use strict; use warnings; use t::test; sub foo : Tests { } package Foo; use t::test; use warnings; use strict; my $__ENDRUNAAAAAAAA = 'Hook::AfterRuntime'->new(0); sub foo { &pass(); } package Foo; use attributes ('Foo', sub { package Foo; use warnings; use strict; &pass(); } , 'Tests'); %FQBSTF σετϥΫλ͕ݺ͹ΕΔ ϑΝΠϧ ͷऴΘΓ ίʔυΛJNQPSUઌʹ ૠೖ͍ͯ͠Δ

Slide 57

Slide 57 text

ϞϯΩʔύον͍ͯ͠Δ ςετϞδϡʔϧ΋յΕΔ

Slide 58

Slide 58 text

w 5FTU1SFUUZ w 5FTU8BSOJOHT

Slide 59

Slide 59 text

5FTUʹΑΔϝϦοτ΋͋Δ

Slide 60

Slide 60 text

5FTUͰςετ Λॻ͘

Slide 61

Slide 61 text

5FTU4VJUF

Slide 62

Slide 62 text

5FTUΛϕʔεʹ
 ศརͳςετؔ਺Λఏڙ

Slide 63

Slide 63 text

VTF5FTU7

Slide 64

Slide 64 text

DPNQBSF σʔλߏ଄ͷൺֱ 5FTU%FFQ

Slide 65

Slide 65 text

JT JT@EFFQMZ DNQ@EFFQMZ JT MJLF

Slide 66

Slide 66 text

my $ref = {a => 1, b => 2, c => [1, 2, 3]} # σʔλߏ଄͕ਖ਼͍͔͠νΣοΫ is $ref, {a => 1, b => 2, c = [1, 2, 3]}; # ࢦఆͨ͠΋ͷҎ֎͸νΣοΫ͠ͳ͍ like $ref, {b => 2};

Slide 67

Slide 67 text

ςετ͕GBJMͨ͠ͱ͖ͷग़ྗ

Slide 68

Slide 68 text

use Test2::V0; my $ref = {a => ['A'], b => 'baz'}; like $ref, hash { field a => array { item 'a' }; field b => match qr/bar/; # ଘࡏ͢Δ͔ field c => E(); end(); };

Slide 69

Slide 69 text

not ok 1 # Failed test at test.t line 9. # +--------+-----------------------+---------+--------------+------+ # | PATH | GOT | OP | CHECK | LNs | # +--------+-----------------------+---------+--------------+------+ # | | HASH(0x7fbddc028400) | | | 3, 9 | # | {a} | ARRAY(0x7fbddc028418) | | | 4 | # | {a}[0] | A | eq | a | 4 | # | {b} | baz | =~ | (?^:bar) | 5 | # | {c} | | !exists | | 7 | # +--------+-----------------------+---------+--------------+------+ ςετग़ྗ

Slide 70

Slide 70 text

NPDL ϞοΫ 5FTU.PDL(VBSE

Slide 71

Slide 71 text

my $mock = mock 'Foo' => ( add => [add_method => sub { ... }], override => [replace_method => sub { ... }], ); Foo->add_method; Foo->replaced_method;

Slide 72

Slide 72 text

w BEE PWFSSJEF w CFGPSF BGUFS BSPVOE w $MBTT.FUIPE.PEJpFSTΈ͍ͨͳͷ w 5FTU.PDL(VBSEͰ͸೉͔ͬͨ͠

Slide 73

Slide 73 text

FYDFQUJPO ྫ֎ͷνΣοΫ 5FTU'BUBM
 5FTU&YDFQUJPO

Slide 74

Slide 74 text

like(dies { die 'xxx' }, qr/xxx/); ok(lives { ... });

Slide 75

Slide 75 text

XBSOJOHT ܯࠂͷνΣοΫ 5FTU8BSO 5FTU8BSOJOHT

Slide 76

Slide 76 text

like warning { warn 'xxx' }, qr/xxx/; ok no_warnings { ... };

Slide 77

Slide 77 text

ཚ਺ͷTFFEʹ஫ҙ w σϑΥϧτͩͱຊ೔ͷ೔෇
 4FFEFETSBOEXJUITFFEGSPNMPDBMEBUF w ؀ڥม਺5@3"/%@4&&%ͰࢦఆՄೳ JTB@PLͷڍಈʹ΋஫ҙ

Slide 78

Slide 78 text

my $ref = {}; ref_ok($ref, 'HASH', 'ϋογϡϦϑΝϨϯε͔Ͳ͏͔'); isa_ok([], 'ARRAY'); # Failed test 'ARRAY->isa('ARRAY')' # at test.t line 3. # ARRAY is neither a blessed reference or a package name. 5FTU4VJUFͷJTB@PLͷڍಈ͸5FTU.PSFͱҟͳΔ

Slide 79

Slide 79 text

ςετ ศར৘ใ

Slide 80

Slide 80 text

ςετΛͭͷؔ਺ʹ ·ͱΊΔ

Slide 81

Slide 81 text

use Test::More; sub my_ok { ok($_[0]); } my_ok(0); my_ok(0); not ok 1 # Failed test at test.pl line 4. not ok 2 # Failed test at test.pl line 4. Ͳͷݺͼग़͠ݩͰGBJM͔ͨ͠Θ͔Βͳ͘ͳΔ

Slide 82

Slide 82 text

ղܾํ๏ ্ͭͷDBMMTUBDLΛݟΔΑ͏ ʹ఻͑Δ

Slide 83

Slide 83 text

use Test::More; sub my_ok { local $Test::Builder::Level = $Test::Builder::Level + 1; ok($_[0]); } 5FTU#VJMEFS MPDBM5FTU#VJMEFS-FWFM ͱॻ͍ͯ͸͍͚ͳ͍

Slide 84

Slide 84 text

use Test::More; use Test2::API qw/context/; sub my_ok { my $ctx = context(); ok($_[0]); $ctx->release; } 5FTU

Slide 85

Slide 85 text

not ok 1 # Failed test at test.pl line 10. not ok 2 # Failed test at test.pl line 11.

Slide 86

Slide 86 text

5FTU1MVHJO4PVSDF%JBH

Slide 87

Slide 87 text

ςετͷग़ྗ݁Ռʹ GBJMͨ͠ߦͷιʔείʔυΛ දࣔ

Slide 88

Slide 88 text

use Test2::V0; use Test2::Plugin::SourceDiag; my $something = 'test'; my $pat = qr/test2/; like $something, $pat; done_testing;

Slide 89

Slide 89 text

not ok 1 - is $something, $pat; # Failed test 'is $something, $pat;' # at test.t line 6. # +------+----+------------+ # | GOT | OP | CHECK | # +------+----+------------+ # | test | =~ | (?^:test2) | # +------+----+------------+ ςετग़ྗ

Slide 90

Slide 90 text

5FTU%FFQͷΑ͏ʹॻ͖͍ͨ

Slide 91

Slide 91 text

5FTU%FFQ-JLF HJUIVCDPNBLJZN5FTU%FFQ-JLF

Slide 92

Slide 92 text

use Test::Deep; cmp_deeply $foo, isa('Foo') & methods(foo => 'FOO'); 5FTU%FFQ 5FTU4VJUF use Test2::V0; is $foo, object { prop blessed => 'Foo'; call foo => 'FOO'; };

Slide 93

Slide 93 text

use Test2::V0; use Test2::DeepLike; is $foo, isa('Foo') & methods(foo => 'FOO'); 5FTU%FFQ-JLF

Slide 94

Slide 94 text

not ok 1 # Failed test at t/methods.t line 16. # Compared $data->foo # got : 'BAR' # expect : 'FOO' 5FTU%FFQ 5FTU%FFQ-JLF not ok 1 # Failed test at t/methods.t line 16. # +-------+-----+----+-------+ # | PATH | GOT | OP | CHECK | # +-------+-----+----+-------+ # | foo() | BAR | eq | FOO | # +-------+-----+----+-------+

Slide 95

Slide 95 text

use Test2::V0; use Test2::DeepLike; my $foo = bless {}, 'Foo'; my $bar = bless {}, 'Bar'; is [$foo, $bar], bag(isa('Foo'), isa('Baz'));

Slide 96

Slide 96 text

not ok 1 # Failed test at test.t line 7. # Comparing $data as a Bag # Missing: 1 reference # Extra: 1 reference 5FTU%FFQ 5FTU%FFQ-JLF not ok 1 # Failed test at test.t line 7. # +------+--------------------------+---------+------------------+-----+ # | PATH | GOT | OP | CHECK | LNs | # +------+--------------------------+---------+------------------+-----+ # | [*] | | ISA | Baz | 7 | # | [1] | Bar=HASH(0x7f91c0803268) | !exists | | | # +------+--------------------------+---------+------------------+-----+

Slide 97

Slide 97 text

·ͱΊ

Slide 98

Slide 98 text

w ςετϞδϡʔϧͷ঺հ w 5FTUҠߦͷ஫ҙ఺ w VTF5FTU1MVHJO65' w 5FTUͷςετͷॻ͖ํ w 5FTUͰςετΛศརʹ͢Δ