Slide 1

Slide 1 text

PHPόʔδϣϯΞοϓͱ ܾࡁϦϓϨΠεΛࢧ͑ͨ Ϣχοτςετ 2018/12/15 (Sat) PHP Conference 2018 Kazuki Higashiguchi / BASE, Inc.

Slide 2

Slide 2 text

Theme of this Talk • ςετ͕গͳ͍ίʔυϕʔεʹରͯ͠Ϣχο τςετΛॻ͍͍ͯͨ͘Ίͷٕ๏ • ςετ͕ແ͍ίʔυΛ࡞Βͳ͍ͨΊͷΞϓ ϩʔν

Slide 3

Slide 3 text

About me • ౦ޱ ࿨ᏻ (@higasgt) • Server Side EngineerʢPHP / Goʣ • BASE, Inc. / BASE Product Division • PHPόʔδϣϯΞοϓ / ޙ෷͍ܾࡁϦϓϨΠε / YELL BANK • Blog: http://khigashigashi.hatenablog.com/

Slide 4

Slide 4 text

About BASE Ձ஋ͷަ׵ΛΑΓγϯϓϧʹ͠ɺ ੈքதͷਓʑ͕࠷దͳܦࡁ׆ಈΛߦ͑ΔΑ͏ʹ͢Δɻ MISSION ωοτγϣοϓ࡞੒αʔϏε ʮBASEʯ γϣοϐϯάΞϓϦ ʮBASEʯ

Slide 5

Slide 5 text

Agenda 1. ͳͥզʑ͸Ϣχοτςετ͕ඞཁͳͷ͔ 2. طଘίʔυΛอޢ͢Δٕ๏ 3. ϢχοτςετྔΛ૿΍͢ࢼΈ 4. Ϣχοτςετ૿Ճʹ͓͚Δ՝୊ͱରࡦ 5. ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͠ͳ͍ٕ๏ 6. ·ͱΊ

Slide 6

Slide 6 text

1. ͳͥզʑ͸Ϣχοτςετ ͕ඞཁͳͷ͔

Slide 7

Slide 7 text

BASE 2017೥ͷ֓گ • 2012೥αʔϏε։࢝ • ଟ͘ͷαʔϏεͰPHP5.3/CakePHP2.3Λ ར༻ • Ϣχοτςετ͕ॻ͔Ε͍ͯΔαʔϏε͕ গͳ͔ͬͨ

Slide 8

Slide 8 text

Ϣχοτςετ͕গͳ͍͕ނʹ • ʮϨΨγʔίʔυʯͱͳΔίʔυϕʔε • อक·ͨ͸֦ு͕ࠔ೉ʹͳΓ͏Δ

Slide 9

Slide 9 text

–ϚΠέϧɾCɾϑΣβʔζஶ ʰϨΨγʔίʔυվળΨΠυʱ “ϨΨγʔίʔυͱ͸ɺ ୯ʹςετͷͳ͍ίʔυͰ͢ɻ” IUUQTXXXTIPFJTIBDPKQCPPLEFUBJM

Slide 10

Slide 10 text

• ີ݁߹ͳίʔυઃܭ • ϢχοτςετΛॻ͍͍ͯͳ͍ίʔυ͸ɺ ີ݁߹ʹͳΓςετ͕ॻ͖ͮΒ͍ίʔυ ʹͳ͍ͬͯΔέʔε͕ଟ͍ Ϣχοτςετ͕গͳ͍͕ނʹ

Slide 11

Slide 11 text

“ίʔυΛมߋ͢ΔͨΊʹ͸ɺςετΛ੔ උ͢Δඞཁ͕͋Δɻଟ͘ͷ৔߹͸ɺςε τΛ੔උ͢ΔͨΊʹ͸ɺίʔυΛมߋ͢ Δඞཁ͕͋Δɻ” ʢϨΨγʔίʔυͷδϨϯϚʣ –ʰϨΨγʔίʔυվળΨΠυʱ

Slide 12

Slide 12 text

• ೔ʑɺอकɾ֦ுΛ͍ͯ͘͠αʔϏεͷίʔ υϕʔε • อकɾ֦ுʹ͋ͨΓɺਖ਼͘͠ಈ͘͜ͱ͕ٻ ΊΒΕΔ • →ʮϨΨγʔίʔυʯͷࠀ෰ʹର͢ΔϞν ϕʔγϣϯ ՝୊ײ

Slide 13

Slide 13 text

อकɾ֦ுʹର͢Δཁٻ 1. طଘͷৼΔ෣͍Λม͑ͳ͍͜ͱ 2. طଘͷৼΔ෣͍Λมߋͯ͠ਖ਼͘͠ಈ͘͜ ͱ 3. ৽نͷৼΔ෣͍Λ௥Ճͯ͠ਖ਼͘͠ಈ͘͜ ͱ େ͖͘3छྨͷཁٻͱͱ΋ʹ೔ʑͷ։ൃΛ͠ ͍ͯΔɻ

Slide 14

Slide 14 text

- อकɾ֦ுʹର͢Δཁٻɿࣄྫ - 1. طଘͷৼΔ෣͍Λม͑ͳ͍ • ʮPHPɾCakePHPόʔδϣϯΞοϓʯ • 2016೥͔Β࢝·ͬͨPHPɾCakePHPͷ όʔδϣϯΞοϓσʔτ • PHP5.3 -> PHP7.1 • CakePHP2.3~2.10 -> CakePHP2.10(2.x ࠷৽) • 2018೥5݄ʹ׬ྃ

Slide 15

Slide 15 text

• 60ສళฮͷγϣοϓ͕ར༻͍ͯ͠ΔαʔϏ εͷݴޠɾϑϨʔϜϫʔΫͷόʔδϣϯΞο ϓ • ίʔυϕʔεશମʹର͢ΔӨڹൣғ • PHPɾCakePHPͷόʔδϣϯΛ҆શʹ্͛ Δඞཁੑ - อकɾ֦ுʹର͢Δཁٻɿ1. طଘͷৼΔ෣͍Λม͑ͳ͍ - PHP/CakePHPόʔδϣϯΞοϓ

Slide 16

Slide 16 text

• ςετΧόϨοδΛ্͛ͯɺอޢൣғΛ޿ ͛Δ • ControllerϨϕϧ͔Β޿ൣғͷΧόϨοδ Λर͍ͬͯ͘ - PHP/CakePHPόʔδϣϯΞοϓ - ςετʹΑ࣮ͬͯݱ͍ͨ͜͠ͱ

Slide 17

Slide 17 text

• ʮޙ෷͍ܾࡁϦϓϨΠεʯ • BASE͸ओʹҎԼ5ͭͷܾࡁํ๏ΛରԠ • ΫϨδοτΧʔυܾࡁɺίϯϏχܾࡁɾPay-easyɺۜ ߦৼࠐɺޙ෷͍ܾࡁɺΩϟϦΞܾࡁ • ʮޙ෷͍ܾࡁʯͷϦϓϨΠεΛ࣮ࢪɻ IUUQTCBTFVKQ - อकɾ֦ுʹର͢Δཁٻɿࣄྫ - 2. طଘͷৼΔ෣͍Λมߋ͢Δ

Slide 18

Slide 18 text

• Ϣʔβʔͷ͓͕ۚؔΘΔͷͰɺԿࣄ΋ͳ͘ ҆શʹ׬਱͢Δඞཁੑ • طଘίʔυͷৼΔ෣͍Λཧղ্ͨ͢͠Ͱख ΛೖΕΔ͜ͱ͕ٻΊΒΕΔɻ • طଘͷৼΔ෣͍Λอޢ্ͨ͠ͰɺϦϑΝΫ λϦϯάɾৼΔ෣͍௥ՃΛߦ͍͍ͨɻ - ޙ෷͍ܾࡁϦϓϨΠε - ςετʹΑ࣮ͬͯݱ͍ͨ͜͠ͱ

Slide 19

Slide 19 text

• ʮYELL BANKʢΤʔϧόϯΫʣʯ • γϣοϓͷ௅ઓΛԠԉ͢ΔࢿۚௐୡαʔϏ ε IUUQTUIFCBTFJOZFMMCBOL - อकɾ֦ுʹର͢Δཁٻɿࣄྫ - 3. ৽نͷৼΔ෣͍Λ௥Ճ͢Δ

Slide 20

Slide 20 text

• ओͱͳΔػೳ͸Web APIͰ࣮૷ɺBASEຊ ମͷίʔυϕʔε͔ΒΞΫηε • ʮϨΨγʔίʔυʯͱͳΒͳ͍อकੑͷ͋ ΔίʔυΛॻ͖͍ͨɻ • ૄ݁߹ͳίʔυઃܭΛਪਐ͠ɺৼΔ෣͍อ ޢΛଅਐ͢Δ - อकɾ֦ுʹର͢Δཁٻɿ৽نͷৼΔ෣͍Λ௥Ճ͢Δ - YELL BANKʢΤʔϧόϯΫʣ

Slide 21

Slide 21 text

ڞ௨తͳϞνϕʔγϣϯ • ςετΛॻ͘͜ͱʹΑͬͯɺΑΓ҆શʹγ εςϜΛѻ͍͍ͨϞνϕʔγϣϯ • ฤूͯ͠فΔʢEdit and Prayʣ • อޢͯ͠มߋ͢ΔʢCover and Modifyʣ • ૄ݁߹ͳίʔυઃܭʹ͠ɺ৽نʹϨΨγʔ ίʔυΛ࢈·ͳ͍

Slide 22

Slide 22 text

• ҆શʹαʔϏεΛอकɾ੒௕͢ΔͨΊʹɺ طଘͷৼΔ෣͍Λอূ͍ͨ͠ɻ • ৽نʹॻ͘ίʔυʹ͸อकੑΛ΋ͨͤͨ ͍ɻ • ϢχοτςετΛॻ͍͍ͯ͘ɻ 1. ·ͱΊ

Slide 23

Slide 23 text

2. طଘίʔυΛอޢ͢Δٕ๏

Slide 24

Slide 24 text

طଘίʔυΛอޢ͢Δٕ๏ • ҆શʹطଘίʔυΛѻ͍͍ͨ • ͢Ͱʹଘࡏ͢Δίʔυʹରͯ͠ৼΔ෣͍Λ อޢ͢Δ • ͦͷ্ͰɺϦϑΝΫλϦϯά͍ͯͨ͘͠Ί ͷɺϢχοτςετͷ࢖͍ํ

Slide 25

Slide 25 text

Ϣχοτςετᴈ໌ظͷϚΠϯυ • طଘίʔυʹςετ͕ͳ͍ͨΊɺϊ΢ϋ΢ ΋গͳ͍ • ʮͲ͜·Ͱςετ͢Δ͔ʯͱ͍͏໎͍͕ͭ ͖·ͱ͏ • →࠷ॳ͸ɺগ͠ա৒͔΋ͱࢥ͏͘Β͍Ͱॻ ͍͍ͯ͘ • ʮͱʹ͔͘ॻ͘ʯ͜ͱʹॏ఺

Slide 26

Slide 26 text

طଘίʔυΛอޢ͢Δٕ๏ طଘίʔυΛอޢ͢Δ2ͭͷٕ๏ 1. ࢓༷Խςετ / ௐࠪతϦϑΝΫλϦϯά 2. ϨΨγʔίʔυͷδϨϯϚͱͷ֨ಆ

Slide 27

Slide 27 text

- طଘίʔυΛอޢ͢Δٕ๏ - 1. ࢓༷Խςετ • “characterization test” • ίʔυͷطଘͷৼΔ෣͍Λ໌Β͔ʹ͢Δς ετ • ॲཧ಺Ͱૢ࡞͢Δཁૉʹର͢Δ࣮ࢪ͍ͯ͠ ͘ • Viewʹηοτ͞ΕΔ஋ • Sessionͷ஋ • Dataͷొ࿥/ߋ৽ • FUD

Slide 28

Slide 28 text

• “exploratory refactoring” • طଘίʔυʹର͢ΔཧղΛਂΊΔ • “ʮະ஌΁ͷڪΕʯΛࠀ෰͢Δ࠷ྑͷํ๏͸ɺͦͷ ίʔυʹඈͼࠐΜͰɺ͍͡Γ࢝ΊΔ͜ͱͩɻ” (ʰϨΨ γʔιϑτ΢ΣΞվળΨΠυʱ) • ཧղΛਂΊΔͨΊิॿͱͯ͠ʮ࢓༷Խςε τʯΛߦ͏ https://www.shoeisha.co.jp/book/detail/9784798145143 - طଘίʔυΛอޢ͢Δٕ๏ɿ1. ࢓༷Խςετ - ௐࠪతϦϑΝΫλϦϯά

Slide 29

Slide 29 text

1. ςετίʔυͷதͰର৅ͷίʔυΛݺͼ ग़͢ 2. ࣦഊ͢ΔͱΘ͔͍ͬͯΔද໌Λॻ͘ 3. ࣦഊͨ݁͠Ռ͔Β࣮ࡍͷৼΔ෣͍Λ֬ೝ ͢Δ 4. ίʔυ͕࣮ݱ͢ΔৼΔ෣͍Λظ଴͢ΔΑ ͏ʹɺςετΛมߋ͢Δ 5. Ҏ্ͷखॱΛ܁Γฦ͢ - طଘίʔυΛอޢ͢Δٕ๏ɿ1. ࢓༷Խςετ - ࢓༷Խςετͷखॱ

Slide 30

Slide 30 text

- 1. ࢓༷Խςετɿ࢓༷Խςετͷखॱ - 1. ςετίʔυͷதͰର৅ͷίʔυΛ ݺͼग़͢ $result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ => ‘post’] ); 1. ςετίʔυͷதͰର৅ͷίʔυΛݺͼग़͢

Slide 31

Slide 31 text

$result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ => ‘post’] ); $expected = []; $this->assertSame($expected, $this->vars); 2. ࣦഊ͢ΔͱΘ͔͍ͬͯΔද໌Λॻ͘ - 1. ࢓༷Խςετɿ࢓༷Խςετͷखॱ - 2. ࣦഊ͢ΔͱΘ͔͍ͬͯΔද໌Λॻ͘

Slide 32

Slide 32 text

$ ./Console/cake test app —-stderr Controller/SampleController PHPUnit 5.7.27 by Sebastian Bergmann and contributors. F 1 / 1 (100%) Time: 19.32 seconds, Memory: 16.00MB There was 1 failure: --- Expected +++ Actual @@ @@ -Array &0 () +Array &0 ( ‘result’ => [‘success’] ) 3. ࣦഊͨ݁͠Ռ͔Β࣮ࡍͷৼΔ෣͍Λ֬ೝ͢Δ - 1. ࢓༷Խςετɿ࢓༷Խςετͷखॱ - 3. ࣦഊͨ݁͠Ռ͔Β࣮ࡍͷৼΔ෣͍Λ ֬ೝ͢Δ

Slide 33

Slide 33 text

$result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ => ‘post’] ); $expected = [ ‘result’ => [‘success’] ]; $this->assertSame($expected, $this->vars); 4. ίʔυ͕࣮ݱ͢ΔৼΔ෣͍Λظ଴͢ΔΑ͏ ʹɺςετΛมߋ͢Δ 5. Ҏ্ͷखॱΛ܁Γฦ͢ - 1. ࢓༷Խςετɿ࢓༷Խςετͷखॱ - 4. ίʔυ͕࣮ݱ͢ΔৼΔ෣͍Λظ଴͢ ΔΑ͏ʹɺςετΛมߋ͢Δ

Slide 34

Slide 34 text

• طଘίʔυͷৼΔ෣͍Λྫ֎ܥؚΊͯอূ ͢Δࣄ͕Մೳ • ςετΛॻ͘͜ͱͰݱࡏͷ࣮૷࢓༷Λཧղ ͢Δ͜ͱ͕Ͱ͖Δ • ҆શͳϦϑΝΫλϦϯάʹͭͳ͕Δ - طଘίʔυΛอޢ͢Δٕ๏ɿ1. ࢓༷Խςετ - ࢓༷Խςετͷޮ༻

Slide 35

Slide 35 text

1. ࢓༷ԽςετΛॻ͘ 2. ςετ͕௨Δ͜ͱΛ֬ೝ͢Δ 3. ϦϑΝΫλϦϯά͢Δ 4. ςετ͕௨Δ͜ͱΛ֬ೝ͢Δ - طଘίʔυΛอޢ͢Δٕ๏ɿ1. ࢓༷Խςετ - ҆શͳϦϑΝΫλϦϯάͷखॱ

Slide 36

Slide 36 text

- ҆શͳϦϑΝΫλϦϯάɿྫ - ର৅ϝιου /** * ར༻Մೳ͔Ͳ͏͔Λ൑ఆ͢Δ * @param int|null $user_id * @return bool */ public function canUse(int $user_id = null): bool { if (!is_null($user_id)) { $user = $this->User->find('first', [ 'conditions' => ['user_id' => $user_id] ] ); if (empty($user)) { return false; } $available = $user['User']['available']; return $available; } else { return false; } } ૣظreturn͢ΔίʔυʹϦϑΝΫλϦϯά͍ͨ͠৔߹

Slide 37

Slide 37 text

/** * @dataProvider dataProvider_canUse * @param int|null $user_id * @param bool $expected */ public function test_canUse(?int $user_id, bool $expected): void { $this->assertSame($expected, $this->User->canUse($user_id)); } public function dataProvider_canUse(): array { return [ 'user_id͕null' => [null, false], 'ଘࡏ͢Δuser_idͰར༻Մೳ' => [1, true], 'ଘࡏ͢Δuser_idͰར༻ෆՄ' => [2, false], ]; } ϦϑΝΫλϦϯάର৅ϝιουʹର͢ΔςετΛॻ͘ - ҆શͳϦϑΝΫλϦϯάɿྫ - 1. ࢓༷ԽςετΛॻ͘

Slide 38

Slide 38 text

/** * @dataProvider dataProvider_canUse * @param int|null $user_id * @param bool $expected */ public function test_canUse(?int $user_id, bool $expected): void { $this->assertSame($expected, $this->User->canUse($user_id)); } public function dataProvider_canUse(): array { return [ 'user_id͕null' => [null, false], 'ଘࡏ͢Δuser_idͰར༻Մೳ' => [1, true], 'ଘࡏ͢Δuser_idͰར༻ෆՄ' => [2, false], ]; } PHPUnitͷdataProviderΛར༻͢Δ͜ͱͰςετέʔεΛγϯϓϧʹ - ҆શͳϦϑΝΫλϦϯάɿྫ - 1. ࢓༷ԽςετΛॻ͘

Slide 39

Slide 39 text

-> % ./app/Console/cake test app User --filter test_canUse PHPUnit 5.7.27 by Sebastian Bergmann and contributors. ... 3 / 3 (100%) Time: 5.9 seconds, Memory: 14.00MB OK (3 tests, 3 assertions) - ҆શͳϦϑΝΫλϦϯάɿྫ - 2. ςετ͕௨Δ͜ͱΛ֬ೝ͢Δ

Slide 40

Slide 40 text

- ҆શͳϦϑΝΫλϦϯάɿྫ - 3. ϦϑΝΫλϦϯά͢Δ /** * ར༻Մೳ͔Ͳ͏͔Λ൑ఆ͢Δ * @param int|null $user_id * @return bool */ public function canUse(int $user_id = null): bool { if (is_null($user_id)) { return false; } $user = $this->User->find('first', [ 'conditions' => ['user_id' => $user_id] ] ); if (empty($user)) { return false; } $available = $user['User']['available']; return $available; } ૣظreturn͢ΔίʔυʹϦϑΝΫλϦϯά

Slide 41

Slide 41 text

-> % ./app/Console/cake test app User --filter test_canUse PHPUnit 5.7.27 by Sebastian Bergmann and contributors. ... 3 / 3 (100%) Time: 5.9 seconds, Memory: 14.00MB OK (3 tests, 3 assertions) - ҆શͳϦϑΝΫλϦϯάɿྫ - 4. ςετ͕௨Δ͜ͱΛ֬ೝ͢Δ

Slide 42

Slide 42 text

• ςετΛॻͨ͘ΊʹɺίʔυΛมߋ͢Δඞ ཁ͕͋Δέʔε͕͋Δ • ͍ΘΏΔɺςετ͠ʹ͍͘ίʔυʹରࡦ͕ ඞཁ - طଘίʔυΛอޢ͢Δٕ๏ - 2. ϨΨγʔίʔυͷδϨϯϚͱͷ֨ಆ

Slide 43

Slide 43 text

“ίʔυΛมߋ͢ΔͨΊʹ͸ɺςετΛ੔ උ͢Δඞཁ͕͋Δɻଟ͘ͷ৔߹͸ɺςε τΛ੔උ͢ΔͨΊʹ͸ɺίʔυΛมߋ͢ Δඞཁ͕͋Δɻ” ʢϨΨγʔίʔυͷδϨϯϚʣ –ʰϨΨγʔίʔυվળΨΠυʱ

Slide 44

Slide 44 text

• ςετ͕ͳ͍ίʔυ͸ɺςετ͠ʹ͍͘ ίʔυͰ͋Δ͜ͱ͕ଟ͍ • ֎෦઀ଓΛؚΉ࣮૷ͱͷີ݁߹ • ܾࡁγεςϜɾAWS • ੹຿ͷେ͖͍ϝιου - طଘίʔυΛอޢ͢Δٕ๏ɿ2. ϨΨγʔίʔυ - ςετ͠ʹ͍͘ίʔυ

Slide 45

Slide 45 text

• ςετ͕͔͚ΔΑ͏ʹॻ͖׵͑Δ • ີ݁߹ΛMockΛࠩ͠ࠐΊΔஈ֊·Ͱղফ ͢Δ • ςετ࣌ʹMockΛࠩ͠ࠐΉ • ֎෦࿈ܞͷৼΔ෣͍ͷMockΫϥεΛ࡞੒ • ֎෦࿈ܞͳͲΛؚΉςετΛߦ͏ࡍɺ֘ ౰ΫϥεΛMockʹஔ͖׵͑Δ - طଘίʔυΛอޢ͢Δٕ๏ɿ2. ϨΨγʔίʔυ - ςετ͠ʹ͍͘ίʔυ΁ͷରࡦ

Slide 46

Slide 46 text

• σβΠϯύλʔϯͷҰͭ • ֎෦͔Βґଘؔ܎ͷ͋ΔΦϒδΣΫτΛ஫ ೖ͢Δ • ;Δ·͍ͱґଘੑղܾΛ෼཭ • https://github.com/google/guice/wiki/Motivation • Martin FowlerࢯʹΑΓఏএ͞Εͨ༻ޠ • https://www.martinfowler.com/articles/injection.html - طଘίʔυΛอޢ͢Δٕ๏ɿ2. ϨΨγʔίʔυ - Dependency Injection

Slide 47

Slide 47 text

େ͖͘3ͭͷDIͷ΍Γํ • Constructor Injection • Setter Injection • Interface Injection - Dependency Injection - DI Pattern IUUQTXXXNBSUJOGPXMFSDPNBSUJDMFTJOKFDUJPOIUNM

Slide 48

Slide 48 text

• खಈDI͔ɺDI ContainerʹΑΔࣗಈDI͔ɺঢ় گʹԠͯ͡બ୒ - Dependency Injection - DIઓུ

Slide 49

Slide 49 text

// Before public function charge($order) { $manager = new PaymentManager(); $result = $manager->charge($order); // ܾࡁγεςϜʹ௨஌ } PaymentManagerͱີ݁߹ɺ Mock΁ͷࠩ͠ସ͕͑೉͍͠ - ςετ͠ʹ͍͘ίʔυɿྫ - खಈDIͰີ݁߹Λղফ͢Δ

Slide 50

Slide 50 text

// After public function __construct($PaymentManager = null) { $this->manager = $PaymentManager ?? new PaymentManager(); } public function charge($order) { $result = $this->manager->charge($order); // ܾࡁγεςϜʹ௨஌ } Constructor Injection ίϯετϥΫλͷҾ਺Ͱ౉͢͜ͱͰɺ Mock΁ͷࠩ͠ସ͑Λ༰қʹ͢Δ - ςετ͠ʹ͍͘ίʔυɿྫ - खಈDIͰີ݁߹Λղফ͢Δ

Slide 51

Slide 51 text

// mock objectΛ࡞Δ $mock = $this->getMockBuilder(Sample::class) ->setMethods(['update']) ->getMock(); // mock objectͷϝιουͷظ଴஋ͱฦ͢஋Λఆٛ $mock->expects($this->once()) ->method('update') ->with($this->equalTo(‘param1')) ->will($this->returnValue(true); // Constructor injection͢Δ৔߹ $target = new Target($mock); IUUQTQIQVOJUEFNBOVBMFOUFTUEPVCMFTIUNM - ςετ͠ʹ͍͘ίʔυɿྫ - खಈDIͰີ݁߹Λղফ͢Δ

Slide 52

Slide 52 text

// mock objectΛ࡞Δ $mock = $this->getMockBuilder(Sample::class) ->setMethods(['update']) ->getMock(); // mock objectͷϝιουͷظ଴஋ͱฦ͢஋Λఆٛ $mock->expects($this->once()) ->method('update') ->with($this->equalTo(‘param1')) ->will($this->returnValue(true); // Constructor injection͢Δ৔߹ $target = new Target($mock); MockΦϒδΣΫτΛ࡞੒͢Δ (PHPUnit Test Doubles) https://phpunit.de/manual/6.5/en/test-doubles.html - ςετ͠ʹ͍͘ίʔυɿྫ - खಈDIͰີ݁߹Λղফ͢Δ

Slide 53

Slide 53 text

// mock objectΛ࡞Δ $mock = $this->getMockBuilder(Sample::class) ->setMethods(['update']) ->getMock(); // mock objectͷϝιουͷظ଴஋ͱฦ͢஋Λఆٛ $mock->expects($this->once()) ->method('update') ->with($this->equalTo(‘param1')) ->will($this->returnValue(true); // Constructor injection͢Δ৔߹ $target = new Target($mock); - ςετ͠ʹ͍͘ίʔυɿྫ - खಈDIͰີ݁߹Λղফ͢Δ Constructor InjectionΛߦ͏

Slide 54

Slide 54 text

• ςετ͠ʹ͍͘ίʔυͷղফʹ͕͔͔࣌ؒ Δ৔߹ • ີ݁߹Λղ͘ͷʹେ͖ͳϦϑΝΫλϦϯάΛཁ͢Δ • ґଘ͍ͯ͠ΔΫϥεͷதͰɺ࣮ࡍʹ֎෦௨৴Λߦ͏ίʔ υΛؚΉͱ͍ͬͨ৔߹ • ςετ͠ʹ͍͘Օॴʹରͯ͠ɺͲ͏खΛೖ ΕΔ͔ • runkitΛ׆༻ͯ͠ςετΛॻ͘ - طଘίʔυΛอޢ͢Δٕ๏ɿ2. ϨΨγʔίʔυ - ςετ͠ʹ͍͘ίʔυͷน

Slide 55

Slide 55 text

• runkit֦ுϞδϡʔϧ • ఆ਺ɾϢʔβʔఆٛؔ਺ ͓ΑͼϢʔβʔఆ ٛΫϥεΛมߋ͢ΔػೳΛఏڙ • ૊ΈࠐΈؔ਺ͷڍಈΛมߋ͍ͨ͠৔߹ͳͲ ʹར༻Ͱ͖Δ IUUQQIQOFUNBOVBMKBJOUSPSVOLJUQIQ - ςετ͠ʹ͍͘ίʔυͷน - runkit

Slide 56

Slide 56 text

// ର৅ؔ਺ఆٛΛॻ͖׵͑Δ $val = <<<_XML__ success __XML__; runkit_function_copy(‘curl_exec’, ‘curl_exec_org’); runkit_function_redefine(‘curl_exec’, ‘’, $val); // ςετର৅ίʔυΛ࣮ߦ $result = $this->Sample->exec(); // ॻ͖׵͑ͨؔ਺ఆٛΛ΋ͱʹ໭͢ runkit_function_remove(‘curl_exec’); runkit_function_copy(‘curl_exec_org’, ‘curl_exec’); runkit_function_remove(‘curl_exec_org’); ؔ਺ఆٛͷόοΫΞοϓΛऔΓɺظ଴͢ΔϨεϙ ϯε($val)Λฦ͢Α͏ʹ࠶ఆٛ͢Δ - ςετ͠ʹ͍͘ίʔυͷน - runkitΛ༻͍ͨςετ

Slide 57

Slide 57 text

// ର৅ؔ਺ఆٛΛॻ͖׵͑Δ $val = <<<_XML__ success __XML__; runkit_function_copy(‘curl_exec’, ‘curl_exec_org’); runkit_function_redefine(‘curl_exec’, ‘’, $val); // ςετର৅ίʔυΛ࣮ߦ $result = $this->Sample->exec(); // ॻ͖׵͑ͨؔ਺ఆٛΛ΋ͱʹ໭͢ runkit_function_remove(‘curl_exec’); runkit_function_copy(‘curl_exec_org’, ‘curl_exec’); runkit_function_remove(‘curl_exec_org’); ςετର৅ίʔυΛ࣮ߦ - ςετ͠ʹ͍͘ίʔυͷน - runkitΛ༻͍ͨςετ

Slide 58

Slide 58 text

// ର৅ؔ਺ఆٛΛॻ͖׵͑Δ $val = <<<_XML__ success __XML__; runkit_function_copy(‘curl_exec’, ‘curl_exec_org’); runkit_function_redefine(‘curl_exec’, ‘’, $val); // ςετର৅ίʔυΛ࣮ߦ $result = $this->Sample->exec(); // ॻ͖׵͑ͨؔ਺ఆٛΛ΋ͱʹ໭͢ runkit_function_remove(‘curl_exec’); runkit_function_copy(‘curl_exec_org’, ‘curl_exec’); runkit_function_remove(‘curl_exec_org’); όοΫΞοϓΛऔ͍ͬͯͨ΋ͱ΋ͱͷؔ਺ఆٛʹ ࠶ఆٛ͠௚͢ - ςετ͠ʹ͍͘ίʔυͷน - runkitΛ༻͍ͨςετ

Slide 59

Slide 59 text

• ࢖Θͳ͍ʹӽͨ͜͠ͱ͸ͳ͍ • ৽ن࣮૷ͷςετίʔυ͸ɺrunkitར༻Λ લఏͱ͠ͳ͍Α͏ʹप஌্ͨ͠Ͱ࢖༻͢Δ • PHPͷόʔδϣϯʹԠͯ͡ɺʮpeclͰͷ഑ ෍ͳͷ͔ʯ౳ར༻ํ๏͕ҟͳΔ • https://qiita.com/kunit/items/ 43ca86a461d2e5e051cf - ςετ͠ʹ͍͘ίʔυͷน - runkitར༻ͷ஫ҙ఺

Slide 60

Slide 60 text

• طଘͷৼΔ෣͍Λ࢓༷ԽςετͰอޢ͢Δ • ௐࠪతϦϑΝΫλϦϯάͰݱঢ়ͷ࣮૷Λཧղ ͢Δ • ີ݁߹Λղফͯ͠ςετΛॻ͖΍͘͢͢Δ • ղ͘ͷʹ࣌ؒͷ͔͔Δίʔυʹରͯ͠͸ runkit֦ு౳Λར༻ 2. ·ͱΊ

Slide 61

Slide 61 text

3. ϢχοτςετྔΛ૿΍͢ ࢼΈ

Slide 62

Slide 62 text

ϢχοτςετྔΛ૿΍͢ࢼΈ • ᴈ໌ظΛա͗ͨޙͷ՝୊ͱͯ͠ɺςετΛॻ ͘ਓɾॻ͔ͳ͍ਓ͕ग़ͯ͘Δ • ։ൃνʔϜͱͯ͠ɺʮϢχοτςετΛॻ͘ จԽʯ͕ඞཁ • ʮςετΛॻ͘ਓʯΛ૿΍͍ͯ͘͠

Slide 63

Slide 63 text

–ΫϦεɾόʔνϟϧஶʰϨΨγʔιϑτ΢ΣΞվળΨΠυʱ “ίʔυ͕ϨΨγʔʹʢͱ͍͏ͷ͸ɺେ ͬ͟ͺʹݴͬͯɺอक͕ࠔ೉ʹʣͳΔʹ ͸ɺଟ͘ͷཧ༝͕͋Γ·͕͢ɺ΄ͱΜͲ ͷݪҼ͸ɺٕज़Ͱ͸ͳ͘ਓؒʹؔ܎ͯ͠ ͍·͢ɻ” https://www.shoeisha.co.jp/book/detail/9784798145143

Slide 64

Slide 64 text

ςετΛ૿΍্͢Ͱͷน • ςετΛॻ͍ͨ͜ͱ͕ͳ͍ͱɺ࠷ॳͷҰา ͕౿Έग़ͮ͠Β͍ • ͏·͍͔͘ͳ͍ͱ͖ͷɺτϥϒϧγϡʔςΟ ϯάʹ΋͕͔͔࣌ؒΔ

Slide 65

Slide 65 text

ରࡦɿςετΛॻ͘োนΛԼ͛Δ • Ϣχοτςετʹ͍ͭͯͷ஌ݟڞ༗ • ࣾ಺ϢχοτςετϋϯζΦϯͷ։࠵ • CakePHPࣗମͷBug Fix • ςετΛॻ͖΍͍͢࢓૊ΈΛ࡞Δ

Slide 66

Slide 66 text

Ϣχοτςετʹ͍ͭͯͷ஌ݟڞ༗ ʮࠔͬͨ͜ͱɺղܾͨ͜͠ͱʯΛυΩϡϝϯτͰڞ༗

Slide 67

Slide 67 text

Ϣχοτςετʹ͍ͭͯͷ஌ݟڞ༗ • Ϣχοτςετͷॻ͖ํɾ஫ҙ఺ʹ͍ͭͯ ·ͱΊΔυΩϡϝϯτ • ֤ࣗ஌ݟΛखʹೖΕͨਓ͕௥ه͍ͯ͘͠ • ςετʹؔ͢Δ࿩Λ͢Δslack channelͷ༻ ҙ

Slide 68

Slide 68 text

ࣾ಺ϢχοτςετϋϯζΦϯ by @tenkoma

Slide 69

Slide 69 text

CakePHPࣗମͷBugFix IUUQTEFWCMPHUIFCBTFJOFOUSZ CakePHPຊମ΁ͷContribute

Slide 70

Slide 70 text

ςετΛॻ͖΍͍͢࢓૊Έ • αʔϏεڞ༻ͷςετεΠʔτϓϥάΠϯ • ϑΟΫενϟػߏΛ֦ு • άϩʔόϧม਺؅ཧ • PHPUnit7.xܥػೳͷόοΫϙʔτ • ʮassertSameͷdiff͕ݟ΍͘͢͢ΔʯͳͲ

Slide 71

Slide 71 text

ςετΛॻ͖΍͍͢࢓૊Έɿར఺ • Ϣχοτςετʹ͓͍ͯɺ๨Ε͕ͪͳલॲ ཧɾޙॲཧͷڞ௨Խ • ֤ςετέʔε࣮૷ऀͷهड़ྔ͕ݮΔ͜ͱͰɺ ςετͷෛ୲ΛͳΔ΂͘ݮΒ͢

Slide 72

Slide 72 text

• ϢχοτςετΛॻ͘จԽΛৢ੒͢Δ • ஌ݟڞ༗ɾ࢓૊ΈʹΑΔԉॿʹΑͬͯɺς ετΛॻ͘োนΛԼ͛Δ 3. ·ͱΊ

Slide 73

Slide 73 text

4. Ϣχοτςετ૿Ճʹ͓͚ Δ՝୊ͱରࡦ

Slide 74

Slide 74 text

Ϣχοτςετ૿Ճʹ͓͚Δ՝୊ͱରࡦ • ഁ୼͠΍͍͢ςετέʔεʹର͢Δରࡦ • ςετίʔυͷϦϑΝΫλϦϯά

Slide 75

Slide 75 text

• ςετέʔεͷ਺͕૿͑Δʹ࿈Εͯɺʮ৮ͬ ͍ͯͳ͍Օॴͷςετ͕མͪΔʯέʔεͷ૿ Ճɻ • ʮϩʔΧϧͰ͸௨Δ͕ɺCI؀ڥͰ͸མͪ Δʯͱ͍͏έʔε΋ൃੜ͢Δ • ମݧͱͯ͠ɺʮςετ͕ো֐෺ʯʹͳΔ - Ϣχοτςετ૿Ճʹ͓͚Δ՝୊ͱରࡦ - ՝୊ɿഁ୼͠΍͍͢ςετ

Slide 76

Slide 76 text

ഁ୼͠΍͍͢ςετྫ • ଞςετέʔεͷӨڹ • ֎෦ཁҼʹӨڹΛड͚Δ • ϥϯμϜੑʹґଘ • FixtureͷมԽʹහײʹམͪΔςετ

Slide 77

Slide 77 text

- ഁ୼͠΍͍͢ςετྫ - ଞςετέʔεͷӨڹ • timecopͳͲޙॲཧͰͷย෇͚͕ඞཁͳ΋ͷ ͕ෆ଍͍ͯ͠Δ • τϥϯβΫγϣϯ͕commit͞Ε͍ͯͳ͍ ίʔυʹର͢Δςετέʔε

Slide 78

Slide 78 text

- ഁ୼͠΍͍͢ςετྫ - ֎෦ཁҼͷมԽʹӨڹ͞ΕΔςετ // test༻CloudSearchʹ઀ଓ͢Δ $search = CloudSearchWrapper::factory(); $search->conditions() ->keyword(‘test’, ‘title’) ->sort(‘list_order asc’); // test༻CloudSearchʹσʔλొ࿥ $search->documentBatch($this->addJson()); // σʔλొ࿥͞ΕΔ·Ͱ͙͢ʹݕࡧͰ͖ͳ͍ͷͰɺ଴ͭ sleep(3); // ݕࡧ࣮ߦ $result = $search->search($search->conditions()->query()); ωοτϫʔΫঢ়گʹґଘͯ͠མͪΔ

Slide 79

Slide 79 text

$val = mt_rand(0, 100); $result = $this->Sample->exec($val); $this->assertTrue($result); “0”͕ग़ͨͱ͖͚ͩམͪΔ - ഁ୼͠΍͍͢ςετྫ - ϥϯμϜੑʹґଘ

Slide 80

Slide 80 text

$data = [‘name’ => ‘hogehoge’]; $result = $this->Sample->saveSample($data); $expected = [ ‘id’ => 1, ‘name’ => ‘hogehoge’, ]; $data = ClassRegistry::init(‘Sample’)->find(‘first’, [ ‘conditions’ => [‘name’ => ‘hogehoge’] ]; $this->assertSame($expected, $data); Sample modelʹରԠ͢ΔϑΟΫενϟʹɺ ϨίʔυΛೖΕΔͱɺ ɹsave࣌ͷid͕auto increment͞ΕམͪΔ - ഁ୼͠΍͍͢ςετྫ - FixtureͷมԽʹහײʹམͪΔςετ

Slide 81

Slide 81 text

• ίʔυϨϏϡʔʹΑΔݕ஌ • ςετεΠʔτ֦ுʹΑΔԉॿ - Ϣχοτςετ૿Ճʹ͓͚Δ՝୊ͱରࡦ - ରࡦɿഁ୼͠ʹ͍͘ςετ΁

Slide 82

Slide 82 text

• ςετʹର͢Δ஌ݟ͕ཷ·͖͍ͬͯͯΔ • ίʔυϨϏϡʔʹͯɺܦݧࡁΈͷʮഁ୼͠ ΍͍͢ςετʯ͕ฆΕ͍ͯͳ͍͔Λ֬ೝ͢ Δ - ରࡦɿഁ୼͠ʹ͍͘ςετ΁ - ίʔυϨϏϡʔʹΑΔݕ஌

Slide 83

Slide 83 text

• શςετέʔεͰڞ௨ͷFixureΛར༻͢Δ͜ ͱͰɺύζϧతͳFixtureʹͳͬͯ͠·͏ • ֤ςετέʔε͝ͱʹͦΕͧΕFixtureΛ༻ ҙ͢Δػߏ - ରࡦɿഁ୼͠ʹ͍͘ςετ΁ - ςετεΠʔτ֦ுʹΑΔԉॿ

Slide 84

Slide 84 text

- ςετεΠʔτ֦ுʹΑΔԉॿɿྫ - CakePHP2Ͱͷ֦ுྫʢ1ʣ class UserTest extends AppTestCase { public $fixtures = [ 'app.user', ]; public $autoFixtures = false; public function test_canUser_ར༻ՄೳϢʔβʔ(): void { $this->loadFixturesWithRecords([ 'User' => [ UserTestHelper::availableUser, ], ]); $this->assertTrue($this->User->canUse(1)); } }

Slide 85

Slide 85 text

- ςετεΠʔτ֦ுʹΑΔԉॿɿྫ - CakePHP2Ͱͷ֦ுྫʢ1ʣ class UserTest extends AppTestCase { public $fixtures = [ 'app.user', ]; public $autoFixtures = false; public function test_canUser_ར༻ՄೳϢʔβʔ(): void { $this->loadFixturesWithRecords([ 'User' => [ UserTestHelper::availableUser, ], ]); $this->assertTrue($this->User->canUse(1)); } } CakePHPͷCakeTestCaseΛ֦ுɻ ඞཁͳςʔϒϧɾϨίʔυΛςετέʔε಺Ͱload͢Δ

Slide 86

Slide 86 text

- ςετεΠʔτ֦ுʹΑΔԉॿɿྫ - CakePHP2Ͱͷ֦ுྫʢ1ʣ 1, 'name' => 'hogehuga', 'available' => 1, 'created' => '2018-12-15 15:30:00', 'modified' => '2018-12-15 15:30:00', ]; } ςετέʔε͝ͱʹඞཁͳϨίʔυঢ়ଶΛఆٛ

Slide 87

Slide 87 text

- ςετεΠʔτ֦ுʹΑΔԉॿɿྫ - CakePHP2Ͱͷ֦ுྫʢ2ʣ class UserTest extends AppTestCase { public $fixtures = [ 'app.user', ]; public $autoFixtures = false; public function test_canUser_ར༻ՄೳϢʔβʔ(): void { $this->loadFixturesWithRecords([ 'User' => ‘User/User.php’, ]); $this->assertTrue($this->User->canUse(1)); } } ϑΝΠϧͰςετέʔεʹඞཁͳϨίʔυΛࢦఆ͢Δ

Slide 88

Slide 88 text

- ςετεΠʔτ֦ுʹΑΔԉॿɿྫ - CakePHP2Ͱͷ֦ுྫʢ2ʣ 1, 'available' => 1, ] ]; ςετέʔεʹͱͬͯ໌ࣔతʹඞཁͳΧϥϜͷΈ஋Λࢦఆ͢Δɻ ࢦఆ͍ͯ͠ͳ͍ΧϥϜ͸ɺςετ࣮ߦ࣌ʹfzaninotto/Fakerʹ ΑΓμϛʔͷ஋Λࣗಈઃఆ IUUQTHJUIVCDPNG[BOJOPUUP'BLFS

Slide 89

Slide 89 text

• શςετέʔεڞ௨తͰ͸ͳ͍͕ɺ౰֘ςε τέʔεͰ͸ඞཁͳϨίʔυͷࢦఆ͕༰қ ͱͳͬͨ • ύζϧతͳϑΟΫενϟͷෳࡶԽΛճආͰ ͖Δ - ରࡦɿഁ୼͠ʹ͍͘ςετ΁ - ςετέʔε͝ͱͷFixtureͷར఺

Slide 90

Slide 90 text

• ࠓճͷ࢓༷ԽςετͰ͸ɺʮطଘͷৼΔ෣͍ʯΛ޿ൣғ Ͱอޢͨ͠ • ޿͍͕Ώ͑ʹɺςετ͕ର৅Ϋϥε͔Βԕ͍৔ॴ͕ݪҼ Ͱམͪͨࡍɺಛఆ͕೉͍͠ • “ςετ͕ςετର৅͔Β཭ΕΕ͹཭ΕΔ΄Ͳɺςετͷࣦഊ͕ԿΛҙ ຯ͢Δ͔ͷ൑அ͕೉͘͠ͳΓ·͢ɻ“ʢʰϨΨγʔίʔυվળΨΠ υʱʣ • ςετ΋ϝϯςφϯεର৅ͱͯ͠खΛೖΕଓ͚Δඞཁੑ - Ϣχοτςετ૿Ճʹ͓͚Δ՝୊ͱରࡦ - ՝୊ɿςετίʔυͷϦϑΝΫλϦϯά

Slide 91

Slide 91 text

• ֤ࣗɺ༻ࣄ͕͋ͬͯमਖ਼͢ΔՕॴʹ͍ͭͯ ͜·ΊͳϦϑΝΫλϦϯάΛ͍ͯ͘͠ • PHPUnitͷػೳΛ༗ޮʹ࢖͏ • લॲཧɾޙॲཧͷෆ଍ͷ௥Ճ • ݟ௨͠Λ্͛ΔͨΊͷςετϔϧύʔԽ • ෆཁͳςετέʔεͷ࡟আ - ՝୊ɿςετίʔυͷϦϑΝΫλϦϯά - ରࡦɿςετίʔυͷϦϑΝΫλϦϯά

Slide 92

Slide 92 text

• Ϣχοτςετྔ͕૿͑Δ͜ͱͰɺڠௐ͠ ͯഁ୼͠΍͘͢ͳΔ • ίʔυϨϏϡʔɾςετεΠʔτʹΑΔճ ආ • ςετίʔυΛϝϯςφϯεର৅ͱͯ͠Ϧ ϑΝΫλϦϯά͍ͯ͘͠ 4. ·ͱΊ

Slide 93

Slide 93 text

5. ςετ͕ͳ͍ίʔυΛ ࠶ੜ࢈͠ͳ͍ٕ๏

Slide 94

Slide 94 text

ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͠ͳ͍ٕ๏ • ৽نʹ௥Ճ͞ΕΔίʔυʹςετ͕ͳ͍৔ ߹ɺʮϨΨγʔίʔυʯ͕ੜ·Εଓ͚ͯ͠ ·͏ • ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͠ͳ͍ඞཁੑ

Slide 95

Slide 95 text

ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͞ΕΔཧ༝ • ʮςετΛॻ͘ͷ͕ਏ͍ʯঢ়گ • →ςετΛॻ͘ͷ͕ਏ͍ίʔυઃܭʹͳͬͯ ͍ΔՄೳੑ • →ϓϩμΫγϣϯίʔυΛɺςετ͕ॻ͖ ΍͍͢ઃܭʹ͍ͯ͘͠ඞཁ͕͋Δ

Slide 96

Slide 96 text

- ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͞ΕΔཧ༝ - ςετΛॻ͘ͷ͕ਏ͍ࣄྫ • طଘॲཧʹ੹຿Λ௥Ճͯ͠͠·͏ • طଘΫϥε΁ͷprivateϝιου௥Ճ • ֎෦ཁૉʹରͯ͠ີ݁߹ • ֎෦APIɾϝʔϧɾSlack ..etc • ੹຿ͷେ͖͍Ϋϥεɾϝιου • ҰͭͷϝιουʹॲཧΛ٧ΊࠐΜͰ͠·͏

Slide 97

Slide 97 text

ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͠ͳ͍ٕ๏ ࠶ੜ࢈͠ͳ͍ͨΊʹਐΊΔ̎ͭͷΞϓϩʔν 1. UNIX఩ֶ͔ΒֶͿ 2. ςετۦಈ։ൃ

Slide 98

Slide 98 text

• ιϑτ΢ΣΞ։ൃʹؔ͢ΔจԽతͳنൣͱ ఩ֶతΞϓϩʔνͷ·ͱ·ΓͷҰͭ • ಛʹೋͭͷΞϓϩʔνΛҙࣝ 1. “ͻͱͭͷ͜ͱΛ͏·͘΍Ε” 2. “Ͱ͖ΔݶΓૣ͘ݪܕʢϓϩτλΠϓʣ Λ࡞Εɻ” - ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͠ͳ͍ٕ๏ - 1. UNIX఩ֶ͔ΒֶͿ

Slide 99

Slide 99 text

– μάϥεɾϚΩϧϩΠɺUNIXͷ࢛൒ੈل “͜Ε͕UNIXͷ఩ֶͰ͋Δɻ Ұͭͷ͜ͱΛߦ͍ɺ·ͨͦΕΛ͏·͘΍ΔϓϩάϥϜΛॻ͚ ڠௐͯ͠ಈ͘ϓϩάϥϜΛॻ͚ɻ ඪ४ೖग़ྗʢςΩετɾετϦʔϜʣΛѻ͏ϓϩάϥϜΛॻ ͚ɻඪ४ೖग़ྗ͸ීวతΠϯλʔϑΣʔεͳͷͩɻ ” IUUQTKBXJLJQFEJBPSHXJLJ6/*9&#&"%"

Slide 100

Slide 100 text

- ʮςετ͕ॻ͖΍͍͢ʯίʔυઃܭ΁ɿ1. UNIX఩ֶ͔ΒֶͿ - 1. “ͻͱͭͷ͜ͱΛ͏·͘΍Ε” • Ұͭͷ͜ͱʹूத͢Δ͜ͱͰෆཁͳ෦෼Λ ແ͍ͯ͘͘͠ɻ • ੹຿͕খ͍͞୯Ұ෦඼Λڠௐͯ͠ಈ͔͢

Slide 101

Slide 101 text

– ϚΠΫɾΨϯΧʔζɺUNIX఩ֶ “Build a prototype as soon as possible.” ʢͰ͖ΔݶΓૣ͘ݪܕʢϓϩτλΠϓʣΛ࡞Εɻʣ IUUQTKBXJLJQFEJBPSHXJLJ6/*9&#&"%"

Slide 102

Slide 102 text

- ʮςετ͕ॻ͖΍͍͢ʯίʔυઃܭ΁ɿUNIX఩ֶ͔ΒֶͿ - 2. “Ͱ͖ΔݶΓૣ͘ݪܕʢϓϩτλΠϓʣΛ࡞Ε” • ૣ͘࠷௿ݶͷظ଴஋͕ಘΒΕΔ΂ͨॻ͖ͷ ࣮૷Λߦ͏ • ࣮૷ମݧ͔Βઃܭʹର͢ΔϑΟʔυόοΫ Λಘͯվળ͍ͯ͘͠ • →ʮςετۦಈ։ൃʯ

Slide 103

Slide 103 text

• “Test-Driven Development: TDD” • ࣗಈԽ͞ΕͨςετʹΑͬͯ։ൃΛਪ͠ਐΊ Δ • Kent Beck ஶʰςετۦಈ։ൃʱ • https://shop.ohmsha.co.jp/shopdetail/000000004967/ - ςετ͕ͳ͍ίʔυΛ࠶ੜ࢈͠ͳ͍ٕ๏ - 2. ςετۦಈ։ൃ

Slide 104

Slide 104 text

1. ·ͣ͸ςετΛ̍ͭॻ͘ 2. ͢΂ͯͷςετΛ૸Βͤɺ৽͍͠ςετͷ ࣦഊΛ֬ೝ͢Δ 3. খ͞ͳมߋΛߦ͏ 4. ͢΂ͯͷςετΛ૸Βͤɺશͯ੒ޭ͢Δ͜ ͱΛ֬ೝ͢Δ 5. ϦϑΝΫλϦϯάΛߦͬͯॏෳΛআڈ͢Δ - ςετۦಈ։ൃ - ςετۦಈ։ൃͷϦζϜ IUUQTTIPQPINTIBDPKQTIPQEFUBJM

Slide 105

Slide 105 text

• ౎౓ಈ࡞͢ΔίʔυʹΑͬͯɺઃܭ൑அʹର͢ ΔϑΟʔυόοΫ͕ಘΒΕΔ • ϦϑΝΫλϦϯάʹର͢Δಈ࡞֬ೝͷলྗԽ ͞ΕΔ • ςετ͕ۦಈ͢ΔͨΊɺςετ͕ॻ͖΍͍͢ઃ ܭʹͳΓ΍͍͢ɻڽॖ౓͕ߴ݁͘߹౓͕௿͍ ෦඼Ͱͷߏ੒ͱͳΔ - ςετۦಈ։ൃ - ςετۦಈ։ൃͷޮ༻

Slide 106

Slide 106 text

ৄࡉ͸ɺ΃ͪ͜Μઋ୆(1/26)ʹͯ IUUQTQIQDPOTFOEBJOFU ʮςετΛॻ͘ͷ͕ਏ͘ͳΒͳ͍ςετۦಈ։ൃͷΞϓϩʔνʯ

Slide 107

Slide 107 text

• ςετΛॻ͘ͷ͕ਏ͍ίʔυઃܭΛճආ͢ Δ • “Ұͭͷ͜ͱΛ͏·͘΍Ε”Λҙࣝ͢Δ • ςετۦಈ։ൃͷΞϓϩʔνʹΑΓɺڽू ౓͕ߴ݁͘߹౓͕௿͍ίʔυઃܭΛ໨ࢦ͢ 5. ·ͱΊ

Slide 108

Slide 108 text

·ͱΊ

Slide 109

Slide 109 text

·ͱΊ • ҆શʹαʔϏεΛ੒௕ͤ͞ΔͨΊʹςετΛ ׆༻͢Δ • طଘͷৼΔ෣͍Λ࢓༷ԽςετͰอޢ͢Δ • ςετ͕͠΍͍͢ίʔυઃܭʹ͢Δ͜ͱͰɺ ʮϨΨγʔίʔυʯΛ࠶ੜ࢈͠ͳ͍

Slide 110

Slide 110 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ Kazuki Higashiguchi / BASE, Inc.