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
hideki kinjyo
PRO
March 31, 2019
Programming
0
1.2k
Datetime tests with cakephp/chronos
#phperkaigi 2019でのLT内容です。
cakephp/chronosを利用して強いテスタビリティを手に入れる話
hideki kinjyo
PRO
March 31, 2019
Tweet
Share
More Decks by hideki kinjyo
See All by hideki kinjyo
夢の無限スパゲッティ製造機 -実装篇- #phpstudy
o0h
PRO
0
79
夢の無限スパゲッティ製造機 #phperkaigi
o0h
PRO
0
360
PHPer Book Revue 「雑に作る」 #phperkaigi
o0h
PRO
0
270
俺にも私がAIと作った オススメの個人ツールを語らせてくれ
o0h
PRO
0
33
#phperbiglt のLT
o0h
PRO
0
74
手軽に積ん読を増やすには?/読みたい本と付き合うには?
o0h
PRO
1
240
symfony/mcp-bundleで、既存アプリケーションもお手軽にMCPサーバー化
o0h
PRO
1
130
組織もソフトウェアも難しく考えない、もっとシンプルな考え方で設計する #phpconfuk
o0h
PRO
10
5.7k
Composerが「依存解決」のためにどんな工夫をしているか #phpcon
o0h
PRO
1
690
Other Decks in Programming
See All in Programming
「効かない!」依存性注入(DI)を活用したAPI Platformのエラーハンドリング奮闘記
mkmk884
0
180
DevinとClaude Code、SREの現場で使い倒してみた件
karia
1
1.1k
野球解説AI Agentを開発してみた - 2026/02/27 LayerX社内LT会資料
shinyorke
PRO
0
370
Claude Codeログ基盤の構築
giginet
PRO
7
3.6k
どんと来い、データベース信頼性エンジニアリング / Introduction to DBRE
nnaka2992
1
330
クライアントワークでSREをするということ。あるいは事業会社におけるSREと同じこと・違うこと
nnaka2992
1
360
Kubernetesでセルフホストが簡単なNewSQLを求めて / Seeking a NewSQL Database That's Simple to Self-Host on Kubernetes
nnaka2992
0
180
我々はなぜ「層」を分けるのか〜「関心の分離」と「抽象化」で手に入れる変更に強いシンプルな設計〜 #phperkaigi / PHPerKaigi 2026
shogogg
2
370
Goの型安全性で実現する複数プロダクトの権限管理
ishikawa_pro
2
1.3k
安いハードウェアでVulkan
fadis
1
780
Migration to Signals, Signal Forms, Resource API, and NgRx Signal Store @Angular Days 03/2026 Munich
manfredsteyer
PRO
0
150
それはエンジニアリングの糧である:AI開発のためにAIのOSSを開発する現場より / It serves as fuel for engineering: insights from the field of developing open-source AI for AI development.
nrslib
1
520
Featured
See All Featured
Writing Fast Ruby
sferik
630
63k
A Soul's Torment
seathinner
5
2.5k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8k
How GitHub (no longer) Works
holman
316
150k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
300
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.4k
Speed Design
sergeychernyshev
33
1.6k
KATA
mclloyd
PRO
35
15k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.4k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
860
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
We Have a Design System, Now What?
morganepeng
55
8k
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࣌ͷؒ௨Βͳ͍ʯ͔Βͷ ଔۀɾɾɾʂ
͓͖߹͍͍ ͖ͨͩ ͋Γ͕ͱ͏͝ ͍͟·ͨ͠ʂ