LoginSignup
2
2

More than 5 years have passed since last update.

TDD(テスト駆動開発)でFizzBuzz問題を解いてみる

Last updated at Posted at 2017-08-01

はじめに

以下本を読みながら初めてテストファーストでプログラムを書いてみました。
いきなり難しいお題だと着地しないかも、と不安だったので、誰でも知ってるFizzBuzz問題を採用してます。
なお、参考にした本は下記です。
(書籍内ではボーリングのスコア計算をTDDで扱っています。いきなりこれだとちょっとできるか不安でしたw)

[参考]これからはじめるTDD テスト駆動開発入門 ThinkIT Books

環境

以前こちらにまとめているのと同様の環境を利用しています。

[参考]Dockerを使い手軽にPHPUnitをはじめる

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;
    }
}
2
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2