## http測試
這篇主要講 `http測試`,參考了[laravel-# HTTP 測試](https://learnku.com/docs/laravel/7.x/http-tests/7506)
[phpunit文檔](http://www.phpunit.cn/manual/7.0/zh_cn/installation.html)
## 安裝phpunit
可以通過 `PHAR` 方式,也可以通過 `composer`。
用 `composer` 吧,更方便。
```
composer require phpunit/phpunit
```
安裝成功后, 將會有 `vendor/bin/phpunit` 文件。

## 創建phpunit.xml
`phpunit` 的配置文件,當你運行`phpunit`的時候, 自動在你這個目錄找配置文件。
一次性測試多個文件,是靠 `phpunit.xml` 來配置的。
```
<?xml version="1.0" encoding="UTF-8"?>
<!-- 版本 編碼 聲明-->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/schema/9.3.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<!-- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" -->
<!-- xsi:noNamespaceSchemaLocation: 不用命名空間加載xsd文件 更詳細我也不懂, 詳細見: https://www.runoob.com/schema/schema-tutorial.html -->
<!-- bootstrap: 測試之前加載的文件 -->
<!-- color: 啟用顏色 -->
<testsuites>
<testsuite name="php_frame">
<!-- name套件名稱 就是"組" 可以有多個套件 -->
<!-- 聲明tests文件夾 后綴是Test.php是測試文件 -->
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
</phpunit>
```
## 創建core/TestCase.php
封裝 `phpunit`。
```
<?php
namespace core;
use core\request\PhpRequest;
use PHPUnit\Framework\TestCase as BaseTestCase;
class TestCase extends BaseTestCase
{
protected $response; // 路由請求響應的結果
// 基境共享
protected function setUp(): void
{
require_once __DIR__ . '/../app.php';
}
// 調用路由
public function call($uri,$method)
{
\App::getContainer()->bind(\core\request\RequestInterface::class,function () use ($uri,$method){ // 將request綁定到容器
return PhpRequest::create($uri,$method);
});
return $this->response = app('response')->setContent( // 響應
app('route')->dispatch( // 路由
\App::getContainer()->get(\core\request\RequestInterface::class) // 調用綁定request
)
);
}
// get方式調用
public function get($uri,$params = [])
{
$this->call($uri,'GET',$params);
return $this;
}
// post方式調用
public function post($uri,$params = [])
{
$this->call($uri,'POST',$params);
return $this;
}
// 斷言狀態碼是否一樣
protected function assertStatusCode($status)
{
$this->assertEquals($status, $this->response->getStatusCode());
return $this;
}
// ... 其他斷言不寫了 參考的斷言狀態碼
// 代理模式 訪問response
public function __call($name, $arguments)
{
return $this->response->{$name}(... $arguments);
}
}
```
至此已經完成了。
## 運行
### 創建測試文件 tests/ExampleTest
```
<?php
class ExampleTest extends \core\TestCase
{
// 測試config
public function testDatabaseDefault()
{
// 斷言內容是 "mysql_one"
$this->assertEquals('mysql_one',
config('database.default')
);
}
// 測試路由
public function testGetRoute()
{
$this->get('/hello')
->assertStatusCode(200); // 斷言狀態碼是200
}
// 測試路由
public function testPostRoute()
{
$res = $this->get('/hello');
// 斷言返回的內容是 "你在訪問hello"
$this->assertEquals('你在訪問hello',
$res->getContent());
}
}
```
## 運行測試
```
vendor\bin\phpunit
```

- 前言
- 基礎篇
- 1. 第一步 創建框架目錄結構
- 2. 引入composer自動加載
- 3. php自動加載 (解釋篇)
- 4. 創建容器 注冊樹模式
- 5. 關于psr規范解釋
- 6. 關于"容器" "契約" "依賴注入" (解釋篇)
- 7. 添加函數文件helpers.php
- 8. 初始化請求(Request)
- 9. 響應 (Response)
- 10. 路由一 (路由組實現)
- 11. 路由二 (加入中間件)
- 12. 配置信息 (類似laravel)
- 13. 數據庫連接 (多例模式)
- 14. 查詢構造器 (query builder)
- MVC實現
- M 模型實現 (數據映射 + 原型 模式)
- C 控制器實現 + 控制器中間件
- V 視圖實現 (Laravel Blade 引擎)
- V 視圖切換成 ThinkPhp 模板 引擎)
- 其他輪子
- 日志
- 自定義異常 (異常托管)
- 單元測試 (phpunit)
- 替換成swoole的http服務器
- 協程上下文解決request問題
- qps測試
- 發布到packagist.org