php测评模块,PHPUnit实践三(构建模块化的测试单元)

本系列教程所有的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

namespace Test;

use Illuminate\Database\Eloquent\Factory;

class BaseCase extends TestCase

{

protected $seeder = false;

const DOMAIN = "http://xxx.com";

const API_URI = [];

const TOKEN = [

'local' => '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即可,具体在运行测试阶段看如何指定配置

bootstrap="../../bootstrap.php"

convertErrorsToExceptions="true"

convertNoticesToExceptions="false"

convertWarningsToExceptions="false"

colors="true">

../../../app/Http/Controllers/Headline

../../../app/Http/Requests/Headline

../../../app/Models/Headline

../../../app/Models/Headline/ArticleKeywordsRelationModel.php

./

highLowerBound="70"/>

测试用例案例

/**

* Created by PhpStorm.

* User: qikailin

* Date: 2019-01-29

* Time: 11:57

*/

namespace Test\Cases\Headline\Articles;

use App\Http\Controllers\Headline\ArticleController;

use App\Models\Headline\ArticleCategoryRelationModel;

use App\Models\Headline\ArticleContentModel;

use App\Models\Headline\ArticleKeywordsRelationModel;

use App\Models\Headline\ArticlesModel;

use Faker\Generator;

use Illuminate\Http\Request;

use Test\BaseCase;

class ArticleTest extends BaseCase

{

private static $model;

public static function setUpBeforeClass()

{

parent::setUpBeforeClass();

self::$model = new ArticlesModel();

}

/**

* 生成factory faker 数据构建模型对象

* @codeCoverageIgnore

*/

public function factory($factory)

{

$words = ["测试", "文章", "模糊", "搜索"];

$id = 262;

$factory->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

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值