Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PHPバージョンアップと決済テストを支えたユニットテスト
Search
Kazuki Higashiguchi
August 07, 2018
Technology
6
5.4k
PHPバージョンアップと決済テストを支えたユニットテスト
「レガシーコード改革!UT/CIでWebサービスの技術的負債を解消する取り組み」での発表資料です。
https://base.connpass.com/event/94476/
Kazuki Higashiguchi
August 07, 2018
Tweet
Share
More Decks by Kazuki Higashiguchi
See All by Kazuki Higashiguchi
Design of a Stateful system for Robust Deployment and Observability
hgsgtk
0
1.2k
A guide to joining operational work in your new DevOps team
hgsgtk
1
1.3k
HTTP Tunneling in Go
hgsgtk
0
1.3k
ブラウザ自動操作技術の深層へ、直接触れて学ぶ WebDriver と Chrome DevTools Protocol
hgsgtk
3
6.4k
HTTP Server on random available port in Go
hgsgtk
0
920
Agile Testingを夢見たテスト自動化 〜ATDDへの挑戦から始まる 1年間の試行錯誤〜 / dreaming agile testing at basebank
hgsgtk
14
7.6k
Create Go WebDriver client from scratch
hgsgtk
1
2.1k
PHPでWeb Driver Clientを自作する〜己の手でブラウザ操作自動化を完全理解する方法〜 / phpcon2021
hgsgtk
2
2.4k
振り返りを積み上げて自分たちのプラクティスとして昇華•体得していくための仕組みと考え方 / ScrumFestMikawa2021
hgsgtk
3
2.4k
Other Decks in Technology
See All in Technology
Python(PYNQ)がテーマのAMD主催のFPGAコンテストに参加してきた
iotengineer22
0
470
信頼性に挑む中で拡張できる・得られる1人のスキルセットとは?
ken5scal
2
530
これまでの計測・開発・デプロイ方法全部見せます! / Findy ISUCON 2024-11-14
tohutohu
3
370
B2B SaaSから見た最近のC#/.NETの進化
sansantech
PRO
0
800
VideoMamba: State Space Model for Efficient Video Understanding
chou500
0
190
BLADE: An Attempt to Automate Penetration Testing Using Autonomous AI Agents
bbrbbq
0
310
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
8
870
インフラとバックエンドとフロントエンドをくまなく調べて遅いアプリを早くした件
tubone24
1
430
リンクアンドモチベーション ソフトウェアエンジニア向け紹介資料 / Introduction to Link and Motivation for Software Engineers
lmi
4
300k
SREによる隣接領域への越境とその先の信頼性
shonansurvivors
2
520
Incident Response Practices: Waroom's Features and Future Challenges
rrreeeyyy
0
160
[CV勉強会@関東 ECCV2024 読み会] オンラインマッピング x トラッキング MapTracker: Tracking with Strided Memory Fusion for Consistent Vector HD Mapping (Chen+, ECCV24)
abemii
0
220
Featured
See All Featured
Designing for Performance
lara
604
68k
A better future with KSS
kneath
238
17k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
The Invisible Side of Design
smashingmag
298
50k
KATA
mclloyd
29
14k
Building Your Own Lightsaber
phodgson
103
6.1k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Being A Developer After 40
akosma
86
590k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Six Lessons from altMBA
skipperchong
27
3.5k
What's in a price? How to price your products and services
michaelherold
243
12k
A Tale of Four Properties
chriscoyier
156
23k
Transcript
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