Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPバージョンアップと決済テストを支えたユニットテスト

 PHPバージョンアップと決済テストを支えたユニットテスト

「レガシーコード改革!UT/CIでWebサービスの技術的負債を解消する取り組み」での発表資料です。

https://base.connpass.com/event/94476/

Kazuki Higashiguchi

August 07, 2018
Tweet

More Decks by Kazuki Higashiguchi

Other Decks in Technology

Transcript

  1. ࣗݾ঺հ • ౦ޱ ࿨ᏻ @Khigashiguchi • BASE, Inc / BASE

    Product Division • Server Side EngineerʢPHP / Goʣ • Works • EίϚʔεϓϥοτϑΥʔϜ ʮBASEʯͷܾࡁྖҬ • PHP/CakePHPͷόʔδϣϯΞοϓ
  2. ϨΨγʔࠀ෰ͷʮ͖͔͚ͬʯ • ςετΛॻ͘͜ͱʹΑͬͯɺΑΓ҆શʹγ εςϜΛѻ͍͍ͨϞνϕʔγϣϯ • ฤूͯ͠فΔʢEdit and Prayʣ • อޢͯ͠มߋ͢ΔʢCover

    and Modifyʣ • PHPόʔδϣϯΞοϓPJɾܾࡁؔ࿈PJͳ ͲʹΑΔϢχοτςετͷॆ࣮Խ • ʢܾࡁؔ࿈PJ=τʔΫϯܾࡁରԠɾܾࡁϦϓϨΠε… etcʣ
  3. ʮௐࠪతϦϑΝΫλϦϯάʯ • “exploratory refactoring” • طଘίʔυʹର͢ΔཧղΛਂΊΔ • “ʮະ஌΁ͷڪΕʯΛࠀ෰͢Δ࠷ྑͷํ๏͸ɺͦͷ ίʔυʹඈͼࠐΜͰɺ͍͡Γ࢝ΊΔ͜ͱͩɻ” (ʰϨΨ

    γʔιϑτ΢ΣΞվળΨΠυʱ) • ཧղΛਂΊΔͨΊิॿͱͯ͠ʮ࢓༷Խςε τʯΛߦ͏ɻ  https://www.shoeisha.co.jp/book/detail/9784798145143
  4. ࢓༷ԽςετͷਐΊํʢྫʣ $result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ =>

    ‘post’] ); $expected = []; $this->assertSame($expected, $this->vars); 2. ࣦഊ͢ΔͱΘ͔͍ͬͯΔද໌Λॻ͘
  5. ࢓༷ԽςετͷਐΊํʢྫʣ $ ./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. ࣦഊͨ݁͠Ռ͔Β࣮ࡍͷৼΔ෣͍Λ֬ೝ͢Δ
  6. ࢓༷ԽςετͷਐΊํʢྫʣ $result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ =>

    ‘post’] ); $expected = [ ‘result’ => [‘success’] ]; $this->assertSame($expected, $this->vars); 4. ίʔυ͕࣮ݱ͢ΔৼΔ෣͍Λظ଴͢ΔΑ͏ ʹɺςετΛมߋ͢Δ 5. Ҏ্ͷखॱΛ܁Γฦ͢
  7. ີ݁߹Λղফ͢Δྫ // Before public function charge($order) { $manager = new

    PaymentManager(); $result = $manager->charge($order); // ܾࡁγεςϜʹ௨஌ } PaymentManagerͱີ݁߹ɺ Mock΁ͷࠩ͠ସ͕͑೉͍͠ɻ
  8. ີ݁߹Λղফ͢Δྫ // After public function __construct($PaymentManager = null) { $this->manager

    = $PaymentManager ?? new PaymentManager(); } public function charge($order) { $result = $this->manager->charge($order); // ܾࡁγεςϜʹ௨஌ } Constructor Injection ίϯετϥΫλͷҾ਺Ͱ౉ͤΔΑ͏ʹ͢Δ ͜ͱͰɺMock΁ͷࠩ͠ସ͑Λ༰қʹ͢Δɻ
  9. PHPUnitͰͷMock // 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 ৄࡉ͸ɺʮPHPUnit mockʯͰݕࡧ
  10. runkitΛ༻͍ͨςετ // ର৅ؔ਺ఆٛΛॻ͖׵͑Δ $val = <<<_XML__ <response>success</response> __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)Λฦ͢Α͏ʹ࠶ఆٛ͢Δɻ
  11. runkitΛ༻͍ͨςετ // ର৅ؔ਺ఆٛΛॻ͖׵͑Δ $val = <<<_XML__ <response>success</response> __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’); ςετର৅ίʔυΛ࣮ߦ
  12. runkitΛ༻͍ͨςετ // ର৅ؔ਺ఆٛΛॻ͖׵͑Δ $val = <<<_XML__ <response>success</response> __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’); όοΫΞοϓΛऔ͍ͬͯͨ΋ͱ΋ͱͷؔ਺ఆٛʹ ࠶ఆٛ͠௚͢ɻ
  13. ֎෦ཁҼͷมԽʹӨڹ͞ΕΔςετ // 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());  ωοτϫʔΫঢ়گʹґଘͯ͠མͪΔ
  14. FixtureͷมԽʹහײʹམͪΔςετ $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͞ΕམͪΔ