Slide 1

Slide 1 text

perl ͳ web application ͷͨΊ ͷςετ৘ใ yapc::asia 2013 at hiyoshi soh335

Slide 2

Slide 2 text

About Me

Slide 3

Slide 3 text

• soh335 • KAYAC inc. • ࣗࣾαʔϏε

Slide 4

Slide 4 text

ςΩετ http://search.cpan.org/~soh/

Slide 5

Slide 5 text

https://github.com/soh335

Slide 6

Slide 6 text

https://github.com/soh335

Slide 7

Slide 7 text

https://github.com/soh335

Slide 8

Slide 8 text

http://soh335.hatenablog.com/

Slide 9

Slide 9 text

Agenda

Slide 10

Slide 10 text

• ςετΛॻ͍ͯ΋Β͍΍͍͢؀ڥ΁ • Ϟδϡʔϧ • db ճΓͷςετͷߴ଎Խ

Slide 11

Slide 11 text

• perl ॻ͘ͷ׳Ε͖͚ͯͨͲɺςετ͸·͔ͩͳ͍͊ͬͯ͏ ਓɾ޻෉͍ͨ͠ͳ͍͊ͬͯ͏ਓ • perl ΍ͬͯͳ͍ਓ ର৅

Slide 12

Slide 12 text

࿩͞ͳ͍͜ͱ • ͜͏ TDD ͢Δͱʙʢ֓೦ʣ • ෼ࢄͯ͠ςετ͢Δͱʙʢ͍͢͝ʣ • ΞδϟΠϧ͕Ͳ͏͜͏ʢ೉͍͠ʣ • test Λॻ͔ͳ͍ͱͳ͍͚ͥͳ͍ͷ͔ʢͭΒ͍ʣ • ͋ͱɺϑϩϯτͷςετ

Slide 13

Slide 13 text

Writing Tests

Slide 14

Slide 14 text

• jenkins Λ্ख͘ճͤͯͳ͍ϓϩδΣΫτ͕͋ͬͨ • ͳΜͰ্ख͍͔͘ͳ͍ΜͩΖ͏ ?

Slide 15

Slide 15 text

• ͕࣌ؒͳͯ͘ςετΛॻ͘Ջ͕ͳ͍ʁ • ͔΋͠Εͳ͍ʢ͜ͷεϥΠυͰ͸ѻΘͳ͍ʣ • ςετ͕ॻ͖ʹ͍͘ঢ়ଶͩͬͨ • ͜ͷεϥΠυͰ࿩͢͜ͱ ͳͥ ?

Slide 16

Slide 16 text

• test ͕ॻ͖ʹ͍͘ঢ়ଶ • test Λॻ͘ίετ͕ߴ͍ɾख͕͔͔ؒΔɾ͕͔͔࣌ؒΔ • ΊΜͲ͍͘͞

Slide 17

Slide 17 text

• ॻ͖΍͍͢ঢ়ଶʹͯ͋͠Ε͹ɺͱ͖ͬͭʹ͍͘ਓʹͱͬͯ ͷোน͕ݮΔ • ศརͳؔ਺΍ϞδϡʔϧΛ࢖ͬͯϨʔϧΛෑ͘ • ྑ͍ςετͱ͔ɺѱ͍ςετ͕Ͳ͏͜͏ͷલʹɺॻ͔ͳ͍ ͱ্ख͘ͳΒͳ͍

Slide 18

Slide 18 text

t/Util.pm

Slide 19

Slide 19 text

• ྫ͑͹ϢʔβΦϒδΣΫτ͔ΒԿ͔Λऔಘ͢Δ஋ͷςετ • t/schema/row/user__take_something.t

Slide 20

Slide 20 text

use Test::More; use MyApp::Schema::Row::User; my $user = MyApp::Schema->user->insert({ name => ...., ... => ...., ... => ...., ... => ...., ... => ...., ... => ...., }); my $something = $user->take_something; is $something, ...; done_testing; $user Λ४උ͢Δ ஋Λऔಘͯ͠ਖ਼͍͔͠ ͔֬ΊΔ

Slide 21

Slide 21 text

• ྫ͑͹ϢʔβΦϒδΣΫτΛ༻͍ͯԿ͔Λ͢Δࡍͷςετ • t/schema/row/user__do_something.t

Slide 22

Slide 22 text

use Test::More; use MyApp::Schema::Row::User; my $user = MyApp::Schema->user->insert({ name => ...., ... => ...., ... => ...., ... => ...., ... => ...., ... => ...., }); ok $user->do_something; done_testing;

Slide 23

Slide 23 text

VTFS@@UBLF@T PNFUIJOHU VTFS@@VQEBUF U VTFS@@EP@TP NFUIJOHU VTFS@@EJFU VTFS@@EVQMJD BUFU VTFS@@EFBE@M PDLU

Slide 24

Slide 24 text

• test ͕૿͍͑ͯͬͨޙʹ user ͷ schema ͕มΘΔͱେྔͷ ςετΛॻ͖׵͑ͳ͍ͱ͍͚ͳ͍ • t/Util.pm ʹ create_user Έ͍ͨͳͷΛ࡞Δ

Slide 25

Slide 25 text

package t::Util; use strict; use warnings; use parent 'Exporter'; our @EXPORT = qw(create_user); sub create_user { ... } 1;

Slide 26

Slide 26 text

• t/Util.pm ʹྑ͘࢖͏ؔ਺Λ·ͱΊ͍ͯ͘ࣄͰɺΊΜͲ͘͞ ͞Λղফ͢Δ

Slide 27

Slide 27 text

random name

Slide 28

Slide 28 text

subtest test1 => sub { my $user = MyApp::Schema->user->insert({ name => "soh335", }); }; subtest test2 => sub { my $user = MyApp::Schema->user->insert({ name => "soh336", }); }; name ͕ uqniue ͩͱͯ͠ద ౰ʹ͚ͭΔ unique ΛอͭͨΊʹͪΐ ͬͱม͑Δ ...

Slide 29

Slide 29 text

• ҙ֎ͱҰҙͳ໊લΛ͍ͪͪ͘༻ҙ͢Δͷ͕ΊΜͲ͍͘͞ • create_user ͱ͔ʹ random ʹੜ੒͢ΔΑ͏ʹ͢ΔͳͲ

Slide 30

Slide 30 text

my $user1 = create_user(); my $user2 = create_user(); my $user3 = create_user(); soh338 soh256 soh942

Slide 31

Slide 31 text

ॱংʹґଘͨ͠ Test::More::subtest

Slide 32

Slide 32 text

use Test::More; use t::Util qw(create_user) my $user = create_user(); subtest 'foo' => sub { ok $user->do_something; }; subtest 'bar' => sub { my $something = $user->take_something; is $something, ...; }; done_testing; ̍ͭ໨ͷςετΛॻ͘ ̎ͭ໨ͷςετΛॻ͘

Slide 33

Slide 33 text

my $user = create_user(); subtest 'foo' => sub { ok $user->do_something; }; subtest 'bar' => sub { my $something = $user->take_something; is $something, ...; }; subtest 'baz' => sub { ok $user->update_something; }; baz Λ௥Ճ user ͷঢ়ଶ͕ͲΜͲ ΜมΘΔ ࠷ॳͷ subtest Λमਖ਼͢Δͱ શ෦मਖ਼͢Δඞ༻͕ग़Δ͔΋͠Ε ͳ͍

Slide 34

Slide 34 text

• subtest Ͱ͍ͬͯ͘͘͘ͷ͕ѱ͍͜ͱͰ͸ͳ͍ • top level ͰΦϒδΣΫτΛڞ༗͢Δͱ͋Γ͕ͪ • Test::Class • http://shibayu36.hatenablog.com/entry/2013/07/16/231144

Slide 35

Slide 35 text

• ڊେͳҰຕͳ test Λॻ͔ͳ͍ • t/schema/row/user/01_take_something.t • t/schema/row/user/02_do_update.t • t/schema/row/user__take_something.t • t/schema/row/user__do_update.t • ͱ͔Ͱ෼͚ͯΔ

Slide 36

Slide 36 text

࣌ؒճΓͷςετ Test::MockTime

Slide 37

Slide 37 text

• ͜ͷظ͔ؒΒɺ͜ͷظؒ·ͰڍಈΛม͍͑ͨͱ͔ɺweb application ͩͱ͋Γ͕ͪɻ • perl ͳΒ time() ͷڍಈΛม͑ΒΕΔ

Slide 38

Slide 38 text

use Test::MockTime; use Time::Piece; ઌʹ Test::MockTime ΛಡΈ ࠐ·ͳ͍ͱͩΊ

Slide 39

Slide 39 text

࣌ؒΛࢭΊΔ ಈ͖ग़͢... use Test::MockTime (:all); set_fixed_time('2013-01-01T00:00:00Z'); # 2013-01-01 00:00:00 time() ...; restore_time(); 2013 - 01 - 01 00:00:00

Slide 40

Slide 40 text

use Test::TimBlock; timeblock { # set_fixed_time('2013-01-01 00:00:00', '%Y-%m-%d %H:%i:%s +0900'); set_time "2013-01-01 00:00:00"; ... }; # <- restore_time scope Λൈ͚Δͱ restore_time() ΛݺͿΑ͏ͳ wrapper Λ project ༻ʹ࡞ͬͨΓͯ͠Δ set_fixed_time( '2013-01-01 00:00:00', '%Y-%m-%d %H:%i:%s +0900' );

Slide 41

Slide 41 text

# set_fixed_time('2013-01-01 00:00:00', '%Y-%m-%d %H:%i:%s +0900'); set_fixed_time '2013-01-01 00:00:00' => sub { ... }; # <- restore_time scope Λൈ͚Δͱ restore_time() ͕ݺ͹ΕΔ Test::TimeMock::set_fixed_time ʹ sub {} Λ౉ͤΔΑ͏ʹ͢Δ

Slide 42

Slide 42 text

DataStore

Slide 43

Slide 43 text

Test::mysqld mysqld runner for tests

Slide 44

Slide 44 text

• ͍͍ͩͨͷ web application ͩͬͨΒ db ͕෇͖వ͏ • temporary ͳ mysqld process ΛͨͯͯɺͦΕΛςετʹ࢖ ͏ • MyApp::Test ͱ͔ t::Util ͱ͔Ͱ db ͷܨ͙ઌΛ test::mysqld ʹ ্ॻ͖͢Δ

Slide 45

Slide 45 text

UFTUNZTRME EBUBCBTFU NZTRME test ͷ͚࣌ͩॻ͖׵͑Δ

Slide 46

Slide 46 text

package MyApp::Test; use Test::mysqld; our $mysqld; sub import { my $class = shift; { $mysqld = Test::mysqld->new( my_cnf => { 'skip-networking' => '', } ); MyApp->config->{ dbi } = [ $mysqld->dsn( dbname => 'test' ) ]; } } 1; ෼͔Γ΍͘͢ྫ͑Δͱ MyApp::Test ͕ use ͞ΕΔͱ dbi ͷ ઃఆΛॻ͖׵͑Δ

Slide 47

Slide 47 text

• Test::mysqld ͷηοτΞοϓʹ͸͋Δఔ౓ίετ͕͔͔Δͷ Ͱ࣮ࡍʹ db ΛಡΈࠐΉͱ͜ΖͰઃఆͷ্ॻ͖Λ͢ΔΑ͏ ʹͨ͠Γ͢Δ • खݩͳΒ mysqld ্ཱͪ͛ͬͺͳ͠ͰͦΕΛ࢖͏ͱ͔΋͋ Γ

Slide 48

Slide 48 text

Test::RedisServer redis-server runner for tests

Slide 49

Slide 49 text

package MyApp::Test; use Test::RedisServer; our $redis_server; sub import { my $class = shift; { $redis_server = Test::RedisServer->new; MyApp->config->{ redis } = $redis_server->connect_info; } } 1;

Slide 50

Slide 50 text

use utf8;

Slide 51

Slide 51 text

• use utf8; ͳ͍ͱ͖ʹΑ͘Θ͔Βͳ͍ײ͡ͰϋϚΔͱΊΜͲ ͏ • use utf8 ͕ͳ͍ϑΝΠϧ͕͋Δͱςετ͕௨Βͳ͍

Slide 52

Slide 52 text

Plack ճΓ

Slide 53

Slide 53 text

Plack::Test Test PSGI applications with various backends

Slide 54

Slide 54 text

use Plack::Test; test_psgi app => sub { my $env = shift; return [ 200, [ 'Content-Type' => 'text/plain' ], [ "Hello World" ] ], }, client => sub { my $cb = shift; my $req = HTTP::Request->new(GET => "http://localhost/hello"); my $res = $cb->($req); like $res->content, qr/Hello World/; }; from Plack::Test synopsis app ʹ request

Slide 55

Slide 55 text

my $app = MyApp->new test_psgi( app => $app->handler, client => sub { my $cb = shift; my $req = GET 'http://localhost/hello'; my $res = $cb->($req); like $res->content, qr/Hello World/; } ); ࣮ࡍʹ͸ MyApp ͱ ͔͔Β app ͱͳΔͱ͜Ζ Λ౉͢

Slide 56

Slide 56 text

use MyApp::Test; my $req = GET 'http://localhost/hello'; my $res = request_to_app( $req ); like $res->content, qr/Hello World/; MyApp::Test ͱ͔Ͱָʹग़དྷΔ ͷ΋Α͍Ͱ͢Ͷ͐ HTTP::Cookie ࢖ͬͯ cookie ΋ ѻ͑ΔΑ͏ʹͨ͠Γ͢Δ

Slide 57

Slide 57 text

Test::WWW::Mechanize ::PSGI Test PSGI programs using WWW::Mechanize

Slide 58

Slide 58 text

my $app = MyApp->new; my $mech = Test::WWW::Mechanize::PSGI->new( app => $app->handler ); $mech->get('/hello'); ok $mech->content_like(qr/Hello World/); mechanize ͷ interface Λ࢖ ͬͯςετ͕ग़དྷΔ

Slide 59

Slide 59 text

• ݸਓతʹ͸ api ͷςετΛॻ͘͜ͱͷํ͕ࠓ͸ଟ͍ͷͰ Test::PSGI + α Ͱ଍ΓͯΔ

Slide 60

Slide 60 text

Testing Batch and Script

Slide 61

Slide 61 text

• ఆظత or Կ͔໰୊͕͋ͬͯ batch script ͷΑ͏ͳ΋ͷ͸Α ͘ॻ͘ • ఆظతʹ࢖͏΋ͷ͸ͪΌΜͱςετ͞Ε͍ͨ • ໰୊͕͋ͬͯमਖ਼͢ΔΑ͏ͳ৔߹͸ͪΌΜͱಈ࡞Λอো͠ ͍ͨ • όονͷ࣮ߦΛ package ʹ֎ग़͢͠Δ

Slide 62

Slide 62 text

TDSJQUEP@TPNFUIJOHU TDSJQUCBUDIQM .Z"QQ#BUDI4PNFU IJOH ҰຕͰશ෦΍ͬ ͯ͘ΕΔ script ෼͚Δ ίϚϯυϥΠϯ͔Β ϞδϡʔϧΛݺͿ ॲཧຊମ

Slide 63

Slide 63 text

use Class::Load qw(load_class); use FindBin::libs; my $name = shift @ARGV; my $module = "MyApp::Batch::$name"; load_class($module); $module->new_with_options->run; ίϚϯυϥΠϯ͔Β౉͞Εͨจ ࣈྻ͔Β class Λ new ͯ͠ run method ΛݺͿ perl script/batch.pl Something --go

Slide 64

Slide 64 text

package MyApp::Batch::Something; use Mouse; with 'MouseX::Getopt'; has go => ( is => 'ro', isa => 'Bool', default => sub { 0 } ); no Mouse; sub run { .... } 1; Mo[ou]seX::Getopt ͰίϚϯυϥΠϯͷ Ҿ਺Λ attribute ʹ͋ͯΔ

Slide 65

Slide 65 text

࣮ߦલͷঢ়ଶͷςετ ࣮ߦޙͷঢ়ଶͷςετ use Test::More; use MyApp::Batch::Something; # before testing MyApp::Batch::Something->new( go => 0 )->run; # after testing done_testing;

Slide 66

Slide 66 text

Testing Cache

Slide 67

Slide 67 text

NPEVMF NZTRM DBDIF ॳճͷΞΫηε͸ mysql ʹΞΫηε͢Δ ೋ౓໨͔Β͸ mysql ʹ͸ ΞΫηε͕ͳ͍

Slide 68

Slide 68 text

package t::Util; sub trace_sql (&) { my $sub = shift; my @sqls; require DBIx::QueryLog; my $g = DBIx::QueryLog->guard; local $DBIx::QueryLog::OUTPUT = sub { my %params = @_; push @sqls, $params{sql}; }; $sub->(); @sqls; } 1; ͜ͷ scope ͚ͩ query Λऔ ಘ͢Δ

Slide 69

Slide 69 text

{ my @sqls = trace_sql { $user->do_heavy_something; }; is scalar @sqls, 10; } { my @sqls = trace_sql { $user->do_heavy_something; }; is scalar @sqls, 0; # cache ! } 10 ճ query ͕ྲྀΕ͍ͯΔ ̍ճ΋ query ͕ྲྀΕ͍ͯͳ͍

Slide 70

Slide 70 text

Testing for not engineer

Slide 71

Slide 71 text

01.jpg 02.jpg 03.jpg august 01.jpg 02.jpg 03.jpg september ຖ݄ߋ৽͢Δ͚Ͳը૾ ͷ໋໊نଇ͸ಉ͡ σΟϨΫτϦͱਖ਼͍͠ը ૾͕͋Δ͔Λςετ͢Δ

Slide 72

Slide 72 text

ZBQDIUNM ΍ʔͽͬ͘

Slide 73

Slide 73 text

• ը૾ͷ໋໊نଇ • ฆΒΘ͍͠จݴ • master data

Slide 74

Slide 74 text

• ͜Μͳײ͡Ͱ৭ʑ༻ҙ͢Δͱςετʹ׳Εͯͳ͍ਓͰ΋޾ ͤʹͳΕΔ • ٳܜ..........

Slide 75

Slide 75 text

Test CPAN Module

Slide 76

Slide 76 text

Test::Deep Extremely flexible deep comparison

Slide 77

Slide 77 text

is_deeply( $user, { name => "foo" relation_users => ["bar", "baz", "yap"], map => { 1 => "hoge", 10 => "fuga", 100 => "piyo", }, }, ); hash ͱ͔ array ͕ܾ·ͬͨύλʔϯ͡ Όͳ͘୔ࢁ͋Δͱ is_deeply ͩͱͩΔ͍࣌ ͕͋Δ

Slide 78

Slide 78 text

cmp_deeply( $user, { name => "foo" relation_users => bag("baz", "yap", "bar"), map => { 1 => "hoge", 10 => "fuga", 100 => "piyo", }, }, ); Test::Deep ͔Β export ͞ΕΔ ॱং͸อোͤͣʹ಺༰͸શ෦ ͋Δ͜ͱΛςετ͢Δ ॱং͸อোͤͣʹ಺༰͸શ෦ ͋Δ͜ͱΛςετ͢Δ

Slide 79

Slide 79 text

cmp_deeply( $user, { name => "foo" relation_users => bag("baz", "yap", "bar"), map => superhashof({ 1 => "hoge", 10 => "fuga", }), }, ); hash ͷҰ෦ͷ key ͚ͩςετग़ དྷΕ͹ྑ͍

Slide 80

Slide 80 text

cmp_deeply( $user, { name => ignore(), relation_users => bag("baz", "yap", "bar"), map => superhashof({ 1 => "hoge", 10 => "fuga", }), }, ); hash ͷ key ͷଘࡏ͚ͩςετ ͠ɺ஋͸ԿͰ΋ྑ͍

Slide 81

Slide 81 text

Test::Deep::JSON Compare JSON with Test::Deep

Slide 82

Slide 82 text

cmp_deeply( $res->content, json({ name => ignore(), relation_users => bag("baz", "yap", "bar"), map => superhashof({ 1 => "hoge", 10 => "fuga", }), }), ); json ʹ decode ͯ͘͠Ε Δ

Slide 83

Slide 83 text

Test::Deep::Matcher Type check matchers for Test::Deep

Slide 84

Slide 84 text

cmp_deeply( $res->content, json({ name => ignore(), relation_users => bag("baz", "yap", "bar"), map => superhashof({ 1 => is_string, 10 => "fuga", }), }), ); is_* Ͱ ignore ΑΓܕͰݫ͠໨ʹν ΣοΫग़དྷΔ

Slide 85

Slide 85 text

Test::Deep::Cond simple code test in Test::Deep

Slide 86

Slide 86 text

cmp_deeply( $res->content, json({ name => ignore(), relation_users => is_array_ref && cond { scalar @$_ == 3 }, map => superhashof({ 1 => is_string, 10 => "fuga", }), }), ); ͪΐͬͱͨ͠ࣄʹ plugin ͱ͔࡞Γ ͨ͘ͳ͍ͳʔͬͯ࣌ʹ $_ ʹ test ͞ΕΔ ஋Λ͍Εͯ͘ΕΔɻ 2 <= $_ and < 5 ͱ͔ɻ

Slide 87

Slide 87 text

• superhashof ͱ͔͸ಛʹෳࡶͳ json Λฦ͢Α͏ͷςετͰ ͸ศར͚ͩͲɺ΍Γ͗͢Δͱɺຊ౰͸ςετ͕ඞ༻ͳ΋ͷ ͕লུ͞ΕͨΓͯ͠ؾ͔ͮͳ͍͔Β஫ҙɻ

Slide 88

Slide 88 text

Test::MockTime Replaces actual time with simulated time

Slide 89

Slide 89 text

• ͖ͬ͞આ໌ͨ͠ͷͰඈ͹͠

Slide 90

Slide 90 text

Test::Exception Test exception based code

Slide 91

Slide 91 text

use Test::Exception; throws_ok { $user->do_something; } qr(user is died because ...), 'expect to die'; ͪΌΜͱྫ֎Λ౤͛ͯɺ͔ͭͦͷจ ݴΛςετ

Slide 92

Slide 92 text

Test::Fatal incredibly simple helpers for testing code with exceptions

Slide 93

Slide 93 text

use Test::Fatal; like( exception { $user->do_something }, qr(user is died because ...), "expect to die", ); Test::Exception ΑΓί ʔυ͕ simple

Slide 94

Slide 94 text

Test::Mock::Guard Simple mock test library using RAII

Slide 95

Slide 95 text

No content

Slide 96

Slide 96 text

• ͱ͍͏࿩͸ஔ͍͓͍ͯͯ

Slide 97

Slide 97 text

Test::Output Utilities to test STDOUT and STDERR messages

Slide 98

Slide 98 text

stderr_is( $user->depcateded_method(), "this method is deplicated !" ); stdout_is, stdout_like ͱ ͔΋͋Δ ྫ͑͹ deplicated ͳ method ͕ݺ͹ΕͨΒ warn ͢Δ͚Ͳɺ৚ ͕݅ෳࡶ͔ͩΒͪΌΜͱݺ͹ΕΔ͔ςετ ͓͖͍ͯͨ͠

Slide 99

Slide 99 text

my $buffer = ''; open my $fh, '>', \$buffer or die $!; local *$STDERR = $fh; $user->depcateded_method(); is $buffer, 'this method is deplicated !'; ݸਓతʹ͸͜ΕͰࣄ଍ΓΔ ͔ͳ͊...

Slide 100

Slide 100 text

use Test::Mock::Guard qw(mock_guard); my $guard = mock_guard( 'MyApp::Schema::Row::User', { 'take_something' => sub { return +{ foo => 1, bar => 2, } }, } ); is_deeply( $user->take_something, { foo => 1, bar => 2, } ); is $guard->call_count( 'MyApp::Schema::Row::User', 'take_something' ), 1; $guard ͕ scope ͷதͰଘ ࡏ͢Δ͚࣌ͩϝιουͷڍಈ Λࠩ͠ସ͑Δ ݺ͹Εͨճ਺Λς ετ

Slide 101

Slide 101 text

http mock

Slide 102

Slide 102 text

• Test::Mock::LWP • Test::Mock::LWP::Conditional • Test::Mock::Furl

Slide 103

Slide 103 text

• ruby ͷ webmock • https://github.com/bblimke/webmock • ֎ʹग़Α͏ͱͨ͠Β die • url ͚ͩ͡Όͳͯ͘ parameter, content, header ͕͋Θͳ͔ ͬͨΒ die

Slide 104

Slide 104 text

• Test::Mock::Furl::Constraint • https://github.com/soh335/Test-Mock-Furl-Constraint

Slide 105

Slide 105 text

speed up test with db

Slide 106

Slide 106 text

• web application, db ͷςετ͕ଟͯ͘ɺςετ͕૿͑Ε͹૿ ͑Δ΄Ͳ஗͘ͳΔ • ࠷ऴతʹ͸෼ࢄͱ͔ͯ͠.... ʹͳΔͷ͔΋͠Εͳ͍͚Ͳɺݸ ਓతʹ͸ͦͷྖҬ·Ͱߦͬͯͳ͍ͷͰ͜͜Ͱ͸ѻΘͳ͍Ͱ ͢

Slide 107

Slide 107 text

• prove -j • ฒྻ࣮ߦ • ฒྻ࣮ߦͯ͠΋େৎ෉Α͏ͳςετΛॻ͘ • ϑΝΠϧͱ͔͸ File::Temp ࢖ͬͨΓ... • Test::Synchronized ͍ͬͯ͏ͷ΋͋Δ͚Ͳ ....

Slide 108

Slide 108 text

JNBHF@XSJUFU JNBHF@VQEBUFU JNBHF@EFMFUFU UFTUKQFH ྫ͑͹ը૾ͷ test Ͱ֤ test Ͱಉ໊͡લͰૢ࡞͢ΔͱฒྻͰ ςετͨ࣌͠ʹ͓͔͘͠ͳΔ use File::Temp !

Slide 109

Slide 109 text

• Test::mysqld ͷ্ཱͪ͛ʹ͕͔͔࣌ؒΔ • Ͳ͜ʹ͕͔͔͍࣌ؒͬͯΔ͔ௐ΂Δ

Slide 110

Slide 110 text

5FTUNZTRME TDIFNB NBTUFS EBUB NZTRME mysqld ͷ্ཱͪ͛ʹ ͕͔͔࣌ؒΔ schema, master data Λ͍ΕΔͷʹ࣌ؒ ͕͔͔Δ

Slide 111

Slide 111 text

• schema Λ࡞ͬͨΓ data Λྲྀ͜͠Ήॴ • ඞ༻ͳσʔλ͚ͩΛಡΈࠐΉΑ͏ʹ͢Δ • ͦΕ͸ͦΕͰΊΜͲ͍͘͞ • σʔλ͕શͯἧͬͯΔঢ়ଶͰςετ͍ͨ͠ؾ࣋ͪ

Slide 112

Slide 112 text

• ઌʹηοτΞοϓࡁΈͷςετ༻ mysqld Λ༻ҙͯ͠͠·͏ • શͯͷςετ͕૸Δ࠷ॳʹ temporary ͳ mysqld Λ࡞Γɺ schema ΍ data Λ༻ҙ͢Δ • ֤ςετͰ db ͕ඞ༻ͳ৔߹͸͔ͦ͜Β copy Λ͠ɺmy.cnf ͳͲΛॻ͖׵͑ͯىಈ͢Δ

Slide 113

Slide 113 text

@VTFSU @VTFSU @VTFSU @VTFSU PSJHJOBM UFTUNZTRME @VTFSU DPQZ UFTUNZTRME prove ։࢝࣌ʹ schema, master data ͕ೖ ͬͯΔ original test::mysqld Λ࡞Δ ֤ςετϑΝΠϧͰ ͸ original test::mysqld ͔Β copy ͠ɺmy.cnf Λमਖ਼͠ى ಈ͢Δ schema, master data Λ༻ҙ ͢ΔίετΛԼ͛ͨ

Slide 114

Slide 114 text

• Test::mysqld::copy_data_from (0.17)

Slide 115

Slide 115 text

• copy ͠·ͬͯ͘Δͱ io ͕ࢮ͵ • copy ճΓͷ΍ΓͱΓΛ tmpfs Ͱ΍Δ

Slide 116

Slide 116 text

• mysqld Λ্ཱͪ͛Δࣗମʹίετ͕͔͔Δ • App::Prove::Plugin::MySQLPool • https://github.com/mash/App-Prove-Plugin-MySQLPool

Slide 117

Slide 117 text

@VTFSU @VTFSU @VTFSU @VTFSU UFTUNZTRME @VTFSU UFTUNZTRME UFTUNZTRME UFTUNZTRME test::mysqld Λฒྻ ෼ ্ཱͪ͛Δ ্ཱ͕ͪͬͯΔ mysql ͔Β࢖͑Δ΋ͷ͕ ׂΓ౰ͯΒΕΔ mysqld ͷ্ཱͪ͛ ͷίετ͕͔͔Βͳ͘ ͳΔ

Slide 118

Slide 118 text

• -j ͗ͯ͢͠ cpu ͕ͭΒ͍ • cpu ࢖͍͖ͬͪΌ͏ͱεϖοΫ͋͛Δ͔෼ࢄ͢Δ͔ ....

Slide 119

Slide 119 text

• ͦΜͳ͋ͳͨʹɺ໌೔ͷ 15:40 ͔Βͷ myfinder ͞Μͷ ϑϧςετ΋50msͰऴΘΒ͍ͤͨ ʙ FreakOutͷऔΓ૊ Έ ʙ ຊ౰ͷߴ଎ԽΛݟͤͯ ͘ΕΔͬͯ HUB Ͱݴͬͯ·͠ ͨ !!!!

Slide 120

Slide 120 text

let’s testing !