はじめに
以下本を読みながら初めてテストファーストでプログラムを書いてみました。
いきなり難しいお題だと着地しないかも、と不安だったので、誰でも知ってるFizzBuzz問題を採用してます。
なお、参考にした本は下記です。
(書籍内ではボーリングのスコア計算をTDDで扱っています。いきなりこれだとちょっとできるか不安でしたw)
[参考]これからはじめるTDD テスト駆動開発入門 ThinkIT Books
環境
以前こちらにまとめているのと同様の環境を利用しています。
FizzBuzz問題
要件としては以下です。
- 3で割り切れる時は「Fizz」
- 5で割り切れる時は「Buzz」
- 3と5で割り切れる時は「FizzBuzz」と出力する
[参考]Fizz-Buzz問題
プログラム
テストコードは以下。
<?php
require_once __DIR__. '/fizzBuzz.php';
class testFizzBuzz extends PHPUnit_Framework_TestCase
{
private $fizzBuzz;
public function setUp()
{
$this->fizzBuzz = new fizzBuzz();
}
public function testFizz()
{
$input = 3;
$expected = "Fizz";
$this->assertEquals($this->fizzBuzz->judge($input), $expected);
}
public function testBuzz()
{
$input = 5;
$expected = "Buzz";
$this->assertEquals($this->fizzBuzz->judge($input), $expected);
}
public function testFizzAndBuzz()
{
$input = 15;
$expected = "FizzBuzz";
$this->assertEquals($this->fizzBuzz->judge($input), $expected);
}
}
プログラムはこちらです。
<?php
class fizzBuzz
{
public function judge($input)
{
$result = $input;
if($input % 3 == 0 && $input % 5 == 0){
$result = "FizzBuzz";
}elseif($input % 3 == 0){
$result = "Fizz";
}elseif($input % 5 == 0){
$result = "Buzz";
}
return $result;
}
}
所感
本を読みながら見よう見真似でトライしてみたので本当にTDDになっているのかあれですが、
- テストファーストで取り組むとコードを書くのが楽しい(RED、GREENな状態を繰り返し、仕上げるプロセスがいい)
- 今までと明らかに違う考え方、設計の仕方になる(設計力のアップに繋がる気がした)
というのは感じました。
ただ、これは取り上げた問題がFizzBuzzだったせいかもしれませんが、実は最終的にテストコードは下記がいいかなと修正したりしてました。
<?php
require_once __DIR__. '/fizzBuzz.php';
class testFizzBuzz extends PHPUnit_Framework_TestCase
{
private $fizzBuzz;
public function setUp()
{
$this->fizzBuzz = new fizzBuzz();
}
public function testResult()
{
$this->assertEquals($this->fizzBuzz->judge(3), "Fizz");
$this->assertEquals($this->fizzBuzz->judge(9), "Fizz");
$this->assertEquals($this->fizzBuzz->judge(10), "Buzz");
$this->assertEquals($this->fizzBuzz->judge(50), "Buzz");
$this->assertEquals($this->fizzBuzz->judge(70), "Buzz");
$this->assertEquals($this->fizzBuzz->judge(90), "FizzBuzz");
$this->assertEquals($this->fizzBuzz->judge(97), 97);
}
}
このあたりはもっとテストコードの量を書いていくと色々見えてくるのかなと思いますので引き続きトライしてみます。
2017/08/03 追記
コメント頂いたことを参考にもう一度FizzBuzz問題にTDDでトライしてみました。
やはりちょっと独学では難しいのかなと思いつつも、PHPUnitについては理解が深まった気がしてます。
<?php
require_once __DIR__. '/fizzBuzz.php';
class testFizzBuzz extends PHPUnit_Framework_TestCase
{
private $fizzBuzz;
public function setUp()
{
$this->fizzBuzz = new fizzBuzz();
}
/**
* @dataProvider fizzProvider
*/
public function testFizz($input)
{
$this->assertEquals('Fizz', $this->fizzBuzz->testFizzBuzz($input));
}
public function fizzProvider()
{
return [[3],[9],[33]];
}
/**
* @dataProvider buzzProvider
*/
public function testBuzz($input)
{
$this->assertEquals('Buzz', $this->fizzBuzz->testFizzBuzz($input));
}
public function buzzProvider()
{
return [[5],[10],[100]];
}
/**
* @dataProvider fizzAndBuzzProvider
*/
public function testFizzAndBuzz($input)
{
$this->assertEquals('FizzBuzz', $this->fizzBuzz->testFizzBuzz($input));
}
public function fizzAndBuzzProvider()
{
return [[15], [45], [60]];
}
/**
* @dataProvider notFizzBuzzProvider
*/
public function testNotFizzBuzz($input)
{
$this->assertEquals($input, $this->fizzBuzz->testFizzBuzz($input));
}
public function notFizzBuzzProvider()
{
return [[7], [11], [98]];
}
}
<?php
class fizzBuzz
{
public function testFizzBuzz($input)
{
$res = $input;
if($input % 3 == 0 && $input % 5 == 0)
{
$res = "FizzBuzz";
}elseif($input % 3 == 0)
{
$res = "Fizz";
}elseif($input % 5 == 0)
{
$res = "Buzz";
}
return $res;
}
}