Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
PHPバージョンアップと決済テストを支えたユニットテスト
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Kazuki Higashiguchi
August 07, 2018
Technology
5.9k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
PHPバージョンアップと決済テストを支えたユニットテスト
「レガシーコード改革!UT/CIでWebサービスの技術的負債を解消する取り組み」での発表資料です。
https://base.connpass.com/event/94476/
Kazuki Higashiguchi
August 07, 2018
Transcript
66 slides
PHPόʔδϣϯΞοϓͱ ܾࡁϦϓϨΠεΛࢧ͑ͨ Ϣχοτςετ 2018/8/7 (Tue) ϨΨγʔίʔυվֵʂUT/CIͰWebαʔϏεͷٕज़తෛ࠴Λղফ͢ΔऔΓΈ BASEגࣜձࣾ ౦ޱᏻ @Khigashiguchi
ʮϨΨγʔίʔυʯͱ IUUQTCBTFDPOOQBTTDPNFWFOU
–ϚΠέϧɾCɾϑΣβʔζஶʰϨΨγʔίʔυվળΨΠυʱ “ϨΨγʔίʔυͱɺ ୯ʹςετͷͳ͍ίʔυͰ͢ɻ” https://www.shoeisha.co.jp/book/detail/9784798116839
BASEʹͱͬͯͷ ʮϨΨγʔίʔυվֵʯ • ςετ͕ͳ͍ίʔυʹରͯ͠Ϣχοτςε τΛॻ͍͍ͯ͘
“ίʔυΛมߋ͢ΔͨΊʹɺςετΛ උ͢Δඞཁ͕͋Δɻଟ͘ͷ߹ɺςε τΛඋ͢ΔͨΊʹɺίʔυΛมߋ͢ Δඞཁ͕͋Δɻ” ʢϨΨγʔίʔυͷδϨϯϚʣ –ʰϨΨγʔίʔυվળΨΠυʱ
BASEʹͱͬͯͷ ʮϨΨγʔίʔυվֵʯ • ςετ͕ͳ͍ίʔυʹରͯ͠Ϣχοτςε τΛॻ͍͍ͯ͘ • ʮϨΨγʔίʔυͷδϨϯϚʯʹటषཱ͘ ͔ͪ͏
࣍ • ࣗݾհ • BASEͷഎܠ • Ϣχοτςετͷʮ͍ํʯ • Ϣχοτςετͷʮ՝ʯͱʮରࡦʯ •
͜Ε͔Βͷʮ՝ʯ • ·ͱΊ
ࣗݾհ • ౦ޱ ᏻ @Khigashiguchi • BASE, Inc / BASE
Product Division • Server Side EngineerʢPHP / Goʣ • Works • EίϚʔεϓϥοτϑΥʔϜ ʮBASEʯͷܾࡁྖҬ • PHP/CakePHPͷόʔδϣϯΞοϓ
PHPΧϯϑΝϨϯεؔ2018ʹͯɺ ςετʹ͍ͭͯͷʮݸਓతʯͷ IUUQTTQFBLFSEFDLDPNLIJHBTIJHVDIJUFTVUPXPTIVJUBLPUPLBOBJFOTJOJBLBUFTVUPXPTIV LFSVZPVOJOBSVNBUFZBUVUBLPUPBUQIQLBOIVBSFOTVHVBOYJ
BASEͷϛογϣϯͱࣄۀ ՁͷަΛΑΓγϯϓϧʹ͠ɺ ੈքதͷਓʑ͕࠷దͳܦࡁ׆ಈΛߦ͑ΔΑ͏ʹ͢Δ MISSION ແྉʗ؆୯ͳωοτγϣοϓ࡞ͷΈ ˍ ʮཉ͍͠ʯ͕ݟ͔ͭΔγϣοϐϯάΞϓϦ γϯϓϧͳΦϯϥΠϯܾࡁιϦϡʔγϣϯ ɾ QRίʔυͳͲγϯϓϧͳܾࡁखஈ
※PAYגࣜձࣾʢBASEגࣜձࣾ100%ࢠձࣾʣʹͯఏڙ
BASEࣄۀ - ֓ཁ ߪೖऀ͚ͷγϣοϓ͕ू·Δγϣοϐϯά Ϟʔϧɻ EίϚʔεϓϥοτϑΥʔϜʮBASEʯ EίϚʔεϓϥοτϑΥʔϜʮBASEʯ BASEੈͷதͷʮՁͷަΛΑΓγϯϓϧʹʯ͢ΔͨΊͷ ECϓϥοτϑΥʔϜࣄۀͰ͢ ωοτγϣοϓ࡞αʔϏεʮBASEʯ
γϣοϐϯάΞϓϦʮBASEʯ ళฮʗൢചऀ͚ͷγϯϓϧɾֹ݄ແྉͷ γϣοϓ࡞ιϦϡʔγϣϯɻ
BASEͷഎܠ
BASEͷഎܠ(~2017) • 6(2012ϦϦʔε) • ଟ͘ͷαʔϏεͰPHP5.3/CakePHP2.3Λ ར༻ • ςετ͕ॻ͔Ε͍ͯΔαʔϏε͕গͳ͔ͬ ͨ
ϨΨγʔࠀͷʮ͖͔͚ͬʯ • ςετΛॻ͘͜ͱʹΑͬͯɺΑΓ҆શʹγ εςϜΛѻ͍͍ͨϞνϕʔγϣϯ • ฤूͯ͠فΔʢEdit and Prayʣ • อޢͯ͠มߋ͢ΔʢCover
and Modifyʣ • PHPόʔδϣϯΞοϓPJɾܾࡁؔ࿈PJͳ ͲʹΑΔϢχοτςετͷॆ࣮Խ • ʢܾࡁؔ࿈PJ=τʔΫϯܾࡁରԠɾܾࡁϦϓϨΠε… etcʣ
ʮPHPόʔδϣϯΞοϓʯ • 2016͔Β࢝·ͬͨPHPɾCakePHPͷ όʔδϣϯΞοϓσʔτ • PHP5.3 -> PHP7.1 • CakePHP2.3~2.10
-> CakePHP2.10(2.x ࠷৽) • 20185݄ʹྃ
ৄ͘͠ɺʮBASEɹPHPΞοϓσʔτʯͰݕࡧ IUUQTEFWCMPHUIFCBTFJOFOUSZ
ʮܾࡁؔ࿈PJʯ • BASEओʹҎԼ5ͭͷܾࡁํ๏ΛରԠ • ΫϨδοτΧʔυܾࡁɺίϯϏχܾࡁɾPay-easyɺۜ ߦৼࠐɺޙ͍ܾࡁɺΩϟϦΞܾࡁ • දͷʮܾࡁϦϓϨΠεʯ • =
ޙ͍ܾࡁϦϓϨΠε IUUQTUIFCBTFJOQBZNFOUT
Ϣχοτςετͷʮ͍ํʯ
PHPΞοϓσʔτ&ςετ • 50ສళฮͷϢʔβʔͷ͍ΔαʔϏεͷ PHPɾCakePHPͷόʔδϣϯΛ҆શʹ্͛ Δ • ςετΧόϨοδΛ্͛ͯɺอޢൣғΛ ͛Δ • ControllerϨϕϧ͔ΒൣғͷΧόϨοδ
Λर͏
ܾࡁϦϓϨΠε&ςετ • ηϯγςΟϒͳܾࡁʹରͯ͠Կࣄͳ҆͘ શʹ͢Δඞཁੑ • طଘίʔυͷৼΔ͍Λཧղ͢Δ • طଘͷৼΔ͍Λอޢ͢Δ • อޢ্ͨ͠ͰɺϦϑΝΫλϦϯάɾίʔυ
ՃΛߦ͏ɻ
> طଘͷৼΔ͍Λอޢ͢Δ
ʮ༷Խςετʯ • “characterization test” • ίʔυͷطଘͷৼΔ͍Λ໌Β͔ʹ͢Δς ετ • ॲཧͰૢ࡞͢Δཁૉʹର͢Δ࣮ࢪ͍ͯ͠ ͘
• Viewʹηοτ͞ΕΔ • Sessionͷ • Dataͷొ/ߋ৽ • FUD
ʮௐࠪతϦϑΝΫλϦϯάʯ • “exploratory refactoring” • طଘίʔυʹର͢ΔཧղΛਂΊΔ • “ʮະͷڪΕʯΛࠀ͢Δ࠷ྑͷํ๏ɺͦͷ ίʔυʹඈͼࠐΜͰɺ͍͡Γ࢝ΊΔ͜ͱͩɻ” (ʰϨΨ
γʔιϑτΣΞվળΨΠυʱ) • ཧղΛਂΊΔͨΊิॿͱͯ͠ʮ༷Խςε τʯΛߦ͏ɻ https://www.shoeisha.co.jp/book/detail/9784798145143
༷Խςετͷखॱ 1. ςετίʔυͷதͰରͷίʔυΛݺͼ ग़͢ 2. ࣦഊ͢ΔͱΘ͔͍ͬͯΔද໌Λॻ͘ 3. ࣦഊͨ݁͠Ռ͔Β࣮ࡍͷৼΔ͍Λ֬ೝ ͢Δ 4.
ίʔυ͕࣮ݱ͢ΔৼΔ͍Λظ͢ΔΑ ͏ʹɺςετΛมߋ͢Δ 5. Ҏ্ͷखॱΛ܁Γฦ͢
༷ԽςετͷਐΊํʢྫʣ $result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ =>
‘post’] ); 1. ςετίʔυͷதͰରͷίʔυΛݺͼग़͢ɻ
༷ԽςετͷਐΊํʢྫʣ $result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ =>
‘post’] ); $expected = []; $this->assertSame($expected, $this->vars); 2. ࣦഊ͢ΔͱΘ͔͍ͬͯΔද໌Λॻ͘
༷ԽςετͷਐΊํʢྫʣ $ ./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. ࣦഊͨ݁͠Ռ͔Β࣮ࡍͷৼΔ͍Λ֬ೝ͢Δ
༷ԽςετͷਐΊํʢྫʣ $result = $this->testAction( ‘/samples/index’, [‘data’ => $data, ‘method’ =>
‘post’] ); $expected = [ ‘result’ => [‘success’] ]; $this->assertSame($expected, $this->vars); 4. ίʔυ͕࣮ݱ͢ΔৼΔ͍Λظ͢ΔΑ͏ ʹɺςετΛมߋ͢Δ 5. Ҏ্ͷखॱΛ܁Γฦ͢
Ϣχοτςετͷ ʮ՝ʯͱʮରࡦʯ
Ϣχοτςετͷʮ՝ʯ • ςετ͠ʹ͍͘ίʔυ • ςετΛॻ͘ਓɾॻ͔ͳ͍ਓ • ഁ͍͢͠ςετ
՝ ςετ͠ʹ͍͘ίʔυ
ςετ͠ʹ͍͘ίʔυ • ςετ͕ͳ͍ίʔυɺςετ͠ʹ͍͘ ίʔυͰ͋Δ͜ͱ͕ଟ͍ • ֎෦ଓΛؚΉ࣮ͱͷີ݁߹ • ܾࡁγεςϜɾAWS • ͷେ͖͍ϝιου
“ίʔυΛมߋ͢ΔͨΊʹɺςετΛ උ͢Δඞཁ͕͋Δɻଟ͘ͷ߹ɺςε τΛඋ͢ΔͨΊʹɺίʔυΛมߋ͢ Δඞཁ͕͋Δɻ” ʢϨΨγʔίʔυͷδϨϯϚʣ –ʰϨΨγʔίʔυվળΨΠυʱ
ςετ͠ʹ͍͘ίʔυ • ςετ͕͔͚ΔΑ͏ʹॻ͖͑Δ • ີ݁߹ΛMockΛࠩ͠ࠐΊΔஈ֊·Ͱղফ ͢Δ • ςετ࣌ʹMockΛࠩ͠ࠐΉ • ֎෦࿈ܞͳͲΛؚΉςετΛߦ͏ࡍɺ֘
ΫϥεΛMockʹஔ͖͑Δ • ֎෦࿈ܞͷৼΔ͍ΛMock͢Δ
ີ݁߹Λղফ͢Δྫ // Before public function charge($order) { $manager = new
PaymentManager(); $result = $manager->charge($order); // ܾࡁγεςϜʹ௨ } PaymentManagerͱີ݁߹ɺ Mockͷࠩ͠ସ͕͍͑͠ɻ
ີ݁߹Λղফ͢Δྫ // After public function __construct($PaymentManager = null) { $this->manager
= $PaymentManager ?? new PaymentManager(); } public function charge($order) { $result = $this->manager->charge($order); // ܾࡁγεςϜʹ௨ } Constructor Injection ίϯετϥΫλͷҾͰͤΔΑ͏ʹ͢Δ ͜ͱͰɺMockͷࠩ͠ସ͑Λ༰қʹ͢Δɻ
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ʯͰݕࡧ
ςετ͠ʹ͍͘ίʔυͷน • ςετ͠ʹ͍͘ίʔυͷղফʹ͕͔͔࣌ؒ Δ߹ • ີ݁߹Λղ͘ͷʹେ͖ͳϦϑΝΫλϦϯάΛཁ͢Δ • ґଘ͍ͯ͠ΔΫϥεͷதͰɺ࣮ࡍʹ֎෦௨৴Λߦ͏ίʔ υΛؚΉͱ͍ͬͨ߹ •
ςετ͠ʹ͍͘Օॴʹରͯ͠Ͳ͏खΛೖΕ Δ͔ɻ • runkitΛ׆༻ͯ͠ςετΛॻ͘
runkit • runkit֦ுϞδϡʔϧ • ఆɾϢʔβʔఆٛؔ ͓ΑͼϢʔβʔఆ ٛΫϥεΛมߋ͢ΔػೳΛఏڙ IUUQQIQOFUNBOVBMKBJOUSPSVOLJUQIQ
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)Λฦ͢Α͏ʹ࠶ఆٛ͢Δɻ
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’); ςετରίʔυΛ࣮ߦ
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’); όοΫΞοϓΛऔ͍ͬͯͨͱͱͷؔఆٛʹ ࠶ఆٛ͢͠ɻ
ৄ͘͠ɺ@kunit͞ΜͷQiitaهࣄΛࢀর IUUQTRJJUBDPNLVOJUJUFNTDBBEFFDG
՝ ςετΛॻ͘ਓɾॻ͔ͳ͍ਓ
–ΫϦεɾόʔνϟϧஶʰϨΨγʔιϑτΣΞվળΨΠυʱ “ίʔυ͕ϨΨγʔʹʢͱ͍͏ͷɺେ ͬ͟ͺʹݴͬͯɺอक͕ࠔʹʣͳΔʹ ɺଟ͘ͷཧ༝͕͋Γ·͕͢ɺ΄ͱΜͲ ͷݪҼɺٕज़Ͱͳ͘ਓؒʹؔͯ͠ ͍·͢ɻ” https://www.shoeisha.co.jp/book/detail/9784798145143
ςετΛॻ͘ਓɾॻ͔ͳ͍ਓ • ςετΛॻ͘ਓɾॻ͔ͳ͍ਓʹ͕͔Ε ͍ͯ͘ • ςετΛॻ͍ͨ͜ͱ͕ͳ͍ͱɺ࠷ॳͷҰา ͕౿Έग़ͮ͠Β͘ɺτϥϒϧγϡʔςΟϯ άʹ͕͔͔࣌ؒΔɻ • ςετ͕ͳ͍ίʔυ͕૿͍͑ͯ͘
ରࡦɿςετΛॻ͘োนΛԼ͛Δ • Ϣχοτςετʹ͍ͭͯͷݟڞ༗ • ࣾϢχοτςετϋϯζΦϯͷ։࠵ • ςετʹ͍ͭͯฉ͘slack channel • CakePHPࣗମͷBug
Fix • ςετΛॻ͖͍͢ΈΛ࡞Δ
Ϣχοτςετʹ͍ͭͯͷݟڞ༗ ʮࠔͬͨ͜ͱɺղܾͨ͜͠ͱʯΛυΩϡϝϯτͰڞ༗
ࣾϢχοτςετϋϯζΦϯ by @tenkoma
CakePHPࣗମͷBugFix IUUQTEFWCMPHUIFCBTFJOFOUSZ CakePHPຊମͷContribute
ςετΛॻ͖͍͢Έ • શϨϙδτϦ༻ͷςετεΠʔτϓϥάΠϯ • ϑΟΫενϟػߏΛ֦ு • άϩʔόϧมཧ • PHPUnit7.xܥػೳͷόοΫϙʔτ •
ʮassertSameͷdiff͕ݟ͘͢͢ΔʯͳͲ
ৄ͘͠ɺʮBASEɹPHPΧϯϑΝϨϯεԬʯ Ͱݕࡧ IUUQTEFWCMPHUIFCBTFJOFOUSZ
՝ ഁ͍͢͠ςετ
ഁ͍͢͠ςετ • ςετέʔεͷ͕૿͑Δʹ࿈Εͯɺʮ৮ͬ ͍ͯͳ͍Օॴͷςετ͕མͪΔʯέʔεͷ૿ Ճɻ • ମݧͱͯ͠ɺʮςετ͕োʯʹͳΔ
ഁ͍͢͠ςετ • ֎෦ཁҼͷมԽʹӨڹ͞ΕΔςετ • ϥϯμϜʹࣦഊ͢Δςετ • FixtureͷมԽʹහײʹམͪΔςετ • …etc
֎෦ཁҼͷมԽʹӨڹ͞ΕΔςετ // 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()); ωοτϫʔΫঢ়گʹґଘͯ͠མͪΔ
ϥϯμϜʹࣦഊ͢Δςετ $val = mt_rand(0, 100); $result = $this->Sample->exec($val); $this->assertTrue($result);
“0”͕ग़ͨͱ͖͚ͩམͪΔ
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͞ΕམͪΔ
ഁ͠ʹ͍͘ςετ • ςετʹର͢Δݟ͕ཷ·͖͍ͬͯͯΔ • ίʔυϨϏϡʔʹͯɺܦݧࡁΈͷʮഁ͠ ͍͢ςετʯ͕ฆΕ͍ͯͳ͍͔Λ֬ೝ͢ Δ
͜Ε͔Βͷ՝
͜Ε͔Βͷ՝ • ༷ԽςετͷϦϑΝΫλϦϯά • ഁ͠ʹ͍͘ςετΛॻ͍͍ͯ͘
༷ԽςετͷϦϑΝΫλϦϯά • ࠓճͷ༷ԽςετͰɺʮطଘͷৼΔ͍ʯΛ͍ ൣғͰอޢͨ͠ • ͍͕Ώ͑ʹɺςετ͕ରΫϥε͔Βԕ͍ॴ͕ݪҼ Ͱམͪͨࡍɺಛఆ͕͍͠ • “ςετ͕ςετର͔ΒΕΕΕΔ΄Ͳɺςετͷࣦഊ͕ԿΛҙ ຯ͢Δ͔ͷஅ͕͘͠ͳΓ·͢ɻ”ʢʰϨΨγʔίʔυվળΨΠ
υʱʣ • ςετϝϯςφϯεରͱͯ͠खΛೖΕଓ͚Δඞཁੑ
ഁ͠ʹ͍͘ςετΛॻ͍͍ͯ ͘ • ςετᴈ໌ظςετ͕গͳ͍࣌ظ • ʮͱʹ͔͘ςετΛॻ͘ʯ͜ͱʹར • ςετέʔε͕૿͖͑ͯͨ • ഁ͠ʹ͍͘ςετΛॻ͍ͯɺϝϯςφϯε
ੑΛ͍͋͛ͯ͘
·ͱΊ
·ͱΊ • ςετͷͳ͍ίʔυʹରͯ͠ςετΛॻ͍ͯ ͍ͬͨ • طଘͷίʔυΛอޢ͢ΔͨΊͷ༷Խςετ Λߦͬͨ • ٻΊΒΕΔςετίʔυ͕ঢ়گʹΑͬͯҟͳ Δɺܧଓతͳϝϯςφϯε͕ඞཁɻ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·͠ ͨɻ BASEגࣜձࣾ ౦ޱᏻ @Khigashiguchi
More Decks by Kazuki Higashiguchi
See All by Kazuki Higashiguchi
Practical Monitoring for Knative Serving / KubeCon + CloudNativeCon Japan 2025
hgsgtk
0
180
Cell-Based Architecture Design in AWS
hgsgtk
1
290
インフラコストとセキュリティ課題解決のためのリアーキテクチャリング / srekaigi2025
hgsgtk
3
9k
Design of a Stateful system for Robust Deployment and Observability
hgsgtk
0
1.6k
A guide to joining operational work in your new DevOps team
hgsgtk
1
1.7k
HTTP Tunneling in Go
hgsgtk
0
1.7k
ブラウザ自動操作技術の深層へ、直接触れて学ぶ WebDriver と Chrome DevTools Protocol
hgsgtk
3
7.1k
HTTP Server on random available port in Go
hgsgtk
0
1.2k
Agile Testingを夢見たテスト自動化 〜ATDDへの挑戦から始まる 1年間の試行錯誤〜 / dreaming agile testing at basebank
hgsgtk
13
8.6k
Other Decks in Technology
See All in Technology
Bots in Kiro Crew (One point of contact for ongoing work) | Kiro: Zero to Hero 12
inariku
PRO
1
140
SREのためのFinOps入門
muziyoshiz
3
1.6k
[NW-JAWS DAY]「うちのAWS、インターネット出られないんで」― AWS外の自社サービスをPrivateLinkでシュッと公開する方法
ykimi
2
380
AWS Quick 入門 | 目指せ Quick マスター 01
inariku
PRO
2
340
Frontier Teams — Amazon は AI で「開発のやり方」をどう変えたのか
kmotohas
0
250
AI時代における医療情報システムのセキュリティ / Security of Healthcare IT Systems in the AI Era
henryofficial
0
170
田んぼの見回りをIoTで減らしたい!水位監視から電池駆動カメラまでの試行錯誤
itosoft
1
200
AWS基盤改善を支える 私たちの理念と行動指針
kentosuzuki
0
220
Claude Codeで作ったアプリを安全に公開する/Built with Claude Japan 2026
yoshidashingo
0
250
狙われているAPIの脆弱性!今こそ手をつけるべき根本的な対策とは?
nagix
0
130
田んぼから始まる挑戦 〜新米農家の1年目〜
miu_crescent
PRO
0
360
高品質と高スピードを支える品質のシフトレフトのアプローチ
goyoki
4
1.1k
Featured
See All Featured
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.6k
Technical Leadership for Architectural Decision Making
baasie
4
640
Being A Developer After 40
akosma
PRO
92
590k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.8k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
300
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
4
1.2k
Making the Leap to Tech Lead
cromwellryan
135
10k
Everyday Curiosity
cassininazir
0
400
Paper Plane
katiecoart
PRO
6
55k
The Curse of the Amulet
leimatthew05
4
17k
Build your cross-platform service in a week with App Engine
jlugia
234
19k