2016.12.15
Codeceptionの導入事例
こんにちは。次世代システム研究室のS.Iです。
次世代システム研究室ではシステム開発を行う上で様々な取り組みを行っています。
現在進行中のプロジェクトでは、Codeceptionを利用して生産性や品質を向上させる取り組みを行っています。ここではその導入事例について触れていきたいと思います。
Codeceptionによるテストの自動化
概要
CodeceptionはテストフレイムワークでLaravel5やsymfony、Yii2、Zend FrameworkなどのPHP Frameworkをサポートしています。また、コードジェネレータが提供されているため、簡単なサンプルのテストコードを素早く生成することが出来ます。
コードを生成する
「./codecept list」で以下のように各コマンドを表示することができます。まずは「generate:suite」設定ファイルを作成し、各テストプログラムを生成していきます。
./codecept list generate generate:cept Generates empty Cept file in suite generate:cest Generates empty Cest file in suite generate:environment Generates empty environment config generate:feature Generates empty feature file in suite generate:groupobject Generates Group subscriber generate:helper Generates new helper generate:pageobject Generates empty PageObject class generate:phpunit Generates empty PHPUnit test without Codeception additions generate:scenarios Generates text representation for all scenarios generate:stepobject Generates empty StepObject class generate:suite Generates new test suite generate:test Generates empty unit test file in suite
導入事例
方針を検討する
テストプログラムは品質を維持し続けるために継続的なメンテナンスが必要です。細かい実装をしてしまうとメンテナンスにコストがかかったり、実装者しかわからない状態となり結果的に利用されなくなってしまいます。そこで、今回は自動化する範囲を以下に限定し導入することにしました。
画面系
アクセプタンステスト
※画面の描画と一連の入力から完了までのフローが正常に動作できることを確認する
API系
ファンクションテスト
※各APIごとに正常系と返却される全てのエラーコードが想定どおり返却されることを確認する
ユニットテスト
※各APIごとの入力のヴァリデーションが想定どおり実行できることを確認する
導入時のポイント
進めていく上でわかってきたポイントを以下でいくつか紹介します。
ポイント1:WebdriverはPhp Browserを利用すべし
要否に応じて使い分けが必要になりますが、「phantomjs」や「Selenium2」などの Webdriverを利用する場合は高機能な反面、インストールや実行時のプロセスの管理などが面倒なのと、実行が遅いのが気になります。シンプルなことしかしないとわりきって「Php Browser」を利用するのがおすすめです。
Php Browser
メリット:PHP,Curlさえあればすぐ実行できる、実行が早い
デメリット:Javascriptが利用できない
ポイント2:CeptよりCestを利用すべし
テストプログラムの実装パターンで「Cept」と「Cest」があります。CeptはシンプルにCestはオブジェクト指向的な実装になります。
Cept
<?php $I = new AcceptanceTester($scenario); $I->wantTo('perform actions and see result'); $I->amOnPage('/login'); $I->fillField('user_id','aaa'); $I->fillField('password','aaa'); $I->click('ログイン'); $I->see('TOP');
Cest
<?php class LoginCest { public function login(\AcceptanceTester $I) { $I->wantTo('perform actions and see result'); $I->amOnPage('/login'); $I->fillField('user_id','aaa'); $I->fillField('password','aaa'); $I->click('ログイン'); $I->see('TOP'); } }
Cestではアノテーションを利用し、より体系だったテストプログラムを実装することができます。たとえば、以下の例ではDataproviderを利用して、あるメソッドに対して指定したパラメータ分の実行を行うことができます。また、他にも@beforeや@afterを利用することで前提条件などを設定することができ、非常に便利です。※二つ目のメソッドはメソッド名に「_」を利用することでテスト実行が不要なことをあらわしています。
サンプル実装
/** * 正常系テスト * @param ApiTester $I * @dataprovider _type */ public function check(ApiTester $I, \Codeception\Example $example) { $I->wantTo('api execute test. type ' . $example['type']); $I->haveHttpHeader('Content-Type', 'application/json'); $I->sendPOST('api/a', ['type' => $example['type']]); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContainsJson(['result' => 'success']); $I->seeResponseContainsJson(['data1' => 'a']); $I->seeResponseContainsJson(['data2' => 'b']); } public function _type() { return [ ['type'=>"a"], ['type'=>"b"], ['type'=>"c"], ['type'=>"d"], ['type'=>"e"], ]; }
実行結果
Codeception PHP Testing Framework v2.2.7 Powered by PHPUnit 4.8.31 by Sebastian Bergmann and contributors. Api Tests (5) ------------------------------------------ ✔ TestGetCest: Api execute test. type a (0.54s) ✔ TestGetCest: Api execute test. type b (0.15s) ✔ TestGetCest: Api execute test. type c (0.15s) ✔ TestGetCest: Api execute test. type d (0.14s) ✔ TestGetCest: Api execute test. type e (0.14s) --------------------------------------------------------
ポイント3:APIの実行結果を解析すべし
JSONでやり取りするようなAPIは「seeResponseContainsJson」で実行の確認と「grabDataFromResponseByJsonPath」で、API Aの実行結果をパースして、API Bの実行に利用することができます。
$I->wantTo('perform actions and see result'); $I->haveHttpHeader('Content-Type', 'application/json'); //api a $I->sendPOST('/api/a', []); $id = $I->grabDataFromResponseByJsonPath('$.data')[0]['id']; //api b $I->sendPOST('/api/b', ['id'=>$id]); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContainsJson(['result' => 'success']);
最後に
実装時にテストプログラムを作成しておいたおかけで、全体的に影響のある修正をした際にもすぐに確認を取ることができました。引き続き、効果的な手法がないか追っていければと思います。
次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。
グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。
Follow @GMO_RD