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
サバンナ便り〜自動テストに関する連載で得られた知見のまとめ〜
Search
Takuto Wada
PRO
March 03, 2023
Programming
19
6.5k
サバンナ便り〜自動テストに関する連載で得られた知見のまとめ〜
2023/03/03(金)
Forkwell エンジニア文化祭 2023
Takuto Wada
PRO
March 03, 2023
Tweet
Share
More Decks by Takuto Wada
See All by Takuto Wada
自動テスト実行結果の目的を整理する / Organizing objectives of automated test results
twada
PRO
10
2.1k
変更容易性と理解容易性を支える自動テスト(2024/02版) / Automated Test Knowledge from Savanna 202402 YAPC::Hiroshima edition
twada
PRO
17
7.7k
実録レガシーコード改善 / Working with Legacy Code: the True Record
twada
PRO
80
33k
Property-based Testing の位置付け / Intro to Property-based Testing
twada
PRO
10
3.2k
Second-System Syndrome: A tale of power-assert
twada
PRO
9
4.2k
技術選定の審美眼(2023年版) / Understanding the Spiral of Technologies 2023 edition
twada
PRO
74
27k
質とスピード(AWS Dev Day 2023 Tokyo 特別編、質疑応答用資料付き) / Quality and Speed AWS Dev Day 2023 Tokyo Edition
twada
PRO
54
28k
サバンナ便り〜自動テストに関する連載で得られた知見のまとめ(2023年5月版)〜 / Automated Test Knowledge from Savanna 202305 edition
twada
PRO
24
17k
組織に自動テストを書く文化を根付かせる戦略(2022秋版) / Building Automated Test Culture 2022 Autumn Edition
twada
PRO
37
24k
Other Decks in Programming
See All in Programming
両面どころかインフラもTSでできるよ ~ 全方位TypeScriptによるプロダクト開発 ~
myfinder
9
2.5k
Laravel標準バリデーションでできること
hmb_ok
2
360
Honoとhtmx
yusukebe
6
1.2k
Parallel Socket Communication in Swift
s_shimotori
0
260
上手な探索的テストとその上達方法について
matsu802
4
660
object-oriented-conference-2024
fuwasegu
6
2k
どうしてこうなった命名集 ~🔥編~ / OOC 2024 LT
pictiny
4
2.9k
脱・初心者!脱・マネコン!AWS CDKを使ってみませんか!?
har1101
0
180
GitHub Copilot Tips and Tricks
yuichielectric
26
7.5k
PHP8の機能を使って堅牢にコードを書く
fendo181
6
2.6k
PHPでOfficeファイルを取り扱う! PHP Officeライブラリを プロダクトに組み込んだ話
hirobe1999
0
840
ここ1~2年くらいで 使えるようになった(主要ブラウザーの最新版 がすべて対応した ) ウェブの新機能について ランダムに喋る!
myzkyy
9
6.5k
Featured
See All Featured
WebSockets: Embracing the real-time Web
robhawkes
59
6.9k
Into the Great Unknown - MozCon
thekraken
10
830
Designing Experiences People Love
moore
135
23k
Building a Modern Day E-commerce SEO Strategy
aleyda
15
6.3k
A Philosophy of Restraint
colly
195
15k
The Power of CSS Pseudo Elements
geoffreycrofte
58
4.9k
Building Applications with DynamoDB
mza
88
5.6k
The MySQL Ecosystem @ GitHub 2015
samlambert
242
12k
Designing on Purpose - Digital PM Summit 2013
jponch
109
6.4k
Thoughts on Productivity
jonyablonski
57
3.8k
Fashionably flexible responsive web design (full day workshop)
malarkey
397
65k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
34
8.8k
Transcript
ాਓʢ!U@XBEBʣ αόϯφศΓ ࣗಈςετʹؔ͢Δ࿈ࡌͰಘΒΕͨݟͷ·ͱΊ 📷🙆 🙆 'PSLXFMMจԽࡇ@" .BS
t-wada t_wada twada 📷🙆 📹🙅 🙆 ࣗݾհ #Forkwell文化祭_A
ٕज़ॻͷग़൛ʹؔΘ͍ͬͯ·͢
αόϯφศΓʜʜʁ
IUUQTUXBEBIBUFOBCMPHKQFOUSZXEQSFTTTBWBOOBDPMVNO 8&# %#13&44ʹίϥϜΛ࿈ࡌ͍ͯ͠·͢
IUUQTUXBEBIBUFOBCMPHKQFOUSZXEQSFTTTBWBOOBDPMVNO 8&# %#13&44ʹίϥϜΛ࿈ࡌ͍ͯ͠·͢
ΑΖ͓͘͠ئ͍͠·͢ 📷🙆 🙆 'PSLXFMMจԽࡇ@"
"HFOEB࿈ࡌ֤ճͷςʔϚ ֶश༻ςετ ِཅੑͱِӄੑ ςεταΠζ ςετμϒϧ ςετϐϥϛου 🦁
ֶͼΛࣗಈςετͱͯ͠ॻ͘ ଈ࣌ੑͱ࠶ݱੑ
ֶशྫ1)1ͷ%BUF5JNFͱ%BUF5JNF*NNVUBCMF IUUQTXXXQIQOFUNBOVBMKBDMBTTEBUFUJNFJNNVUBCMFQIQ
/** * @test * @group learning */ public function DateTimeのaddは自身の状態を変更しつつ自身を返す():
void { $halloween = new \DateTime('2021-10-31'); $oneYear = \DateInterval::createFromDateString('1 year'); $halloween2022 = $halloween->add($oneYear); $this->assertSame($halloween, $halloween2022); $this->assertEquals('2022-10-31', $halloween->format('Y-m-d')); $this->assertEquals('2022-10-31', $halloween2022->format('Y-m-d')); } /** * @test * @group learning */ public function DateTimeImmutableのaddは自身の状態を変更せず新しい状態を伴う新しいインスタンスを返す(): void { $halloween = new \DateTimeImmutable('2021-10-31'); $oneYear = \DateInterval::createFromDateString('1 year'); $halloween2022 = $halloween->add($oneYear); $this->assertNotSame($halloween, $halloween2022); $this->assertEquals('2021-10-31', $halloween->format('Y-m-d')); $this->assertEquals('2022-10-31', $halloween2022->format('Y-m-d')); } %BUF5JNFͱ%BUF5JNF*NNVUBCMFͷҧ͍Λֶशςετʹ͢Δ ֶशςετʢֶͼ͕తͷςετʣΛ ݟ͚ΔͨΊʹ MFBSOJOHλάΛ͚͍ͭͯ·͢ ֶ͕͜͜ͼ ֶ͕͜͜ͼ
ٙΛςετʹ͢Δ
/** * @test * @group learning */ public function 同じ時刻を指している場合はタイムゾーンが異なっても等価とみなされる():
void { $utc = new DateTimeImmutable('2021-12-24T15:00:00', new DateTimeZone('UTC')); $jst = new DateTimeImmutable('2021-12-25T00:00:00', new DateTimeZone('Asia/Tokyo')); $this->assertTrue($utc == $jst); } ٙΛςετʹ͢Δ ςετʹฉ͍ͯΈΕ͍͍
ڻ͖Λςετʹ͢Δ ྫ͑ʜʜ
ί ϯ ε τ ϥ Ϋ λ
Ұ ճ ͠ ͔ ݺ ͳ ͍ ͱ ࡨ ֮ ͠ ͯ ͍ ͨ ʁ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ Ұ ମ ͍ ͭ ͔ Β
/** * @test * @group learning */ public function コンストラクタをもう一度呼ぶと破壊的変更ができてしまう():
void { $dt = new \DateTimeImmutable('2021-12-24'); $this->assertSame('2021-12-24', $dt->format('Y-m-d')); $dt->__construct('2022-01-01'); $this->assertSame('2022-01-01', $dt->format('Y-m-d')); } ͳΜʜʜͩͱʜʜʂʁ ໌ࣔతʹݺͯ͠·͏ ༨ஊ͜ͷςετίʔυΛ͖͔͚ͬʹQIQTSDʹJTTVFͱͯ͠ใࠂ͞Εɺ͕ٞߦΘΕ·ͨ͠ɻ IUUQTHJUIVCDPNQIQQIQTSDJTTVFT ༨ஊ͜ͷςετίʔυΛ͖͔͚ͬʹ੩తղੳπʔϧ1)14UBOͱ1TBMNʹػೳఏҊ͕ߦΘΕɺ 1)14UBOʹ!NVOP@͞Μ͕࡞ͨ͠QVMMSFRVFTU͕࠾༻͞ΕɺϦϦʔε͞Ε·ͨ͠ɻ IUUQTHJUIVCDPNQIQTUBOQIQTUBOTSDQVMM
"HFOEB࿈ࡌ֤ճͷςʔϚ ֶश༻ςετ ِཅੑͱِӄੑ ςεταΠζ ςετμϒϧ ςετϐϥϛου 🦁
ࣗಈςετͷ৴པੑΛ Ή͠ΉݱΛཧղ͢Δ
ςετࣗಈԽͱاۀͷۀͷҼՌؔ IUUQTXXXBNB[PODPKQEQ ςετͷࣗಈԽʹ͓͍ͯɺ*5ύϑΥʔϚϯεͷ༧ଌईͱͳΓ͏Δ ͜ͱ͕໌ͨ͠ͷ࣍ͷͭ ৴པੑͷߴ͍ࣗಈςετΛඋ͑Δ͜ͱ ։ൃऀओମͰड͚ೖΕςετΛ࡞ɾཧ͠ɺ खݩͷ։ൃڥͰ؆୯ʹ࠶ݱɾमਖ਼Ͱ͖Δ͜ͱ
ʰ-FBOͱ%FW0QTͷՊֶʱQʢ˞༁ΛҰ෦มߋʣ
IUUQTXXXBNB[PODPKQEQ ςετʹ߹֨ͨ͠ιϑτΣΞͰ͋ΕϦϦʔεՄೳɺෆ߹֨Ͱ͋Εॏେͳ ෆ۩߹͕͋ΔɺͱνʔϜ͕֬৴Ͱ͖ΔΑ͏ͳςετΛ࣮ࢪ͍ͯ͠Δ͜ͱ ޡݕʢِཅੑGBMTFQPTJUJWFʣݟಀ͠ʢِӄੑGBMTFOFHBUJWFʣ͕ଟ ͘ɺ৴པੑʹ͚ܽΔςετεΠʔτ͕͋·Γʹଟ͗͢Δ ৴པͷߴ͍ςετεΠʔτΛ࡞Γ্͛ΔܧଓతͳྗͱࢿՁ͕͋Δ ʰ-FBOͱ%FW0QTͷՊֶʱQʢ˞༁ΛҰ෦มߋʣ ৴པੑͷߴ͍ࣗಈςετΛඋ͑Δ͜ͱ
ِཅੑͱِӄੑ IUUQTHJIZPKQNBHB[JOFXEQSFTTBSDIJWFWPM
ِཅੑͱِӄੑͷύλʔϯ w ِཅੑ w ੬͍ςετ CSJUUMFUFTU GSBHJMFUFTU w ৴པෆೳςετ
fl BLZUFTU w ِӄੑ w ۭৼΓ w ΧόϨοδෆ w ςετରϩδοΫͷςετίʔυͷ࿙Εग़͠
// プロダクトコード class Item { // コンストラクタ割愛 tax_amount() { const
rate = (this.tax_rate / 100); return (this.price / (1 + rate)) * rate; } } // テストコード it('税込価格から税額を返す', () => { const item = new Item('技評茶', 130, 8); const expected = (130 / (1 + (8 / 100))) * (8 / 100); assert.equal(item.tax_amount(), expected); }); ྫςετରϩδοΫͷςετίʔυͷ࿙Εग़͠ ԁະຬͷ͕ൃੜ͢Δ όά͕͋Δ ςετίʔυͷํಉ͡ϩδοΫͰ ظΛܭࢉ͍ͯ͠ΔͷͰ ςετ͕ޭͯ͠͠·͏
৴པෆೳੑʢ fl BLJOFTTʣ͕ʹۙ͢ΔͱɺςετՁΛࣦ͍࢝ΊΔ IUUQTXXXPSFJMMZDPKQCPPLT ʰ(PPHMFͷιϑτΣΞΤϯδχΞϦϯάʱQ
"HFOEB࿈ࡌ֤ճͷςʔϚ ֶश༻ςετ ِཅੑͱِӄੑ ςεταΠζ ςετμϒϧ ςετϐϥϛου 🦁
ࣗಈςετͱ$*ʹϑΟοτ͢Δ ໌֬ͳςετྨج४
օ͞Μʹ͓͍͠·͢ 🙋🙋🙋 wσʔλϕʔεʹΞΫηε͢ΔͷϢχοτςετ :FT/P wωοτϫʔΫʹΞΫηε͢ΔͷϢχοτςετ :FT/P wϑΝΠϧʹΞΫηε͢ΔͷϢχοτςετ :FT/P wݱࡏ࣌ࠁʹΞΫηε͢ΔͷϢχοτςετ :FT/P
wґଘઌͷΫϥεʹຊΛ͏ͷϢχοτςετ :FT/P
IUUQTNBSUJOGPXMFSDPNCMJLJ6OJU5FTUIUNM 6OJU5FTUͷ6OJUͬͯԿʁ
5FTU4J[FΑΓᐆດ͞ͷগͳ͍ྨ
IUUQTUFTUJOHHPPHMFCMPHDPNUFTUTJ[FTIUNM 5FTU4J[F
4NBMM ʢ୯Ұϓϩηεʣ .FEJVN ʢ୯ҰϚγϯʣ -BSHF ʢ੍ͳ͠ʣ 6OJU
ൺ େ͍ʹਪ ආ͚͍͕ͨ ͔ͨ͠ͳ͍ͱ͖ ࠷ѱ͕ͩ Α͘ݟ͔͚Δ *OUFHSBUJPO ൺ ॻ͚ΔͳΒ ίεύྑ͠ ී௨ Ͱ͖Ε ආ͚͍ͨ && ൺ ݪཧ্ෆՄೳʹ͍͕ۙ খ͍͞γεςϜͳΒՄೳʁ খ͍͞γεςϜ ͳΒՄೳ ී௨͔ͭ $6+ʹߜΓ͍ͨ 5FTU4DPQF 5FTU4J[F 5FTU4DPQFͱ5FTU4J[F
4NBMM ʢ୯Ұϓϩηεʣ .FEJVN ʢ୯ҰϚγϯʣ -BSHF ʢ੍ͳ͠ʣ 6OJU
ൺ େ͍ʹਪ ආ͚͍͕ͨ ͔ͨ͠ͳ͍ͱ͖ ࠷ѱ͕ͩ Α͘ݟ͔͚Δ *OUFHSBUJPO ൺ ॻ͚ΔͳΒ ίεύྑ͠ ී௨ Ͱ͖Ε ආ͚͍ͨ && ൺ ݪཧ্ෆՄೳʹ͍͕ۙ খ͍͞γεςϜͳΒՄೳʁ খ͍͞γεςϜ ͳΒՄೳ ී௨͔ͭ $6+ʹߜΓ͍ͨ 5FTU4DPQF 5FTU4J[F 5FTU4DPQFͱ5FTU4J[F ίεύྑ͠ ίεύѱ͠
"HFOEB࿈ࡌ֤ճͷςʔϚ ֶश༻ςετ ِཅੑͱِӄੑ ςεταΠζ ςετμϒϧ ςετϐϥϛου 🦁
࣮ੑͱܾఆੑͷ τϨʔυΦϑΛཧղ͢Δ
IUUQYVOJUQBUUFSOTDPN5FTU%PVCMFIUNM 5FTU%PVCMFࣗಈςετ༻ͷِ
IUUQYVOJUQBUUFSOTDPN5FTU%PVCMFIUNM 5FTU%PVCMFͷྨʢ࿈ࡌͷϖʔδʹऩ·Βͣʜʜʣ
ςετμϒϧͷརͱҙ IUUQTXXXBNB[PODPKQEQ w ར w ςετ͠ʹ͍͘ͷΛςετՄೳʹ͢Δ w ςετͷͱܾఆੑΛ্ͤ͞Δ w ҙ
w ςετ͕੬͘ͳΓɺมߋΛ͛Δʢརͷཪฦ͠ʣ w ςετͷِӄੑΛট͘ʢࣗ࡞ࣗԋςετʣ
"HFOEB࿈ࡌ֤ճͷςʔϚ ֶश༻ςετ ِཅੑͱِӄੑ ςεταΠζ ςετμϒϧ ςετϐϥϛου 🦁
ࣗಈςετͷ৴པੑΛ தظతʹอͭ ࠷దͳόϥϯε
Ϣχοτ ΠϯςάϨʔγϣϯ && ίετ ࣮ੑ ςετέʔε ߴ
ߴ ܾఆੑ ςετϐϥϛου
ςετϐϥϛουͱΞΠεΫϦʔϜίʔϯΞϯνύλʔϯ IUUQTXBUJSNFMPOCMPHJOUSPEVDJOHUIFTPGUXBSFUFTUJOHJDFDSFBNDPOF
ࠞཚղऍͷϒϨ͔Βੜ͕ͪ͡
͜Ε·ͰͷݟΛ·ͱΊΔͱ ֶश༻ςετ ِཅੑͱِӄੑ ςεταΠζ ςετμϒϧ ςετϐϥϛου 🦁 🦁 🦁 🦁
4NBMM .FEJVN -BSHF ίετ ࣮ੑ ςετέʔε ߴ
ߴ ܾఆੑ ·ͱΊςετμϒϧͰαΠζμϯͯ͠ɺ֤αΠζΛϐϥϛουܕʹஔ͠ɺςετશମͷ৴པੑΛҡ࣋͢Δ ςετμϒϧ ςετμϒϧ ςετ༰қੑઃܭ υϝΠϯઃܭ
͓ΘΓʹ
ࣦ৬ͷةػྑॻ͗͢Δ IUUQTCPPLNZOBWJKQFDQSPEVDUTEFUBJMJE
ࣦ৬ͷةػ͍͔ʹࢲͷݴ͍ͦ͏ͳ͜ͱΛݴ͏"* IUUQTUXJUUFSDPNLBXBTJNBTUBUVT
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ 📷🙆 🙆 'PSLXFMMจԽࡇ@"