Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
一人でゲームをリリース
するための自動化
PHPUnit編
~~ 目指せCoverage 100% ~
すずな株式会社  代表取締役  中村悟
PHPカンファレンス関西2013 (2013/6/1)
✤ 名前  中村悟
✤ 所属  すずな株式会社  代表取締役
✤ Twitter @cloned ((読み方::  クローンディー))
✤ Blog http://d.hatena.ne.jp/cloned/
✤ 略歴
自己紹介
営業マン
派遣エンジニア
✤ インサイド  クリプト  よかったら遊んでね♪
✤ https://play.google.com/store/apps/details?
id=com.suzna.labyrinth.android
44//2255  ゲームをリリースしました
✤ 誰が企画するのか
✤ 誰が開発するのか
✤ 誰がテストするのか
✤ 誰がサーバ用意するのか
✤ 誰が((rryy
“一人でやる”ゲーム開発
あなたです
✤ 私が企画します
✤ 私とSymfonyが開発します
✤ PHPUnitがテストします
✤ Chefがサーバ用意します
✤ Jenkinsが(ry
“一人でやる”には分身が必要
上記、すずなで実際に利用しているツールなどの一部です
✤ 私が企画します
✤ 私とSymfonyが開発します
✤ PHPUnitがテストします
✤ Chefがサーバ用意します
✤ Jenkinsが(ry
“一人でする”には分身が必要
時間が短いので今日はココを話します♪
✓ --coverage-htmlして現状を確認
✓ time()やmt_rand()などを使うコードもテスト
✓ 複雑なオブジェクトを使うコードもテスト
✓ ファイルシステムを使うコードもテスト
Coverage 100%への道のり※注11
※注11  ここでのCoverage 100%はすべてのケースという意味ではなく
すべてのコードがテストで実行されるという意味です
--coverage-htmlして
現状を確認
✤ 弊社プロジェクトの場合
✤ 開発のみで使うツール24% 全体95%
--coverage-htmlして現状を確認
✤ とはいえ、100%のモジュールもたくさ
んあります!!
--coverage-htmlして現状を確認
✤ --coverage-htmlの出力を見れば、どこが
テストできてないか一目瞭然
✤ 人間の目では判り難い間違いも・・・
--coverage-htmlして現状を確認
✤ --coverage-htmlの出力を見れば、どこが
テストできてないか一目瞭然
✤ 人間の目では判り難い間違いも・・・
--coverage-htmlして現状を確認
rroollllbbaakkaa??
✤ すべてのコードをテストで実行していれ
ば単純なttyyppooや、きっと動く筈(でも動
かない)なコードの多くを排除できる
✤ まずはここから始めましょう
--coverage-htmlして現状を確認
time()やmt_rand()などを
使うコードもテスト
time()やmt_rand()などを使うコードもテスト
class Campaign
{
public function isEnabled()
{
// キャンペーンは5/31まで!
return time() < strtotime('2013-06-01');
}
}
class CampaignTest extends PHPUnit_Framework_TestCase
{
public function testIsEnabled()
{
えーっと・・・time()ってどうやってテストするんだっ!
}
}
テストコード
time()やmt_rand()などを使うコードもテスト
class Campaign
{
public function isEnabled()
{
// キャンペーンは5/31まで!
return $this->getNow() < strtotime('2013-06-01');
}
protected function getNow()
{
return time();
}
}
✤ せめてメソッドを分ける
time()をgetNow()に移動
time()やmt_rand()などを使うコードもテスト
class CampaignTest extends PHPUnit_Framework_TestCase
{
public function testIsEnabled()
{
$c = $this->getMock('Campaign', array('getNow'));
$c->expects($this->at(0))
->method('getNow')
->will($this->returnValue(strtotime('2013-05-31')));
$c->expects($this->at(1))
->method('getNow')
->will($this->returnValue(strtotime('2013-06-01')));
$this->assertTrue($c->isEnabled(), 'キャンペーン中');
$this->assertFalse($c->isEnabled(), 'キャンペーン終了');
}
}
✤ メソッドが分かれていればテスト可能
複雑なオブジェクトを使う
コードもテスト
複雑なオブジェクトを使うコードもテスト
class Kansai extends ContainerAware
{
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getKansai($id)
{
return $this->container->get('doctrine')
->getManager()
->getRepository('PhpConBundle:Kansai')
->find($id);
}
}
✤ こんな“関西さん”をDDBBから取得する
Symfonyのコードがあったとして
複雑なオブジェクトを使うコードもテスト
public function getKansai($id)
{
return $this->container->get('doctrine')
->getManager()
->getRepository('PhpConBundle:Kansai')
->find($id);
}
✤ どうやってdoctrineを生成するんだ!?
✤ 仕方ない、DBにデータ入�れてテストする
か。。。となりがち
✤ これをユニットテストするのは苦しい
複雑なオブジェクトを使うコードもテスト
$doctrine = $this->getMockBuilder(
'DoctrineBundleDoctrineBundleRegistry')
->disableOriginalConstructor()
->setMethods(array('getManager'))
->getMock();
✤ disableOriginalConstructor()  を使ってコンス
トラクタをスキップしてモックを作る
✤ time()のケースと同じくモックを使ったテ
ストがすぐに始められる
✤ ただし・・・
✤ このメソッドは多くのことをやり過ぎなのでもっと分解しましょう
✤ 実際のデータベースを使ったファンクショナルテストも書きましょう
ファイルシステムを使う
コードもテスト
ファイルシステムを使うコードもテスト
✤ vfsStreamを使いましょう!
✤ PHPUnitにドキュメントがあります
✤ http://phpunit.de/manual/3.8/ja/test-
doubles.html
✤ vfsStreamのGitHub
✤ https://github.com/mikey179/vfsStream
ファイルシステムを使うコードもテスト
✤ こんな感じで、仮想のURLに対してファイ
ル操作してテストできる
public function testAText() {
vfsStreamWrapper::register();
vfsStreamWrapper::setRoot(new vfsStreamDirectory('test_dir'));
$aText = vfsStream::url('test_dir') .'/a.txt';
touch($aText);
$this->assertTrue(is_file($aText));
}
まとめ
✤ Coverage 100%を目指すためのTTiippssをほん
の少し紹介しました。
✤ 本番環境でPHP Parse errorとかPHP Fatal
errorとかを出すの、やめましょう。やめま
しょう。やめましょう。
ご清聴ありがとう
ございました

More Related Content

一人でゲームをリリースするための自動化 PHPUnit編 ~目指せCoverage 100%~