laravel 测试框架
2017-12-16 01:06
• 编辑本页
这里是以 laravel 5.5 为准
其中 phpUnit
的文档在 https://phpunit.de/manual/current/zh_cn/index.html
create
1
2
3
4
5
| # 创建测试用例
php artisan make:test XXControllerTest
# 创建单元测试
php artisan make:test XXUnitTest --unit
|
usage
HTTP
ex:
1
2
3
4
5
6
7
| public function testHttpSample()
{
array $json = [];
$this->json("PUT", $url, $json)
->assertExactJson(['errno' => 0]);
}
|
可用的 Assertions
Database
数据库部分在官方文档中很详细
主要的assertion就是检查数据库中是否存在某个条目,是否不存在某个条目,以及软删除的检查
1
2
3
4
5
6
7
| public function testDbSample()
{
$this->assertDatabaseHas('sample_table', [
'id' => '100',
'data' => 'sample'
]);
}
|
可用的 Assertions
Mocking
官方文档中在这部分只给出了少量的例子,我在实际应用中,有更多有用的用法,如 Log 对象:
1
2
3
4
5
6
7
8
9
10
| public function testLogSample
{
// 可以用此方法来模拟触发了错误后,
// 在代码中打印的error log是否和预期一致
// 以及从此推断出是否触发了预期的错误
Log::shouldRecive('error')->once()->with('error happened');
// run test...
// ...
}
|
Guzzle
Guzzle 作为发起 HTTP 子请求的重要模块,在 laravel 中的应用也应当被测试用例覆盖到。
Guzzle 提供自己的 Mock 方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| public function testGuzzleSample
{
$mockResponses = [
[
200, // code
['Content-Type' => 'application/json'], // headers
'{"errno": 0}' // body
]
[
500, // code
['Content-Type' => 'application/json'], // headers
'{"errno": 99}' // body
]
];
$mockHandler = new Client([
'handler' => HandlerStack::create(
(new MockHandler($mockResponses))
)
]);
$this->app->instance('GuzzleHttp\Client', $mockHandler);
// run tests...
// ...
// 在测试中,guzzle 会按顺序返回定义好的响应,来测试预期的用例。
}
|
扩展用法:想具体测试子请求中的输入与输出,可以写一个简单MVC类,输入预期子请求的输入(url, method, header, body),来动态生成例子中的 $mockResponses
数组。
env
在 laravel 项目的目录下,有一个 phpunix.xml
文件,在其中可以指定在测试运行时的一些环境变量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| <?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="bootstrap/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_HOST" value="127.0.0.1"/>
<env name="DB_PORT" value="3306"/>
<env name="DB_DATABASE" value="lavaral_test"/>
</php>
</phpunit>
|
我在项目中强制指定了测试时使用的数据库地址与名称,为了防止在生产环境中有人运行该脚本,在 .env 文件的设定下,对线上的数据库进行操作。
当然在官方的配置说明中提到,在测试运行时,如果有 .env.testing
的文件存在,在使用 --env=testing
参数限定下,.env.testing
会将 .env
文件覆盖
run
运行测试用例非常简单,只要在项目目录下执行 phpunit
文件即可。
phpunit
还有一些参数可供使用,其中我主要使用的是 --filter
,用来执行某个或者某批测试用例。
1
| ./vendor/bin/phpunit --filter=testHttp
|