<PHP>FizzBuzzの例外処理とPHPUnitでテストコードを書く
勉強記録
PHPでFizzBuzzの例外処理と、PHPUnitで例外のテストコードをどうやって書くのか勉強しました。
例外処理とは
プログラムがエラーを出した時に、処理を中断して別の処理を行うこと。
PHPでの例外処理
throw文
throw new 例外
任意の場所で例外を投げることができる。
例外はExceptionクラス、またはExceptionクラスのサブクラスである必要がある。
(参考サイト)
PHP: 例外 - Manual
try...catch構文
try{ 例外が発生する可能性がある処理 }catch(例外のクラス 変数){ エラー発生時の処理 }finally{ 例外の有無に関わらず最後に必ず実行される処理 }
tryに書かれた処理の中で例外が起こると、例外が投げられる(throw文)
例外が投げられると、catchで例外が捕捉され、エラー発生時の処理が行われる
FizzBuzz問題で例外処理を行う
今回、FizzBuzz問題における例外処理を書いてみました。
FizzBuzz(フィズバズ)とは、英語圏で行われている言葉遊びの一種だそうですが、このゲームをプログラミングに応用したものが有名です。
・3の倍数でfizz
・5の倍数でbuzz
・両方の倍数でfizzbuzz
・それ以外は整数
を返すコードを書きます。
今回は、1~100までの数字でFizzBuzz問題を行うとし、1~100以外のものの場合例外を投げる処理を書きました。
<?php function fizzbuzz($i) { if (!(1<=$i && $i<=100)) { throw new OutOfBoundsException("1~100までの数字のみ", 999); } //3の倍数でfizz、5の倍数でbuzz、3と5の両方の倍数でfizzbuzzと表示 if ($i%3==0 && $i%5==0) { return "fizzbuzz"; } if ($i%3==0) { return "fizz"; } if ($i%5==0) { return "buzz"; } return $i; }
最初に1~100ではないものに関しては、throw new OutOfBoundsExceptionで例外を投げています。
テストコードとは
テストコードは、書いたプログラムが想定どうりの動きをしているのかを確認するためのコード。
PHPUnitでテストコードを書く
PHPでユニットテストを行うツール。
ユニットテスト(単体テスト)とは、クラスや関数などの小さな単位(ユニット)で動作を確認するためのテストのこと。
Laravelには標準搭載されている。
FizzBuzz問題のテストコード
<?php use PHPUnit\Framework\TestCase; require_once('src/fizzbuzz.php'); class fizzbuzzTest extends TestCase { /** * @dataProvider fizzbuzzProvider */ public function testFizzBuzz($i,$expected) { $this->assertEquals($expected, fizzbuzz($i)); } public function fizzbuzzProvider() { return[ [1, 1], [2, 2], [3, 'fizz'], [4, 4], [5, 'buzz'], [6, 'fizz'], [7, 7], [8, 8], [9, 'fizz'], [10, 'buzz'], [11, 11], [12, 'fizz'], [13, 13], [14, 14], [15, 'fizzbuzz'], [16, 16], [17, 17], [18, 'fizz'], [19, 19], [20, 'buzz'], [21, 'fizz'], [22, 22], [23, 23], [24, 'fizz'], [25, 'buzz'], [26, 26], [27, 'fizz'], [28, 28], [29, 29], [30, 'fizzbuzz'], [31, 31], [32, 32], [33, 'fizz'], [34, 34], [35, 'buzz'], [36, 'fizz'], [37, 37], [38, 38], [39, 'fizz'], [40, 'buzz'], [41, 41], [42, 'fizz'], [43, 43], [44, 44], [45, 'fizzbuzz'], [46, 46], [47, 47], [48, 'fizz'], [49, 49], [50, 'buzz'], [51, 'fizz'], [52, 52], [53, 53], [54, 'fizz'], [55, 'buzz'], [56, 56], [57, 'fizz'], [58, 58], [59, 59], [60, 'fizzbuzz'], [61, 61], [62, 62], [63, 'fizz'], [64, 64], [65, 'buzz'], [66, 'fizz'], [67, 67], [68, 68], [69, 'fizz'], [70, 'buzz'], [71, 71], [72, 'fizz'], [73, 73], [74, 74], [75, 'fizzbuzz'], [76, 76], [77, 77], [78, 'fizz'], [79, 79], [80, 'buzz'], [81, 'fizz'], [82, 82], [83, 83], [84, 'fizz'], [85, 'buzz'], [86, 86], [87, 'fizz'], [88, 88], [89, 89], [90, 'fizzbuzz'], [91, 91], [92, 92], [93, 'fizz'], [94, 94], [95, 'buzz'], [96, 'fizz'], [97, 97], [98, 98], [99, 'fizz'], [100, 'buzz'], ]; } /** * @dataProvider fizzbuzzErrorProvider */ public function testException($i, $e) { //例外の型をチェック $this->expectException(get_class($e)); //指定したメッセージかチェック $this->expectExceptionMessage($e->getMessage()); //指定したコードかチェック $this->expectExceptionCode($e->getCode()); fizzbuzz($i); } public function fizzbuzzErrorProvider() { return[ [0, new OutOfBoundsException("1~100までの数字のみ",999)], [101,new OutOfBoundsException("1~100までの数字のみ",999)], [102,new OutOfBoundsException("1~100までの数字のみ",999)], ["a",new OutOfBoundsException("1~100までの数字のみ",999)], ["あ",new OutOfBoundsException("1~100までの数字のみ",999)], ]; } }
今回のテストコードのポイント!
・fizzbuzzTestクラスはPHPUnit\Framework\TestCaseクラスを継承する。
・require_onceでテスト対象のファイルを読み込んでテストを行う。
・データプロバイダを使用。テストケースに渡すデータのセットを定義できる機能。
テーブルドリブンテストを書くための仕組み。
/** *@dataProvider データのセットを渡すメソッド名 */
@dataProviderアノテーションを記述することで、使うことができる。
「テーブルドリブンテスト」とは?
テーブル駆動テストとも言う。
入力と期待値をセットにしてテーブルのように記述していく。
こうすることで、たくさんのデータを同じ処理でテストすることができる。
(テーブルドリブンテストにしないと、データのかたまりがないから処理をたくさん書かなければならない。書き間違える可能性もあるし、読みにくい!)
今回は特に1~100の値について、testFizzBuzzという1個のテストで100個のサブテストを行なっている。