1時間で分かる
PHPUnit講座
水島創太
1
プロジェクトの配置
• ¥C:直下にzipファイルを解凍して配置
2
目次
1. そもそもユニットテストって何?
2. PHPUnitについて
3. 実際にPHPUnitでコードを書いてみよう!
4. まとめ
3
4
そもそもユニットテストって?
ユニットテスト=メソッド単位のテスト
5
<?php
// クラス
class Human
{
// メソッド
function eat ($food)
{
$foodを噛む;
$foodを溶かす;
$foodを吸収;
return 栄養;
}
}
?>
• テスト: 実装したプログラムが
設計した通りに動くか
確認
• クラス: 共通する変数や
メソッドをまとめたもの
• メソッド: 処理をまとめて
名前をつけたもの
ユニットテストのメリット
1. 範囲が狭いので問題の原因や修正箇所の特
定が容易
2. テストコードを資産として残せる
3. 疎結合なソースコードの記述を意識しやすい
6
ではPHPUnitとは?
• テスティングフレームワーク
• ユニットテストの手順をPHPプログラムと
して作成し、自動実行できるツール
• メソッドが想定通りに動くか自動確認
できる!
7
どうやってテストをするのか?
• メソッドの実行結果が期待値と一致するか
• 期待値 = 処理が実行された結果の予想
8
/**
* 渡された値に+1をして返却する.
*/
public function add(int $num) {
return $num + 1;
}
1
$num 結果
期待値:
2
2
長々と話しましたが・・・・・・
• PHPUnitでテストコードを
書いてみよう!
9
今回のテスト完了基準
• コードカバレッジ100%(分岐網羅) + 条件網羅
1. $numberが3の倍数の時、”Fizz”を返却する
2. $numberが5の倍数の時、”Buzz”を返却する
3. $numberが3と5の倍数の時、”FizzBuzz”が返却される
4. $numberが3の倍数でも5の倍数でもない時、
$numberに渡された数値がそのまま返却される
※コードカバレッジ : 対象のプログラム全体の中でテストが行われた部分の割合
※分岐網羅: それぞれの判定条件における真偽が少なくとも1回は実行される
※条件網羅: それぞれの条件文における真偽が少なくとも1回は実行される
テストファイルの実行設定
• phpunit.xml.dist:テストの実行計画ファイル
テストコード実行する対象を指定
ディレクトリ単位でもファイル単位
でも指定できる
テストコード対象に選択しない
テストコード作成のルール①
• Class名は「テスト対象名 + Test」
class HogeHogeTest
{
}
テストコード作成のルール②
• PHPUnitの「TestCase」クラスを継承すること
Class HogeHogeTest extends TestCase
{
}
テストコード作成のルール③
• テストしたいメソッドごとにテストメソッドを作成
• テストメソッドは「test+メソッド名」
Class HogeHogeTest extends TestCase
{
public function testHogeHoge()
{
}
}
どうやってテストをするのか?
• メソッドの実行結果が期待値と一致するか
• 期待値 = 処理が実行された結果の予想
15
/**
* 渡された値に+1をして返却する.
*/
public function add(int $num) {
return $num + 1;
}
1
$num 結果
期待値:
2
2
Assertで期待値と結果を比較
• TestCaseにはAssert**というテスト結果比較
用の関数が用意されている
• $this->assert**(期待値, 結果); を実行し
期待値と結果の比較を出力する
• Assertには状況に応じて使える様々な種類が
ある
DataProvider
• 配列に登録したデータを引数として複数渡すことができる
• テストデータを複数用意してテストができる!
public function hogehogeProvider()
{
return [
// テストケースごとに作成
[
// 引数$hoge
hoge,
// 引数$fuge
fuge,
],
];
}
DataProviderの紐付け設定
• PHPDocでコメントを記述してDataProviderを
使いたいテストメソッドを関連づけることが
できる
/**
* @dataProvider [プロバイダメソッド名]
*/
public function testHogeHoge()
{
環境情報
• PHPフレームワーク Symfony3.1
• PHPUnit 3.7.21(最新は6.0.0)
• PHP 5.6.19
• IDE:Visual Studio Code
PHP7.0以上の人 => PHPUnitは 最新 のものでOK (今のところ)
PHP5.6の人 => PHPUnitは 5.7系 のものでOK (pharファイルはphpunit-5.7.21.phar)
PHP5.5以下の人 => PHPUnitは 4.8系 を使う (pharファイルはphpunit-4.8.36.phar)
19
ユニットテストのメリットとは?
20
問題の原因や修正箇所の特定が容易
21
結合
テスト
ユニット
テスト
テスト範囲が大きいので
上手く行かなかった場合
に原因特定が困難!
問題があってもメソッド内
の処理と、テスト値のみ
検証すれば良い
メソッドごとの正常動作
は担保できる!
<?php
// クラス
class Human
{
// メソッド
function eat ($food)
{
}
}
?>
テストコードを資産として残せる
• 資産としてソースコードが残ることで
1. コードの処理が理解しやすくなる
2. リファクタリングがしやすくなる
3. リグレッションテスト工数を減らせる
※リファクタリング:プログラムを動作を変えずに読みやすく綺麗な形に変更すること
※リグレッションテスト:
プログラムの変更によって予想外の影響が現れていないかを確認するテスト
例) バグ修正によって新たなバグが発生していないかを確認する 22
疎結合なソースコードを意識しやすい
• 疎結合とは他との結びつきが弱く独立性が
強い構造。 ⇔ 密結合
• ユニットテストを実装していると疎結合な
デザインを感覚的に意識 しやすい
⇒何故か?
• 密結合なfunctionはユニットテスト書くのが
めんどくさい!!!!
23
密結合だとめんどくさいので・・・
• テストコードをシンプルにするためにソース
もシンプルになる
• 疎結合なデザインに自然となっていく
24
1. 疎結合なデザイン⇒ソースコードの洗練
2. メソッド単位の担保⇒バグの発生率の低下
3. テストのソースコード化⇒テストの工数削減
↓
全体の工数の圧縮につながり
システムの質の向上にも結び付く!
25
まとめ

PHPUnitTest勉強会スライド