# PhalApi 2.x 單元測試
## 測試驅動開發與PHPUnit
PhalApi推薦使用測試驅動開發最佳實踐,并主要使用的是PHPUnit進行單元測試。
> PHPUnit官網:[https://phpunit.de](https://phpunit.de),如需進行單元測試,請先安裝PHPUnit。
以下是在PhalApi下簡化后TDD步驟。
## 定義接口服務的函數簽名
當新增一個接口服務時,可先定義好接口服務的函數簽名,通俗來說,即確定類名和方法名,以及輸入、輸出參數、接口服務的名稱與描述等。
例如,對于獲取評論的接口服務,可以這樣定義。
```php
<?php
namespace App\Api;
use PhalApi\Api;
/**
* 評論服務
*/
class Comment extends Api {
public function getRules() {
return array(
'get' => array(
'id' => array('name' => 'id', 'type' => 'int', 'require' => true, 'min' => 1, 'desc' => '評論ID'),
),
);
}
/**
* 獲取評論
* @desc 根據評論ID獲取對應的評論信息
* @return int id 評論ID,不存在時不返回
* @return string content 評論內容,不存在時不返回
*/
public function get() {
}
}
```
通過在線接口詳情文檔,可以看到對應生成的接口文檔內容。

這樣就完成了我們偉大的第一步,是不是很簡單,很有趣?
## phalapi-buildtest自動生成測試代碼
接下來是為新增的接口類編寫對應的單元測試。單元測試的代碼,可以手動編寫,也可以使用phalapi-buildtest腳本命令自動生成。
生成的命令是:
```bash
phalapi$ ./bin/phalapi-buildtest ./src/app/Api/Comment.php App\\Api\\Comment > ./tests/app/Api/Comment_Test.php
```
保存的測試文件,統一放在tests目錄下,保持與產品代碼結構平行,并以“_Test.php”為后綴。
查看生成的單元測試代碼文件./tests/app/Api/Comment_Test.php,可以看到類似以下代碼:
```php
class PhpUnderControl_AppApiComment_Test extends \PHPUnit_Framework_TestCase
{
public $appApiComment;
protected function setUp()
{
parent::setUp();
$this->appApiComment = new App\Api\Comment();
}
protected function tearDown()
{
// 輸出本次單元測試所執行的SQL語句
// var_dump(DI()->tracer->getSqls());
// 輸出本次單元測試所涉及的追蹤埋點
// var_dump(DI()->tracer->getSqls());
}
/**
* @group testGet
*/
public function testGet()
{
$rs = $this->appApiComment->get();
$this->assertTrue(is_int($rs));
}
}
```
生成的骨架只是初步的代碼,還需要手動調整一下才能最終正常運行。例如需要調整bootstrap.php的文件引入路徑。
```php
require_once dirname(__FILE__) . '/../../bootstrap.php';
```
## 完善單元測試用例
最為重要的是,應該根據**構造-操作-檢驗(BUILD-OPERATE-CHECK)模式**編寫測試用例。對于Api接口層,還需要依賴[]()進行模擬請求。例如這里的:
```php
class PhpUnderControl_AppApiComment_Test extends \PHPUnit_Framework_TestCase
{
public function testGet()
{
// Step 1. 構造
$url = 's=Comment.Get';
$params = array('id' => 1);
// Step 2. 操作
$rs = PhalApi\Helper\TestRunner::go($url, $params);
// Step 3. 檢驗
$this->assertEquals(1, $rs['id']);
$this->assertArrayHasKey('content', $rs);
}
}
```
## 執行單元測試
使用phpunit,可以執行剛生成的測試文件。執行:
```bash
phalapi$ phpunit ./tests/app/Api/Comment_Test.php
```
會看到類似這樣的輸出:
```bash
PHPUnit 4.3.4 by Sebastian Bergmann.
.F
Time: 39 ms, Memory: 8.00Mb
There was 1 failure:
1) PhpUnderControl_AppApiComment_Test::testGet
Failed asserting that false is true.
/path/to/phalapi/tests/app/Api/Comment_Test.php:53
FAILURES!
Tests: 2, Assertions: 1, Failures: 1.
```
## 實現接口服務
在單元測試驅動的引導下,完成接口服務的具體功能,例如這里簡單地返回:
```php
<?php
namespace App\Api;
use PhalApi\Api;
class Comment extends Api {
public function get() {
return array('id' => 1, 'content' => '這是一條模擬的評論');
}
}
```
再次執行單元測試,便可通過了。
#### 溫馨提示:以上示例代碼可從[這里](https://github.com/phalapi/phalapi/commit/4eb124792cf6616035dcf937fe56e8e0fc5ebe77)查看。