本系列教程所有的PHPUnit测试基于PHPUnit6.5.9版本,Lumen 5.5框架
目录结构
模块下的目录是符合Lumen的模块结构的
如:Controllers、Models、Logics等是Lumen模块目录下的结构目录
如果有自己的目录同级分配即可,如我这里的Requests
整体结构
├── BaseCase.php 重写过Lumen基类的测试基类,用于我们用这个基类做测试基类,后续会说明
├── bootstrap.php tests自动加载文件
├── Cases 测试用例目录
│ └── Headline 某测试模块
│ ├── logs 日志输出目录
│ ├── PipeTest.php PHPUnit流程测试用例
│ ├── phpunit.xml phpunit配置文件xml
│ └── README.md 本模块测试用例说明
├── ExampleTest.php 最原始测试demo
└── TestCase.php Lumen自带的测试基类
某模块的目录结构
Headline //某测试模块测试用例目录
├── Cache
├── Controllers
│ ├── ArticleTest.php
│ ├── ...
├── Listeners
│ └── MyListener.php
├── Logics
├── Models
│ ├── ArticleTest.php
│ ├── ...
├── README.md
├── Requests
│ ├── ArticleTest.php
│ ├── ...
├── logs //日志和覆盖率目录
│ ├── html
│ │ ├── ...
│ │ └── index.html
│ ├── logfile.xml
│ ├── testdox.html
│ └── testdox.txt
├── phpunit-debug-demo.xml //phpunit.xml案例
├── phpunit-debug.xml //改名后测试用的
└── phpunit.xml //正式用的xml配置
BaseCase.php
'token*',
'dev' => 'token*',
'prod' => '' //如果测试真实请填写授权token
];
/**
* 重写setUp
*/
public function setUp()
{
parent::setUp();
$this->seeder = false;
if (method_exists($this, 'factory')) {
$this->app->make('db');
$this->factory($this->app->make(Factory::class));
if (method_exists($this, 'seeder')) {
if (!method_exists($this, 'seederRollback')) {
dd("请先创建seederRollback回滚方法");
}
$this->seeder = true;
$this->seeder();
}
}
}
/**
* 重写tearDown
*/
public function tearDown()
{
if ($this->seeder && method_exists($this, 'seederRollback')) {
$this->seederRollback();
}
parent::tearDown();
}
/**
* 获取地址
* @param string $apiKey
* @param string $token
* @return string
*/
protected function getRequestUri($apiKey = 'list', $token = 'dev', $ddinfoQuery = true)
{
$query = "?token=" . static::TOKEN[strtolower($token)];
if ($ddinfoQuery) {
$query = $query . "&" . http_build_query(static::DDINFO);
}
return $apiUri = static::DOMAIN . static::API_URI[$apiKey] . $query;
}
}
phpunit-debug-demo.xml
本文件是我们单独为某些正在测试的测试用例,直接编写的xml,可以不用来回测试,已经测试成功的测试用例了,最后全部编写完测试用例,再用正式phpunit.xml即可,具体在运行测试阶段看如何指定配置
../../../app/Http/Controllers/Headline
../../../app/Http/Requests/Headline
../../../app/Models/Headline
../../../app/Models/Headline/ArticleKeywordsRelationModel.php
./
测试用例案例
define(ArticlesModel::class, function (Generator $faker) use (&$id, $words) {
$id++;
return [
'id' => $id,
'uri' => $faker->lexify('T???????????????????'),
'title' => $id == 263 ? "搜索" : $words[rand(0, sizeof($words) - 1)],
'authorId' => 1,
'state' => 1,
'isUpdated' => 0,
];
});
}
/**
* 生成模拟的数据,需seederRollback 成对出现
*/
public function seeder()
{
$articles = factory(ArticlesModel::class, 10)->make();
foreach ($articles as $article) { // 注意: article为引用对象,不是copy
if ($article->isRecommend) {
$article->recommendTime = time();
}
$article->save();
}
}
/**
* getArticleList 测试数据
* @return array
*/
public function getArticleListDataProvider()
{
return [
[1, "搜索", 1, 10, 1],
[2, "搜索", 1, 10, 0],
[2, null, 1, 10, 0],
[3, "搜索", 1, 10, 0],
[1, null, 1, 10, 1],
[2, null, 1, 10, 0],
[3, null, 1, 10, 0],
];
}
/**
* @dataProvider getArticleListDataProvider
*/
public function testGetArticleList($type, $searchText, $page, $pageSize, $expceted)
{
$rst = self::$model->getArticleList($type, $searchText, $page, $pageSize);
$this->assertGreaterThanOrEqual($expceted, sizeof($rst));
$rst = self::$model->getArticleCount($type, $searchText);
$this->assertGreaterThanOrEqual($expceted, $rst);
}
/**
* addArticle 测试数据
* @return array
*/
public function addArticleDataProvider()
{
return [
[
[
'id' => 273,
'uri' => 'dddddddddd0123'
],
'save',
0
],
[
[
'id' => 274,
'uri' => 'dddddddddd123'
],
'publish',
0
],
[
[
'id' => 275,
'uri' => 'dddddddddd456'
],
'preview',
0
],
];
}
/**
* @dataProvider addArticleDataProvider
*/
public function testAdd($data, $action, $expected)
{
$rst = self::$model->addArticle($data, $action);
if ($rst) {
self::$model::where('id', $rst)->delete();
}
$this->assertGreaterThanOrEqual($expected, $rst);
}
public function testGetArticleInfo()
{
$rst = self::$model->getArticleInfo(263, 0);
$this->assertGreaterThanOrEqual(1, sizeof($rst));
$rst = self::$model->getArticleInfo(2000, 1);
$this->assertEquals(0, sizeof($rst));
}
/**
* 回滚模拟的数据到初始状态
*/
public function seederRollback()
{
self::$model::where('id', '>=', 263)->where('id', '<=', 272)->delete();
}
}
运行测试
cd {APPROOT}/tests/Cases/Headline
# mv phpunit-debug-custom.xml -> phpunit-debug.xml
../../../vendor/bin/phpunit --verbose -c phpunit-debug.xml
参考
PHPUnit 5.0 官方中文手册