phpunit 支持命名空间_thinkphp5.0 使用 phpunit 进行单元测试

b2e1a06764a032257dd5d57097760510.png

起步

thinkphp5.0 是 tp 发展路线第一个支持 composer 的。tp 有自己的载入机制,composer 也有自己的载入机制。

官方提供了 think-testing 组件可以通过 composer require topthink/think-testing 1.* 安装,但我对这个测试组件不是很满意,原因是它每个测试都是模拟成 http 请求。这也就意味着对于一些特定函数,还得封装到控制器中或者路由,该控制器还得控制它生产环境不能对外开放。

另一个原因是可读性会变差,在单元测试文件中只是能看到请求体和响应体,具体测试的函数,测试的细节都看不到。于是我尝试寻找可以独立测试tp或者tp项目,测试颗粒更细的测试单元。(当然是可行的,不然我也不会写这篇文章)

使用 phpunit 单元测试

安装:

composer require --dev phpunit/phpunit

进行安装,我安装的版本是 8.5.2 ,项目是运行在 php7.2 环境的。tp 和 composer 都有自己的载入机制,于是我决定都试一试。

使用 composer 载入机制

composer 的载入主要是针对 vendor 文件内的第三方依赖。 但对于 vendor 外的文件需要指定载入空间映射的文件路径,在 composer.json 中添加 autoload 字段:

{
"require-dev": {
"phpunit/phpunit": "8.5.2"
},
"autoload": { # 设置命名空间映射
"psr-4": {
"app\\": "application/",
"basic\\": "extend/basic",
"traits\\": "extend/traits",
"tests\\": "tests/"
}
}
}

通过 composer dumpautoload 让配置生效。单元测试的文件按规范放在项目目录 tests 文件夹中:

<?php 
// tests/ThinkableTest.php
namespace tests;
use app\core\model\user\User;
use PHPUnit\Framework\TestCase;
use think\Config;
use think\Db;
// 初始化app
define('APP_PATH', dirname(__DIR__) . '/application/');
define('VENDOR_PATH', APP_PATH . 'vendor_fake' . DIRECTORY_SEPARATOR); // 让tp不用自己的载入机制,而使用composer的autoload
include dirname(__DIR__) . '/thinkphp/base.php';
Config::load(APP_PATH . '/database.php', 'database');
class ThinkableTest extends TestCase
{
public function testFrameworkVersion() { // 检查 tp 版本
$this->assertTrue(version_compare(THINK_VERSION, '5.0', '>='));
$this->assertTrue(version_compare(THINK_VERSION, '6.0', ' }
public function testDbConnect() { // 数据库是否能连接
$tables_count = Db::execute('show tables');
$this->assertTrue($tables_count > 0);
}
public function testModelUser() { // 模型是否可用
$model = new User();
$user = $model->limit(1)->find();
$this->assertTrue($user != null);
}
}

运行结果:

D:\wamp64\bin\php\php7.2.4\php.exe E:/workspace/gift_mall_official/vendor/phpunit/phpunit/phpunit --no-configuration tests\ThinkableTest E:\workspace\gift_mall_official\tests\ThinkableTest.php --teamcity
PHPUnit 8.5.2 by Sebastian Bergmann and contributors.
Time: 89 ms, Memory: 6.00 MB
OK (3 tests, 4 assertions)
Process finished with exit code 0

能运行成功归功于这几行载入 tp 的依赖,这几行代码可以提取到公共文件中:

// 初始化app
define('APP_PATH', dirname(__DIR__) . '/application/');
define('VENDOR_PATH', APP_PATH . 'vendor_fake' . DIRECTORY_SEPARATOR); // 让tp不用自己的载入机制,而使用composer的autoload
include dirname(__DIR__) . '/thinkphp/base.php';
Config::load(APP_PATH . '/database.php', 'database');

其中定义 VENDOR_PATH 并设置了一个不存在的路径,是为了使用 composer 自身的自动载入。

模拟请求API测试

模拟请求就可以借助 think-testing 组件了,但我还是不打算用它,我选择了 GuzzleHttp 依赖进行,以下是测试样例:

<?php 
// tests/SimpleAPITest.php
namespace tests;
use GuzzleHttp\Client;
use PHPUnit\Framework\TestCase;
class SimpleAPITest extends TestCase {
private $client = null;
public function __construct(?string $name = null, array $data = [], string $dataName = '')
{
parent::__construct($name, $data, $dataName);
$this->client = new Client([
'base_uri' => 'http://localhost'
]);
}
public function testWebIndex() {
$resp = $this->client->get('/');
$this->assertEquals(200, $resp->getStatusCode());
}
}

更多 GuzzleHttp 的使用方法查看文档: https://guzzle-cn.readthedocs.io/zh_CN/latest/

总结

本文介绍了如何用原生的 phpunit 针对 thinkphp5.0 进行单元测试,这里重点是如何载入tp框架又要避免重复引入依赖。

使用tp自身的指令进行单元测试是未来发展的趋势,tp6.0 就比较的成熟。而对于tp5.0 ,它是第一次对composer的尝试,我还是想用自己的整合方式进行单元测试。

5528469ba7e66b0ba78d93e4fe00fbdc.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值