Edited at

PHPUnit + Guzzleで WebAPIのテストを書く

More than 1 year has passed since last update.

今までWebAPIのテストはFrisby + jasmine-nodeで書いていましたが、PHPでも書いてみます。

なお、WebAPIにリクエストするライブラリとしてGuzzleを利用してみたいと思います。Guzzleは直感的でかつ、非同期や様々なオプションに対応していてすばらしいです。

WebUIのテストについてはこちら


前提


  • composerがインストールされている

  • Mac(El capitan)

ホームディレクトリ内にtestというフォルダを作ってその中で作業するものとします。


準備


ライブラリのダウンロード

#ディレクトリ作成

cd ~/
mkdir test
cd test

#phpunitとguzzleのインストール
composer require phpunit/phpunit
composer require guzzlehttp/guzzle


guzzeleはVer5以上からguzzle/guzzleからguzzlehttp/guzzleになったそうです。



テストを書く(テスト対象)

テスト対象のAPIとして下記のようなものを用意してみました。

これを、http://localhost/test/api.phpとして参照できるようにしています。

ポイントとしては、


  • POST/GETに対応

  • Dataは配列を戻します(DBレスポンスのイメージ)

となっていて、これをどう取得、テストできるか試してみます。

<?php

$name = "xxx";

if(isset($_POST['name'])) $name = $_POST['name'];
if(isset($_GET['name'])) $name = $_GET['name'];

$data = [
['name'=>'hoge','age'=>'30'],
['name'=>'foo','age'=>'20']
];

$response = [];
$response['status'] = "OK";
$response['message'] = "Hello ".$name.".";
$response['data'] = $data;

header('Content-type: application/json');
echo json_encode($response);

こんなJSONが戻ります。



{
"status":"OK",
"message":"Hello xxx.",
"data":
[
{"name":"hoge","age":"30"},
{"name":"foo","age":"20"}
]
}


テストを書く(テストコード)

Guzzleを利用すると、非常に直感的でわかりやすいコードで書けます。

GETもPOSTもほぼ同じコードでかけることが分かります。


guzzle5まではPOSTのパラメータ名はbodyだったようですが、6からはform_paramsとなっているようです。


<?php

class sampleTest extends PHPUnit_Framework_TestCase
{
public function testWebAPI_GET()
{
//
$client = new GuzzleHttp\Client();

//get
$res = $client->get('http://localhost/test/api.php',[
'query'=>[
'name'=>'POO',
'email'=>'poo@poo.com',
],
]);

//取得 第2引数にtrueつけると連想配列
$obj = json_decode($res->getBody());

//取得
$status = $obj->status;
$message = $obj->message;
$rows = $obj->data;

//loop(参考)
foreach ($rows as $row) {
//echo $row->name;
}

//評価
$this->assertEquals("OK",$status);
$this->assertEquals("Hello POO.",$message);
$this->assertRegExp('/^Hello.+\.$/',$message);
$this->assertCount(2,$rows);
}

public function testWebAPI_POST()
{
//
$client = new GuzzleHttp\Client();

//post
$res = $client->post('http://localhost/test/api.php',[
'form_params'=>[
'name'=>'POO',
'email'=>'poo@poo.com',
],
]);

//取得 第2引数にtrueつけると連想配列
$obj = json_decode($res->getBody());

//取得
$status = $obj->status;
$message = $obj->message;
$rows = $obj->data;

//loop(参考)
foreach ($rows as $row) {
//echo $row->name;
}

//評価
$this->assertEquals("OK",$status);
$this->assertEquals("Hello POO.",$message);
$this->assertRegExp('/^Hello.+\.$/',$message);
$this->assertCount(2,$rows);
}
}


実行

cd ~/test

./vendor/bin/phpunit --colors tests/

OK (2 tests, 6 assertions)

グリーンで完了しました。


最低限のassertメソッド


  • assertEquals(\$expect,\$var) $expectと$varが等しいか?

  • assertRegExp(\$ptn, \$var) 正規表現にマッチするかどうか?

  • assertNull(\$var)

  • assertTrue(\$var)

  • assertFalse(\$var)

  • assertCount(\$num,\$array)

  • assertEmpty(\$array)


LaravelのQueryBuilderやEloquentを使う

UIやAPIのテストを実行した結果、DBに正常に値が書き込まれているかをチェックしたくなります。もちろん普通にPDOでコードを書いてもいいですが、Laravelに慣れてる場合、QueryBuilderやEloquentが使いたくなります。その場合は、こちらを参考にしてください。