読者です 読者をやめる 読者になる 読者になる

Codeceptionを使ってTDD Boot Camp 大阪 2.0/課題に挑戦してみた

PHP Codeception

しばらくはCodeceptionネタが続きます。

社内でTDDの勉強会をする機会があり、課題としてTDD Boot Campのものを利用させていただきました。
どうせなら、ということでCodeceptionを使って挑戦してみました。

ユニットテストのみで、あまりCodeceptionの旨味は引き出せていないとは思いますが、何かの参考になればと思い、公開してみます。

工夫したポイント

課題のところどころに出てくる、以下のような、「出力する」。
私はこれを標準出力に出力すると理解して進めました。

想定外のもの(硬貨:1円玉、5円玉。お札:千円札以外のお札)が投入された場合は、投入金額に加算せず、それをそのまま釣り銭としてユーザに出力する。

標準出力をテストする場合、PHPUnit出力内容のテストで説明されているexpectOutputString()で実現可能なのですが、

<?php
function testOutput()
{
    $this->expectOutputString("foo");
    $obj->echoFoo();

    $this->expectOutputString("bar");
    $obj->echoBar();
}

のように1メソッド内で連続して使用することができないため、不便です。*1

これをCodeceptionのヘルパーを利用することで解決しました。
ヘルパーについての詳しい説明はModulesAndHelpersにあります。

https://github.com/piccagliani/TddStudy/blob/master/tests/_helpers/CodeHelper.php

<?php
namespace Codeception\Module;

// here you can define custom functions for CodeGuy 

class CodeHelper extends \Codeception\Module
{
    public function seeInStandardOutput($expect, \Closure $func)
    {
        ob_start();
        ob_implicit_flush(false);
        $result = $func();
        $output = ob_get_contents();
        ob_end_clean();
        $this->assertContains($expect, $output);
        return $result;
    }
}

ヘルパーに追加した機能を利用できるようにするためには、vendor\bin\codecept.bat buildする必要があります。

これを、以下のように使います。(VendingMachineTestから抜粋)

<?php
        $insertMoney = function($amount) use ($V) {
            return function() use ($V, $amount) {
                $V->insertMoney(new Money($amount));
            };
        };

        $I->expect("1円玉が投入された場合は、それをそのまま釣り銭としてユーザに出力する。");
        $I->seeInStandardOutput("釣り: 1円", $insertMoney(1));

        $I->expect("5円玉が投入された場合は、それをそのまま釣り銭としてユーザに出力する。");
        $I->seeInStandardOutput("釣り: 5円", $insertMoney(5));

最後に

つい先日、バージョン1.6.4がリリースされました。
テストコードのリファクタリングに役立つPageObjectsStepObjectが追加されたり、Extensionの仕組みが導入されたりしているようです。

また、ちらほらtwitterやブログ等でCodeceptionの日本語情報を取り上げる方が増えて来たように感じます。
日本でも流行の兆しが見えて来たか。今後が楽しみです。

*1:間違っていたら教えてください