SlideShare a Scribd company logo
CakePHP + PHPUnitによる
実践的ユニットテスト
2013/07/06 ゆるかわPHP#2
若松 慶信(@yshnb)
自己紹介
• 若松慶信
• 1987/8/1生
• 所属:ヴォラーレ株式会社 Webエンジニア
CakPHP
CakePHP
• 学習コスト低
• 設置が簡単
• ActiveRecordが使い易い
• 情報が豊富
典型的なWebサービスの開発が容易
Cake php + php unitによる実践的ユニットテスト
フレームワークの動向
Google Web検索の人気度
(日本、2012/07 ~ 2013/06)
CakePHP > その他
ちなみに世界では
Google Web検索の人気度
(すべての国、2012/07 ~ 2013/06)
CakePHPでのテスト
CakePHP1.x → SimpleTest
CakePHP2 → PHPUnit
Cake php + php unitによる実践的ユニットテスト
PHPUnit
• xUnit系テスティングフレームワーク
– 最新はPHPUnit3.8
• コマンドラインから実行可能
– JenkinsなどCIツールと併用しやすい
Cake php + php unitによる実践的ユニットテスト
ユニットテストの基本の話
テストの目的
• なぜテストするか?を考える
– バグを発見する
– 仕様通りの動作をするか検証する
テストの方針
• ユニットテストで守るべきルールは?
– コードカバレッジ100%?
– 同値分割・境界値分析で全パターンを網羅?
– あらゆる例外ケースの網羅?
テストの方針
• ユニットテストで守るべきルールは?
– コードカバレッジ100%?
– 同値分割・境界値分析で全パターンを網羅?
– あらゆる例外ケースの網羅?
(実践的)テストの方針
誰でも実践できる・変更に強い
「誰でも実践できる」とは?
• 高度なテスト・複雑なテスト
– 書いた人に依存しやすい
– プロダクトコードの変更時、
テストコードが無視されてしまう
できるだけ誰にでも分かる形で書く
変更への強さ
コードの変更 バグの発見
厳密なテスト 変更に弱い より多くのバグを発見できる
寛容なテスト 変更に強い 発見できるバグは限られる
テストの厳密性と発見できるバグの関係
具体例:アサートの使い分け
$actual = $this->Sample->getSomething();
$this->assertInternalType("array", $something);
$this->assertEquals($expected, $something);
寛容なアサート:戻り値の型チェックのみ
厳密なアサート:等価かどうかのチェック
実行
Q. 寛容なテストは意味があるか?
• 意外とこれで発見できるバグも多い
– もちろん寛容のレベルはケースバイケース
• テストは銀の弾丸ではない
– あくまでバグ発見手段の1つにすぎない
– 完璧主義に陥ってはいけない
CakePHP流テストの話
CakePHP流のテストの話
• MVC(Model2)フレームワーク
– 重いModel + 軽いController + α
– テスト対象の主役はModel
• オブジェクト間の依存
– 副作用をもつものもある
• 戻り値のチェックのみで十分なのは
副作用がない場合のみ
メソッドの副作用
public function url2link($url = null) {
return empty($url) ? $url : "<a href="{$url}">{$url}</a>";
}
副作用のないコードの例
副作用のあるコードの例
public function createHoge($data) {
$this->create();
return $this->save($data);
}
メソッドの実行は外部に影響しない
メソッドの実行が外部に影響する
副作用のテスト方法
• 2つのアプローチ
• 状態中心テスト
• 相互作用中心テスト
状態中心テスト
テストケース
テスト対象
オブジェク
ト
副作用実行
参照・検証
実行対象によって変化した状態を検証
相互作用中心テスト
テストケース
テスト対象
オブジェク
ト
(モック)
副作用実行
検証
モックの準備(エクスペクテーション設定)
実行対象が外部に与えようとする変化を検証
どちらのアプローチを使うか?
• Model (Component)
→ 状態中心テスト
• Controller (Behavior, Shell)
→ 相互作用中心テスト
1つの考え方
あくまで一例。例えば
Model間の依存が多い場合は、相互作用中心のテスト
というアプローチも全然あり
テストの流れ
• 事前準備
– テストに使うデータの生成など
• 実行
– テスト対象のメソッド実行
• 検証
– メソッド実行結果の検証(アサート)
• 後処理
– 使用したオブジェクトの破棄
Modelのテスト
• 事前準備
– データの準備はテストに含めておき
Fixtureには依存させない
• 検証
– 戻り値の検証
– 変更された状態の検証
– チェック目的が明確に分かるように
– アサートは必要に応じ別メソッドを用意
Modelのテスト例
// 事前準備(検証データの挿入)
$this->Hoge->save($this->sampleData);
// 実行
$data = $this->Hoge->getTableData();
// 検証
$this->assertIntenralType(‘array’, $data);
$this->assertDataFormat($data);
Controllerのテスト
• 厳密なユニットテストではない
• 相互作用中心のテスト
– Model, Componentなどをモックで扱い
相互作用を検証する
Controllerのテスト
• 事前準備
– Controller内のオブジェクトをモック化
• ControlllerTestCase::generate
– モックへエクスペクテーション設定
• 実行
– エクスペクテーションの検証
• 検証
– set内の値の検証など
Controllerのテスト例
// 事前準備
$this->Hoges = $this->generates(“Hoges”);
// 実行
$this->testAction(“/test/”);
// 検証
$this->assertArrayHasKey(“hoge”, $this->vars);
その他Tips
• dataProviderによる類似ケース管理
• プライベートメソッドのテスト
• モック使用時のアンチパターン
dataProviderでの類似ケース管理
• 渡すパラメータだけを変更して
実行過程を管理
• どんなケースに有効か?
– 同値分割・境界値分析で
パラメータ組み合わせを変えたケース
– バリデーションのテストケース
dataProviderでの類似ケース管理
public function dp_sample() {
$cases[] = array(1); // Case1
$cases[] = array(-1); // Case2
return $cases;
}
/**
* @test
* @dataProvider dp_sample
*/
public function dp_sample($arg) {
// …
}
プライベートメソッドのテスト
※ただし単体でテストせずに済む方法を探すほうが望ましい
• 別クラスのオブジェクトにして処理を委譲
• 呼び出し元の状態中心テストでカバー
• あきらめる
プライベートメソッドはテストケースから直接実行できない
→ どのように実行するか?
プライベートメソッドのテスト
// 事前準備
$__privateMethod = new ReflectionMethod(‘Subject’, ‘__privateMethod’);
$__privateMethod->setAccessible(true); // アクセス権限をpublicに変更
// 実行
$__privateMethod->invoke($this->Subject, null);
// 検証
// …
① ReflectionMethodを使ってアクセス権限書き換え
プライベートメソッドのテスト
Closure::bind(function() {
// 事前準備
$Subject = ClassRegistry::init(“Subject”);
// 実行
$Subject->doSomething();
// 検証
…
}, $this, “Subject”)->__invoke();
② Closure::bind() を利用して実行スコープを変更
モック使用時のアンチパターン
public function register() {
App::uses("File", "Utility");
$file = new File("/path/to/file");
if ($file->open()) {
// …
}
}
例えばプロダクトコードでの場当たり的オブジェクト生成
• あれ、テストのときもFile動いちゃうじゃんw
• モックへの差し替えが難しい
→ テストが難しくなる
→ テストを書かない・書いても複雑なテストに
public function startup() {
App::uses("File", "Utility");
$this->File = new File("/path/to/file");
}
public function register() {
if ($this->File->open()) {
$filetext = $this->File->read();
}
}
アンチパターンへの対処
• オブジェクトを委譲しておくことで対処
• しかし本質的に重要なのはテストの声を聞くこと
テストの書きづらさ=プロダクトコードの問題
ツールの簡単な紹介
Jenkins
Jenkins
Jenkinsでできること
• 出来ること一例
– テストの実行
– 各種レポーティング
– 静的解析ツールとの併用
• Mess Detector
• Code Sniffer
• Copy Paste Detecor
– ドキュメントの生成
Phing
こんなツールですよ
要はPHP版 Ant
※めんどくさくなってきたからこれだけ
ご清聴ありがとうございました

More Related Content

What's hot (20)

PDF
phpspecで始めるBDD
Yuuki Takezawa
 
PPTX
PHP x AWS でスケーラブルなシステムをつくろう
Taiji INOUE
 
PDF
Drupal 8 - モダンなアーキテクチャのPHPベースOSS CMS
Tomoki Hasegawa
 
PDF
恋に落ちるデプロイツール
totty jp
 
PDF
Php非同期の技法
Shogo Kawahara
 
KEY
php-timecopを実戦投入してみた
Yoshio Hanawa
 
PDF
NetBeans、FuelPHP と過ごしたこの 2 ヶ月
suno88
 
PDF
Laravel5.1 Release
Yuuki Takezawa
 
PDF
NetBeansではじめる FuelPHP
Junichi Yamamoto
 
PPTX
Jenkins tips 20161014
Hideaki Ishijima
 
PPTX
テストしなイカ? Seleniumで自動ブラウザテスト
Ohishi Mikage
 
PDF
Laravel 5.1 LTSでサービスを作る
infinite_loop
 
PPTX
あるあるLT〜サーバーサイドエンジニア〜 Vol.3
Keiichi Hagiwara
 
PDF
8時間耐久PHPUnitの教室
Yusuke Ando
 
PPT
PHP agile test tips
Tsutomu Chikuba
 
KEY
PHPエクステンションの開発tips
Yoshio Hanawa
 
PPT
メタプログラミングって何だろう
Kota Mizushima
 
PDF
anyenv + phpenv + php-build が便利すぎる件
y-uti
 
PPTX
Eggplant Functional - Lesson 9 (Japanese slides)
Eggplant
 
PDF
CakePHP最新情報 PHPカンファレンス関西2012
ichikaway
 
phpspecで始めるBDD
Yuuki Takezawa
 
PHP x AWS でスケーラブルなシステムをつくろう
Taiji INOUE
 
Drupal 8 - モダンなアーキテクチャのPHPベースOSS CMS
Tomoki Hasegawa
 
恋に落ちるデプロイツール
totty jp
 
Php非同期の技法
Shogo Kawahara
 
php-timecopを実戦投入してみた
Yoshio Hanawa
 
NetBeans、FuelPHP と過ごしたこの 2 ヶ月
suno88
 
Laravel5.1 Release
Yuuki Takezawa
 
NetBeansではじめる FuelPHP
Junichi Yamamoto
 
Jenkins tips 20161014
Hideaki Ishijima
 
テストしなイカ? Seleniumで自動ブラウザテスト
Ohishi Mikage
 
Laravel 5.1 LTSでサービスを作る
infinite_loop
 
あるあるLT〜サーバーサイドエンジニア〜 Vol.3
Keiichi Hagiwara
 
8時間耐久PHPUnitの教室
Yusuke Ando
 
PHP agile test tips
Tsutomu Chikuba
 
PHPエクステンションの開発tips
Yoshio Hanawa
 
メタプログラミングって何だろう
Kota Mizushima
 
anyenv + phpenv + php-build が便利すぎる件
y-uti
 
Eggplant Functional - Lesson 9 (Japanese slides)
Eggplant
 
CakePHP最新情報 PHPカンファレンス関西2012
ichikaway
 

Similar to Cake php + php unitによる実践的ユニットテスト (20)

PDF
関西Php勉強会のlimeの話
Hisateru Tanaka
 
PDF
Code igniterでテスト駆動開発 資料作成中
Takako Miyagawa
 
PDF
PHPUnitTest勉強会スライド
ssuser7a9029
 
PDF
PHPUnitTest勉強会スライド
ssuser7a9029
 
PDF
Getting Started with Testing using PHPUnit
Atsuhiro Kubo
 
PDF
Intellij idea for php
Kazuhiko Uno
 
PDF
Introduction to Continuous Test Runner MakeGood
Atsuhiro Kubo
 
PPT
Caketest
ryota ichie
 
PDF
Local php-100828 2
Akio Ishida
 
PDF
Php勉強会資料20090629
Takako Miyagawa
 
PPT
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
Tsutomu Chikuba
 
PDF
実"戦"CakePHP Plugin
Kenichirou Oyama
 
PPTX
CakePHP3.x での各種実装例 ~| PHP Tech Bash 20171121 ~
諒一 上野
 
PDF
MakeGoodで快適なテスト駆動開発を
Atsuhiro Kubo
 
KEY
EC-CUBE + PHPUnit で 実践テスト駆動開発
Kentaro Ohkouchi
 
PPT
ビジネス的に高価値なアジャイルテスト
Tsutomu Chikuba
 
PDF
Angular js meets cakephp at cloud on the beach 2014 前夜祭
司 知花
 
PDF
Eclipse PDT + MakeGoodによるPHPコードのテスト
Atsuhiro Kubo
 
PPT
CakeにTestがやってきた
kishida4slideshare
 
PPTX
CakePHP を使ってよかったこと
Wataru Terada
 
関西Php勉強会のlimeの話
Hisateru Tanaka
 
Code igniterでテスト駆動開発 資料作成中
Takako Miyagawa
 
PHPUnitTest勉強会スライド
ssuser7a9029
 
PHPUnitTest勉強会スライド
ssuser7a9029
 
Getting Started with Testing using PHPUnit
Atsuhiro Kubo
 
Intellij idea for php
Kazuhiko Uno
 
Introduction to Continuous Test Runner MakeGood
Atsuhiro Kubo
 
Caketest
ryota ichie
 
Local php-100828 2
Akio Ishida
 
Php勉強会資料20090629
Takako Miyagawa
 
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
Tsutomu Chikuba
 
実"戦"CakePHP Plugin
Kenichirou Oyama
 
CakePHP3.x での各種実装例 ~| PHP Tech Bash 20171121 ~
諒一 上野
 
MakeGoodで快適なテスト駆動開発を
Atsuhiro Kubo
 
EC-CUBE + PHPUnit で 実践テスト駆動開発
Kentaro Ohkouchi
 
ビジネス的に高価値なアジャイルテスト
Tsutomu Chikuba
 
Angular js meets cakephp at cloud on the beach 2014 前夜祭
司 知花
 
Eclipse PDT + MakeGoodによるPHPコードのテスト
Atsuhiro Kubo
 
CakeにTestがやってきた
kishida4slideshare
 
CakePHP を使ってよかったこと
Wataru Terada
 
Ad

Recently uploaded (9)

PDF
安尾 萌, 松下 光範. 環境馴致を計量可能にするための試み,人工知能学会第4回仕掛学研究会, 2018.
Matsushita Laboratory
 
PDF
論文紹介:AutoPrompt: Eliciting Knowledge from Language Models with Automatically ...
Toru Tamaki
 
PDF
安尾 萌, 北村 茂生, 松下 光範. 災害発生時における被害状況把握を目的とした情報共有システムの基礎検討, 電子情報通信学会HCGシンポジウム2018...
Matsushita Laboratory
 
PDF
安尾 萌, 藤代 裕之, 松下 光範. 協調的情報トリアージにおけるコミュニケーションの影響についての検討, 第11回データ工学と情報マネジメントに関する...
Matsushita Laboratory
 
PPTX
勉強会_ターミナルコマンド入力迅速化_20250620. pptx. .
iPride Co., Ltd.
 
PPTX
Vibe Codingを始めよう 〜Cursorを例に、ノーコードでのプログラミング体験〜
iPride Co., Ltd.
 
PDF
Forguncy 10 製品概要資料 - ノーコードWebアプリ開発プラットフォーム
フォーガンシー
 
PDF
論文紹介:Unbiasing through Textual Descriptions: Mitigating Representation Bias i...
Toru Tamaki
 
PPTX
色について.pptx .
iPride Co., Ltd.
 
安尾 萌, 松下 光範. 環境馴致を計量可能にするための試み,人工知能学会第4回仕掛学研究会, 2018.
Matsushita Laboratory
 
論文紹介:AutoPrompt: Eliciting Knowledge from Language Models with Automatically ...
Toru Tamaki
 
安尾 萌, 北村 茂生, 松下 光範. 災害発生時における被害状況把握を目的とした情報共有システムの基礎検討, 電子情報通信学会HCGシンポジウム2018...
Matsushita Laboratory
 
安尾 萌, 藤代 裕之, 松下 光範. 協調的情報トリアージにおけるコミュニケーションの影響についての検討, 第11回データ工学と情報マネジメントに関する...
Matsushita Laboratory
 
勉強会_ターミナルコマンド入力迅速化_20250620. pptx. .
iPride Co., Ltd.
 
Vibe Codingを始めよう 〜Cursorを例に、ノーコードでのプログラミング体験〜
iPride Co., Ltd.
 
Forguncy 10 製品概要資料 - ノーコードWebアプリ開発プラットフォーム
フォーガンシー
 
論文紹介:Unbiasing through Textual Descriptions: Mitigating Representation Bias i...
Toru Tamaki
 
色について.pptx .
iPride Co., Ltd.
 
Ad

Cake php + php unitによる実践的ユニットテスト