laravel 测试框架

2017-12-16 05: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#

  • json
  • get
  • post
  • put
  • delete

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 文件即可。

1
./vendor/bin/phpunit

phpunit 还有一些参数可供使用,其中我主要使用的是 --filter,用来执行某个或者某批测试用例。

1
./vendor/bin/phpunit --filter=testHttp

标签:php

点击加载Disqus评论
Creative Commons © 2013 — 2018 xiao_cang | Theme based on fzheng.me & NexT | Hosted by Netlify