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
もう少しテストを書きたいんじゃ〜 #phpstudy
Search
hideki kinjyo
PRO
February 26, 2025
Programming
2
130
もう少しテストを書きたいんじゃ〜 #phpstudy
第173回 PHP勉強会@東京でのメイン発表枠の資料です
https://phpstudy.connpass.com/event/344583/
hideki kinjyo
PRO
February 26, 2025
Tweet
Share
More Decks by hideki kinjyo
See All by hideki kinjyo
『テスト書いた方が開発が早いじゃん』を解き明かす #phpcon_nagoya
o0h
PRO
6
2.2k
色んなオートローダーを覗き見る #phpcon_okinawa
o0h
PRO
5
560
ヒューマンエラーの本を読んだ ~報告会~
o0h
PRO
3
290
みんなでワイワイ「テスト駆動開発」の話をやる会 #techramen24conf
o0h
PRO
3
560
SPLから始める「データ構造」入門
o0h
PRO
7
1.9k
PHPUnit11の新しい仲間たち
o0h
PRO
3
420
単体テストを書かない技術 #phpcon_odawara
o0h
PRO
62
21k
パンフ記事 「初めてのリファクタリング!」 の裏側 #phperkaigi
o0h
PRO
2
170
phpunit/php-code-coverageって何をしてるんだ #phperkaigi
o0h
PRO
3
1.5k
Other Decks in Programming
See All in Programming
Ça bouge du côté des animations CSS !
goetter
2
140
Better Code Design in PHP
afilina
0
160
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
7
4.1k
Software Architecture
hschwentner
6
2.1k
Djangoにおける複数ユーザー種別認証の設計アプローチ@DjangoCongress JP 2025
delhi09
PRO
4
420
dbt Pythonモデルで実現するSnowflake活用術
trsnium
0
240
Kubernetes History Inspector(KHI)を触ってみた
bells17
0
250
負債になりにくいCSSをデザイナとつくるには?
fsubal
10
2.5k
sappoRo.R #12 初心者セッション
kosugitti
0
270
ナレッジイネイブリングにAIを活用してみる ゆるSRE勉強会 #9
nealle
0
130
CDK開発におけるコーディング規約の運用
yamanashi_ren01
2
230
仕様変更に耐えるための"今の"DRY原則を考える
mkmk884
9
2.9k
Featured
See All Featured
Music & Morning Musume
bryan
46
6.4k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Typedesign – Prime Four
hannesfritz
40
2.5k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Become a Pro
speakerdeck
PRO
26
5.2k
Scaling GitHub
holman
459
140k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.7k
Six Lessons from altMBA
skipperchong
27
3.6k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.1k
Building Adaptive Systems
keathley
40
2.4k
Transcript
もう少しテストを書きたいんじゃ〜 第173回 PHP勉強会@東京 Hideki Kinjyo GitHub: o0h / X: @o0h_
[公開用]
つい先日! 愛知県の某イベントで発表をしてきました 
お題: 『テスト書いた方が 開発が早いじゃん』を解き明かす 話したこと: テストがない環境で、テストを書きたい人ができること テストを書くとこんな風に役立つよ〜 
こんな会話がありました ※ 一部改変  発表を聴きました〜 トテモウレシイ アリガトウ
こんな会話がありました ※ 一部改変  会社ではテストまだ書けてい ないので、試してみたいかも ワ、ウレシイ アリガトウ
こんな会話がありました ※ 一部改変  ただ、機会があってテストを ちょっと書いた時に どんな検査をすればいいの? で手が止まっちゃって !
「テスト的なものに取り組む動機」と 「テストを書き始めるための裏道」を 与えることは出来た ・・・・が!  今回(名古屋)の発表で
「テストを書けていない」人が 「自信や興味を持ってテストを書いてみる」に まだ届いていない!  自分が目指していた世界
ということで、 「テストを書く時の観点」の話 をリベンジだと思って話します 
本日のテーマ 🙅 テスト自体の「保守性」観点での品質の求め方 🙆 テストケースを考える際のコツ、観点 ⇓ ちょっとだけ「テストを書く」のに自信がつくように! 
本日のゴール テストケースを 気ままに増やせる/減らせるようになろう! 
自己紹介 • 金城秀樹 / きんじょうひでき • GitHub: @o0h / 𝕏
: @o0h_ • 好きなFWはCakePHP • アイコンは美味しい鮭親子丼の写真です • 最近はPodcastをやっています • ハッシュタグ: #readlinefm 
前回との比較(ターゲット) • 前回(#phpcon_nagoya)の発表は 「まだテストを書き始められていない」人向け • 今回の発表は 「書き始めたけど、いまいち自信がない・ふわふわしている」人向け 
本題に入る前に • 同日に名古屋であった、こちらの発表も素敵でした! • 勇気づけられる資料なので紹介です 
おしながき 1. 基礎編 2. 頭の体操編 3. まとめ 
1. 基礎編 2. 頭の体操編 3. まとめ
1. 基礎編 => 単体テストを考える際のヒント(技法) 2. 頭の体操編 3. まとめ
この章は? テストケース考えるときに、 どんな引き出しがあるんだろう? を広げるために薄く広く用語を並べます 
(・・・の前に) そもそもテストって何なんだ、の話
テストの基本 「事前条件」「入力」「結果」「事後条件」をセットで考える • これらが「何をテストするの?」の軸ということに • ケースが考えにくい時は、 いったん、日本語でこれらを考えるのも手助けになるはず 
テストの基本 この4つの「バリエーション」「網羅性」を考えられた時が 「テストに自信を持てる」時になるはず。 特に次の2点に着目して考えるのがスタート地点(※個人の意見です) • 「何が動けばOKか」 = 結果
• 「どんな動かし方が考えられるか」 = 入力 
テストの基本 テストは何をしてくれるのか?を定義すると・・・ • 🙆 テストとは「欠陥があることを証明するもの」 • 🙅 テストとは「欠陥がないことを証明するもの」 すなわち、「書かれた範囲で何かを証明する」だけ。
「◦◦がない」ことを証明はできない => 「こういう欠陥があるのではないか?」というマインドで取り組む 
テストを『知る』入口となる色々
出力値ベース・テスト [文献] 単体テストの考え方/使い方 (6章) • 何らかの入力をして、その出力(戻り値) を検査する • 対象のオブジェクトや関連オブジェクト が、状態を持たない(変化しない)場合に
使える • これが1番シンプルで便利と思って良さ そう  
状態ベース・テスト [文献] 単体テストの考え方/使い方 (6章) • 何らかの操作を行い、対象の状態を検査 する • ファイルへの書き込みやDBのデータ更新 も、この範疇
• 「計算して結果を直接返す」ことが出来 ないが、「結果が何処か別の所で観察で きる」場合などに使う  
コミュニケーション・ ベース・テスト [文献] 単体テストの考え方/使い方 (6章) • テスト対象から、その協力オブジェクト への入力を検査する •
結果を返してもくれないし、かつ影響 (変更)を観測できない場合に使う • モックやスパイ等のテクニックが必要  
制御フローテスト [文献] はじめて学ぶソフトウェアのテス ト技法 (10章) • 制御フロー(分岐経路)を整理して、その フローを通るように検査する • いわゆる「◯◯カバレッジ」を意識する
やり方で、テストケースを充実させる  ᶃ ᶄ ᶅ
◯◯カバレッジ • プログラムを実行した際に、 その処理を通った(cover)箇所の割合(-age) • ソースコードの行単位だったり、分岐単位だったり、色々なレベルが あります • 以前にPHPUnitの機能を絡めて発表した資料
があるので、引用してイメージを共有します • Line Coverage • Branch Coverage • Path Coverage 
Line Coverage 行単位で通ったコード(の割合)  実行される
Branch Coverage 「分岐」単位で通ったコード(の割合)  実行される 実行されない
Branch Coverage 「分岐」単位で通ったコード(の割合)  実行される 実行される
Path Coverage 「経路」単位で通ったコード(の割合)  4つのパス(=分岐の組み合わせ)が生まれる
比較すると?  Line Coverageを100%にするのは、どれでもOK OR OR OR
Branch Coverageを100%にするのは、$cの判定まで行く必要がある それさえあればOK 比較すると?  OR
Path Coverageを100%にするのは、すべて必要 (※1番下って必要?については説明しません!) 比較すると?  AND AND AND
カバレッジとテスト • 必ずしも「ちゃんと測定する」「数字を気にする」とならなくても • なんとなく「そういう観点があるんだな」を知って • 自分がテストを良くする際の発想のヒントに使える!!(はず
同値クラステスト [文献] はじめて学ぶソフトウェアのテス ト技法 (3章) • 「違う値だけど意味が同じ」ものを削っ て、テストケースを減らす 
開始日 終了日 2025-02-10 2025-03-10 この区間は どれをとっても 「同じ意味」
境界値テスト [文献] はじめて学ぶソフトウェアのテス ト技法 (4章) • 「意味の境目」に着目して、テストケー スを増やす • 境界線の「内側」「ぴったり」「外側」
の値を使ってテストする  開始日 終了日 2025-02-10 2025-03-10 変わり目に沿って 検査をする
ディシジョンテーブルテスト [文献] はじめて学ぶソフトウェアのテスト技法 (5章) • 「入力」「出力」のバリエーションを表形式で整理し、組み合わせの 漏れをなくす • 1列 =
1ケースとして扱う  έʔε1 έʔε2 έʔε3 έʔ ೖྗ Ωϟϯϖʔϯظؒத y y y ݶఆ n y n ΩϟϯϖʔϯରՁ֨ Ҏ্ Ҏ্ ະຬ ظ Ձ֨ -10% ±0% ±0% ϙΠϯτ 5% 5% 3%
ペアワイズ法 • 効果的に「無駄な組み合わせ」を減らす方法 • デシジョンテーブルを全うにやりすぎると、組み合わせが増えすぎる • 「PICT」というツールが有名 • これを使うとがーーーーーっと減らせる •
Emacsで便利に使えるらしいので、Emacs を使いましょう! 
三角測量 [文献] テスト駆動開発(3章) • 1つの視点で「成功すること」もしくは 「失敗したこと」を検査した後に、別の 視点でテストするで確かさを高める  A
1視点だけだと、ブレる 2視点で座標を確定する A B
ホワイトボックステスト • 内部実装の知識に頼らずに実施するテスト • 例えば「シグニチャ(引数や返り値、phpdocの内容など)」や「仕様書」 に沿ってテストケースを作成する 
ブラックボックステスト • 内部実装の知識に頼って実施するテスト • 例えば「コードカバレッジを高める(行カバレッジやブランチカバレッ ジetc)」ようなテストケースを作成する 
1. 基礎編 2. 頭の体操編 3. まとめ
このテスト、よさそう? • 機能: 指定されたIDのユーザーを消す • テスト: • id=1を入力して、操作を実行する • ユーザー(id=1)が消えていることを確認する

このテスト、よさそう? • 機能: 指定されたIDのユーザーを消す • テスト: • id=1を入力して、操作を実行する • ユーザー(id=1)が消えていることを確認する
 この世界で最も美しいクエリ───
このテスト、よさそう? • 機能: 指定されたIDのユーザーを消す • テスト: • id=1を入力して、操作を実行する • ユーザー(id=1)が消えていることを確認する
 DELETE FROM user;
そのテスト、駄目そう • 機能: 指定されたIDのユーザーを消す • テスト: • id=1を入力して、操作を実行する • ユーザー(id=1)が消えていることを確認する
• テスト2[三角測量]: • ユーザー(id=2)が消えていないことを確認する • 取りうるIDは「指定されたID」か「指定されていないID」だけなので、 それらの同値クラスを代表する値を1つずつ確かめられていればOK 
こんなテスト、どうする? • 機能: 入力されたメッセージを、世界中の市役所に送信する • テスト: • メッセージを実際に入力して • 「送信されたかな」を確認する
 テスト対象 クラス 世界市役所 クライアント
こんなテスト、どうする? • 機能: 入力されたメッセージを、世界中の市役所に送信する • テスト: • メッセージを実際に入力して • 「送信されたかな」を確認する
• 問題: • 「世界中の市役所が壊れていたら」という挙動を確認できない • シナリオ1: 入力が正しく、送信先も正常な場合、成功  テスト対象 クラス 世界市役所 クライアント ココがOK ココもOK
こんなテスト、どうする? • 機能: 入力されたメッセージを、世界中の市役所に送信する • テスト: • メッセージを実際に入力して • 「送信されたかな」を確認する
• 問題: • 「世界中の市役所が壊れていたら」という挙動を確認できない • シナリオ1: 入力が正しく、送信先も正常な場合、成功 • シナリオ2: 入力が正しくなくて、失敗  テスト対象 クラス 世界市役所
こんなテスト、どうする? • 機能: 入力されたメッセージを、世界中の市役所に送信する • テスト: • メッセージを実際に入力して • 「送信されたかな」を確認する
• 問題: • 「世界中の市役所が壊れていたら」という挙動を確認できない • シナリオ1: 入力が正しく、送信先も正常な場合、成功 • シナリオ2: 入力が正しくなくて、失敗 • シナリオ3: 入力が正しく、送信先が異常な場合、???  テスト対象 クラス 世界市役所 クライアント ココがOK ココがNG
こんなテスト、どうする? • 機能: 入力されたメッセージを、世界中の市役所に送信する • テスト: • メッセージを実際に入力して • 「送信されたかな」を確認する
• 問題: • 「世界中の市役所が壊れていたら」という挙動を確認できない • シナリオ1: 入力が正しく、送信先も正常な場合、成功 • シナリオ2: 入力が正しくなくて、失敗 • シナリオ3: 入力が正しく、送信先が異常な場合、???  これも 「要素」×「状態」 で洗い出せる
こんなテスト、ダミーオブジェクトを使う • モックとかスタブとか • 「もし、こうなったら?」を ハリボテ化する • これらは、
テストを簡単にするための方法 • 簡単 = テストの実装をシンプルに • 簡単 = テストの意図をわかりやすく  テスト対象 クラス 世界市役所 クライアント ココがOK ココがNG スタブ!
参考: こんなテスト、ダミーオブジェクトを使う • 「なるほど〜〜」ってなりやすのでオススメの資料 • 混乱されがちな「モックとは?スタブとは?」を解説する内容です が、コミュニケーション・ベース・テストの意義についても感じら れると思います 
カバレッジの練習 こんな仕様で実装したつもりです • お弁当とお茶の合計金額を返す • お弁当1個777円 • お茶1本120円 • お弁当を2つ以上買うと、お茶が1本無料
• お茶が無料になるのは最大1本まで 
カバレッジの練習 • Lineでカバレッジを見ると どうなりますか? 
カバレッジの練習 • Lineで見てみるとこうなる① 
カバレッジの練習 • Lineで見てみるとこうなる② 
カバレッジの練習 • Lineで見てみるとこうなる③ 
カバレッジの練習 • テストでカバーできているのは? • Branchでみてみる場合 
カバレッジの練習 • テストでカバーできているのは? • Branchでみてみる場合① 
カバレッジの練習 • テストでカバーできているのは? • Branchでみてみる場合② 
カバレッジの練習 • テストでカバーできているのは? • Branchでみてみる場合③ 
カバレッジの練習 カバレッジだけで見えてこないもの => まだ欠陥があるかも 例: • お弁当2つ以上でお茶が全部無料にな るバグ •
あらゆる条件でお茶が無料にならない バグ • あらゆる条件でお茶が1本無料になる バグ 
1. 基礎編 2. 頭の体操編 3. まとめ
これが言いたい テストは場数!!!! 
これが言いたい 書いてみる 読んでみる やっていきましょう!! 
更に学習するために • こうした話を深ぼるには「ソフトウェアテスト技法」で調べると◎ • 『ソフトウェアテスト技法練習帳』(技術評論社)などもオススメ • テスト的な感覚や「仕様や期待する挙動をコードに落とす」の感覚を 磨くには、『テスト駆動開発』の写経を真面目にやってみるのもオス スメです •
よく使うフレームワークの機能や仕様を「テストコードから読み解い てみる」のも非常にオススメ • cloneして手元で「もうあるテストを書き換えて・壊して動かしてみる」のも学 びが深まります! 
おしまい! お付き合いいただき ありがとうございました!!
参考書籍 • Vladimir Khorikov 著ほか. 単体テストの考え方/使い方, マイナビ出 版, 2022.12, (Compass
Programming). 978-4-8399-8172-3. • リー・コープランド 著ほか. はじめて学ぶソフトウェアのテスト技 法, 日経BP社, 2005.11. 4-8222-8251-1. • Kent Beck 著ほか. テスト駆動開発, オーム社, 2017.10. 978-4-274- 21788-3.