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
Datetime tests with cakephp/chronos
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
hideki kinjyo
PRO
March 31, 2019
Programming
1.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Datetime tests with cakephp/chronos
#phperkaigi 2019でのLT内容です。
cakephp/chronosを利用して強いテスタビリティを手に入れる話
hideki kinjyo
PRO
March 31, 2019
More Decks by hideki kinjyo
See All by hideki kinjyo
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
190
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
230
ソースコード→AST→オペコード、の旅を覗いてみる
o0h
PRO
1
170
PCOVから学ぶコードカバレッジ #phpcon_odawara
o0h
PRO
0
370
夢の無限スパゲッティ製造機 -実装篇- #phpstudy
o0h
PRO
0
240
夢の無限スパゲッティ製造機 #phperkaigi
o0h
PRO
0
490
PHPer Book Revue 「雑に作る」 #phperkaigi
o0h
PRO
0
370
俺にも私がAIと作った オススメの個人ツールを語らせてくれ
o0h
PRO
0
73
#phperbiglt のLT
o0h
PRO
0
110
Other Decks in Programming
See All in Programming
CSC307 Lecture 17
javiergs
PRO
0
320
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
4.7k
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
230
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
250
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
140
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
150
Modding RubyKaigi for Myself
yui_knk
0
900
Spec-Driven Development with AI-Agents: From High-Level Requirements to Working Software
antonarhipov
2
470
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.2k
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
200
柔軟なPDFレイアウトエディタを支える型システム設計 — Discriminated UnionとConditional Typeの実践
minako__ph
4
1.4k
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
Featured
See All Featured
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.9k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
220
Discover your Explorer Soul
emna__ayadi
2
1.1k
Six Lessons from altMBA
skipperchong
29
4.3k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
Mobile First: as difficult as doing things right
swwweet
225
10k
Evolving SEO for Evolving Search Engines
ryanjones
0
210
HDC tutorial
michielstock
2
690
Navigating Team Friction
lara
192
16k
KATA
mclloyd
PRO
35
15k
Transcript
࣌Λࢧ͢ΔPHP #phperkaigi 2019.03.31 Hideki Kinjyo twitter: @o0h_ / github: o0h
ಥͰ͕͢
Έͳ͞Μࢥ͍·ͤΜ͔
͋ʙɺ͕࣌ؒͱ·Ε͍͍ͷʹɻ
Ͱ͢ΑͶʁ
ͦΕɺPHPͰͰ͖ΔΑʂ
ຊͷ͝հ
cakephp/chronos
ࣗݾհ • ίωώτגࣜձࣾ • αʔόʔαΠυΤϯδχΞ • ओʹCakePHPͳͲ • ࠷ۙɺ{ॳ}ॻ੶Λࣥච͠·ͨ͠ ͡Ί·ͯ͠ʂ
TL;DR • cakephp/chronos A standalone DateTime library originally based off
of Carbon • Date(calendar) / DateTimeͷศརͳॲཧΛఏڙ ͢Δ • ࣌ॲཧΛҕৡ͢Δ͜ͱͰɺ γεςϜ࣌ʹґଘ͠ͳ͍ʮݱࡏ࣌ʯΛॲཧ͕ Մೳʹ
Α͋͘Γͦ͏ͳ
དྷ݄ɺզ͕ࣾ ͕ECαΠτʮଠ ܅ͷ͓หശʯ Λ࢝Ίͯɺ7प ͩɻ ײँͷؾ࣋ͪΛ ͜Ίͨɺεϖγϟ ϧηʔϧΛΖ ͏Α ࣾͷਓ
͕ࣾɺϫλ γʹͱͬͯ ΤϞ͍ࣄΛ ͤͯ͘Εͨ ͧɻ͜Εઈ ରʹࣦഊͰ͖ ͳ͍ɺ͕Μ Δ͔͠ͳ͍ʂ ৽ೖࣾһϫλγ
͋ʙΒΑͬʂͱɻ $template = 'itsumono_hanbai_page'; if (time() >= strtotime(START_SALE_DATETIME_STR)) { $template
= 'special_taro_sale'; } render($template);
͜ΕͰɺ ʹͳͬͨΒϖʔ δ͕ΓସΘ Δɻྑ͔ͬͨɺ ྑ͍ײ͡ʹ ࣄ͕Ͱ͖ͨͧɻ ৽ೖࣾһϫλγ
͊ɺ͕Μͬ ͨͶʂ͏Ұ ਓલ͍͔ۙ ͳʁ(স)͜Εͳ ΒɺΈΜ ͳେتͼʹҧ ͍ͳ͍ɻ͠ ͘ͳΔͧʙʙʂ པΕΔઌഐ
ͱ͜ΖͰ͞ʂ ͜Εͬͯɺ ͏CI௨ͨ͠ ͔ͳʁͲ͏ͩͬ ͨʁ པΕΔઌഐ
͋ɺઌഐʂς ετͬͯ͜ͱ Ͱ͔͢ʁϩʔ ΧϧͰɺγ εςϜλΠϜ Λมߋͯ͠ಈ ࡞֬ೝ͠· ͨ͠ɻ ৽ೖࣾһϫλγ
ͰɺΉΉΉɺ ͔֬ʹςετ ίʔυɾɾɾ runkitͱ͔ೖ ΕͪΌ͍ͬͯ ͍Ͱ͔͢Ͷʁ ৽ೖࣾһϫλγ
͏Μ͏Μɺͦ ͏ͩΑͶɻͦ Μͳ࣌ʹɺͱͬ ͯศརͳ Μͷ͕͋ΔΜ ͩɻ པΕΔઌഐ
cakephp/chronos͞ʂ
৭ʑͱػೳ͕ ͋ΔΑ པΕΔઌഐ
ԼͷΒͷ ؔ৺ͱͯ͠ɺ ʮtesting aidʯػೳ͕ ʹཱͪͦ͏ͩ ͔Βɺհ͢ ΔͶɻ པΕΔઌഐ
setTestNow()
before $template = 'itsumono_hanbai_page'; if (time() >= strtotime(START_SALE_DATETIME_STR)) { $template
= 'special_taro_sale'; } render($template);
·ͣɺʮݱࡏʯʹ͍ͭͯ ͯ͢Chronosܦ༝ͰऔΓग़͢Α͏ʹॻ͖͑ΔΑ use Cake\Chronos\Chronos; $template = 'itsumono_hanbai_page'; if (Chronos::now() >=
strtotime(START_SALE_DATETIME_STR)) { $template = 'special_taro_sale'; } render($template);
͍ͭͰʹɺ ૬खํॻ͖͑ͯ͠·͓͏ use Cake\Chronos\Chronos; $template = 'itsumono_hanbai_page'; if (Chronos::now() >=
new Chronos(START_SALE_DATETIME_STR) ) { $template = 'special_taro_sale'; } render($template);
ൺֱϝιουΛ͏ͱ ܕνΣοΫͰ͖ΔͷͰɺ͓ΈͰɻ use Cake\Chronos\Chronos; $template = 'itsumono_hanbai_page'; if (Chronos::now()->gte(new Chronos(START_SALE_DATETIME_STR))
) { $template = 'special_taro_sale'; } render($template);
ϓϩμΫτίʔ υͷ४උͰ ͖ͨɻͯ͞ɺ ͜ΕͰςετ ͕ॻ͚ΔΜͩ Αʂ པΕΔઌഐ
testίʔυΛॻ͍ͯΈΔ /** * @test */ public function セール開始前() { Chronos::setTestNow('2019-03-10');
$targetPageUrl = '/'; $actual = get($targetPageUrl); $this->assertTitleIs( '太郎君のお弁当箱', $actual ); }
testίʔυΛॻ͍ͯΈΔ /** * @test */ public function セール開始前() { Chronos::setTestNow('2019-03-10');
$targetPageUrl = '/'; $actual = get($targetPageUrl); $this->assertTitleIs( '太郎君のお弁当箱', $actual ); } ͜͜ʹೖΕ͕ͨ A$ISPOPTOPX AʹͳΔ
testίʔυΛॻ͍ͯΈΔ /** * @test */ public function セール期間中() { Chronos::setTestNow('2019-04-01');
$targetPageUrl = '/'; $actual = get($targetPageUrl); $this->assertTitleIs( '太郎君のお弁当箱〜7周年ありがとう!〜', $actual ); } ֘ظؒʹ͓͍ͯ ϖʔδίϯςϯπ͕ ࠩ͠ସΘΔ͜ͱΛظ͢Δ
testίʔυΛॻ͍ͯΈΔ /** * @test */ public function セール終了後() { Chronos::setTestNow('2019-05-01
06:59:59’); $targetPageUrl = '/'; $actual = get($targetPageUrl); $this->assertTitleIs( ‘太郎君のお弁当箱', $actual ); } ࣌ࠁϨϕϧ·ͰݻఆՄೳ
͓ͬͱɺऴྃ ࣌ͷઃఆΛͯ͠ ͳ͔͔ͬͨͶʂ ͪΖΜɺ͙͢ ʹඞཁͳ͍͚ Ͳɺࠓͷ͏ͪʹ ͓͍ͬͯͪΌ ͑҆৺ͩͶʂ པΕΔઌഐ
Θɺ͋Ϳͳ͍ʂ ઌഐ͋Γ͕ͱ ͏͍͟͝·͢ʂ ͬͺΓɺς ετ͕(͔͠ ؆୯ʹ)ॻ͚Δ ͱ҆৺ײ͕͋ Δͳʙ ৽ೖࣾһϫλγ
ͪͳΈʹɺ `setTestNow(null )` ͯ͋͛͠Εɺ ϑΣΠΫ࣌Ͱ ͳ͘ݱ࣮ͷ͕࣌ ฦͬͯ͘ΔͷͰ҆ ৺͞ɻςετͰ ͏࣌ͱ͔ɺ tearDown()ʹڬΜ
Ͱ͓͖͍ͨͶɻ པΕΔઌഐ
ଞʹศརͳ͜ͱ (࣌ؒ͋ΕͶ!)
৭ʑͱϔϧύʔͳͲ • DateTimeInterfaceDateTimeImmutableͷػೳͦͷ··͑Δͷ ͰɺҠߦͦΜͳʹ͠ΜͲ͘ͳ͍ͣ • add/sub/diffͳͲͳͲ • ࣌ૢ࡞ʹɺʮࣗવจͬΆ͍දݱͰಡΈ͍͢ʯAPI͕૿͑Δҹ • ge/gte/lt/lte/between/wasWithinLastͳͲͷൺֱػೳ
• addDays(int $value) / subMonths(int $value)ͳͲͷߋ৽ػೳ • Chronos::yesterday() / Chronos::instance(DatetimeInterface $dt) ͳͲͷϑΝΫτϦ
ΞάϨογϒͳ͍ํ <?php use Cake\Chronos\Chronos; if (!function_exists('now')) { function now() {
return Chronos::now(); } } // usage if (now()->isSunday()) { goto doNidone(); }
(ͪͳΈʹ)cakephpͷ߹ • I18nܥύοέʔδͰܧঝͨ͠ɺTime/FrozenTime ͕ར༻͞Ε͍ͯΔ • timezonelocaleͷใΛ͍࣋ͬͯΔ • https://github.com/cakephp/i18n/blob/master/ FrozenTime.php •
ORMܦ༝ͰRDBMS͔ΒऔΓग़ͨ͠datetimeྻͷ ɺࣗಈతʹίΠπʹϚʔγϟϧ͞ΕΔ
·ͱΊ
·ͱΊ(1/2) • ςετ = ҆৺ײ • ςελϒϧ = ઃܭͷɺςεςΟϯάϑϨʔ ϜϫʔΫ(etc)ଆͷදݱྗͷ
• ࣌Λࢧ͢Δͱͱͬͯศར ಛʹςετɺ͜ΕͰTDDΓ͍ͧ͢ʂ
·ͱΊ(2/2) • cakephpνʔϜͷϝϯς͚ͩͲɺελϯυΞ ϩϯͰ͑ΔͷͰɺͲ͜ʹͰ࿈Ε͍͚ͯΔʂ • ʮਂ0࣌ʙਂ2࣌ͷؒ௨Βͳ͍ʯ͔Βͷ ଔۀɾɾɾʂ
͓͖߹͍͍ ͖ͨͩ ͋Γ͕ͱ͏͝ ͍͟·ͨ͠ʂ