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
53
もう少しテストを書きたいんじゃ〜 #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.1k
色んなオートローダーを覗き見る #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
仕様変更に耐えるための"今の"DRY原則を考える
mkmk884
8
2.8k
DRFを少しずつ オニオンアーキテクチャに寄せていく DjangoCongress JP 2025
nealle
2
210
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
600
パスキーのすべて ── 導入・UX設計・実装の紹介 / 20250213 パスキー開発者の集い
kuralab
3
860
Ruby on cygwin 2025-02
fd0
0
170
Domain-Driven Transformation
hschwentner
2
1.9k
React 19アップデートのために必要なこと
uhyo
5
890
ソフトウェアエンジニアの成長
masuda220
PRO
12
2k
楽しく向き合う例外対応
okutsu
0
570
密集、ドキュメントのコロケーション with AWS Lambda
satoshi256kbyte
1
210
Code smarter, not harder - How AI Coding Tools Boost Your Productivity | Angular Meetup Berlin
danielsogl
0
100
データベースのオペレーターであるCloudNativePGがStatefulSetを使わない理由に迫る
nnaka2992
0
230
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.2k
Mobile First: as difficult as doing things right
swwweet
223
9.4k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
33
2.8k
A better future with KSS
kneath
238
17k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
27
1.6k
Being A Developer After 40
akosma
89
590k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2k
What's in a price? How to price your products and services
michaelherold
244
12k
Gamification - CAS2011
davidbonilla
80
5.1k
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.