ひよこテスト駆動開発 
- PHPとユニットテストとJenkinsとGitHubの話 - 
株式会社サイバード 大西啓太郎
自己紹介 
• 名前: 大西啓太郎 @Dollhyn_kei 
• 株式会社サイバード 
ゲーム事業本部 恋愛ゲーム技術チーム所属 
• エンジニア歴: 新卒1年目、半年が過ぎました 
• 普段のお仕事:  
・女性向け恋愛ゲームのサーバーサイド開発 
・最近はJavaScriptでクライアントも 
• プライベートな開発 
・Ruby > PHP 
・iOS, Androidのアプリなんかもやっています
実際にプロジェクトで 
ユニットテストをはじめて使った時 
にハマったことを 
簡単にまとめてみました。 
PHPUnitを使っています。
今日のアジェンダ 
• DBを使ったユニットテストとスローテス 
ト問題 
• Jenkins・GitHubを使ったテストの自動化 
• テストコードのアンチパターン 
• まとめ
DBを使ったユニットテ 
ストとスローテスト問題
チームの状況 
• 実DB(MYSQL)を使ってDB処理 
をテストしたい! 
• モックは使いたくない! 
• 本番に近いデータでテストがしたい
DBを使ったユニットテスト 
を実行出来る条件 
• DB/テーブルが存在する 
• マスタデータが存在する 
• 不要なレコードに干渉されない
ダメだったやりかた
1つのテストが走るたびに 
マスターデータが読み込まれる
1つのテストが終了する際には 
すべてデータを『TRUNCATE』して掃除する
流石にテストにかかる時間が 
長くなってしまった。
やっぱり、最初のロード処理と 
最後のTRUNCATE処理がボトルネックに
マスターデータの読み込みは 
一番最初に実行されるテストクラス 
(データセットアップ用クラス)でのみロードする 
テストが実行されるたびに 
新しいユーザーデータを発行することで 
『TRUNCATE』を不要にしました。
イメージ(以前) 
user_id: 001_t 
test_hoge() 
TRUNCATE 
LOAD 
ユーザー作成 
user_id: 001_t 
test_fuga() 
TRUNCATE 
LOAD 
ユーザー作成 
user_id: 001_t 
test_piyo() 
TRUNCATE 
LOAD 
ユーザー作成
user_id: 001_t 
test_hoge() 
TRUNCATE 
LOAD 
ユーザー作成 
user_id: 002_t 
test_fuga() 
ユーザー作成 
user_id: 003_t 
test_piyo() 
ユーザー作成 
イメージ(いま)
user_id: 001_t 
test_hoge() 
TRUNCATE 
LOAD 
ユーザー作成 
user_id: 002_t 
test_fuga() 
ここが浮きます 
ユーザー作成 
user_id: 003_t 
test_piyo() 
ユーザー作成 
イメージ(いま)
Jenkins・GitHubを使った 
ユニットテストの自動化
開発の進め方
出てきた問題点 
• 複数のユニットテストのジョブが回っている時に 
DBの整合性を保証ができない 
• ジョブを複数実行できず、待ちが発生して『プル 
リク』→『レビュー』→『マージ』→『デプロイ』 
をスムーズに行えない 
• マイグレーションが扱いにくい
解決策 
ジョブの実行毎に新しいDBを作る。
ビルド時の環境変数をもとに 
CREATE DATABASEを発行! 
CREATE DATABASE 
HOGE_${BUILD_NUMBER}
テストコードの 
アンチパターン
アンチパターン1 
『assertXXX(expected, actual)』 
の引数の順番が逆
期待値に検証対象の値が・・・
テストが失敗した際の 
メッセージの文脈が逆になってしまう
アンチパターン2 
1つのテストケースに 
複数のアサーション
なにをテストしたいかが 
よくわからない
1テストケース 
1メソッドを守ればスッキリ
アンチパターン3 
類似なテストケース
引数が違うだけ・・・
@dataProviderでスッキリ
まとめ
まとめ 
• まずは、PHPユニットのドキュメントをじっく 
り目を通す! 
• テストで扱うデータの初期化・破棄には気をつ 
ける! 
• Jenkinsでテストする場合はビルド毎に 
DBを作成する!
ご静聴、 
ありがとうございました

ひよこテスト駆動開発(PHPカンファレンス2014)