thinkphp5.0 使用 phpunit 进行单元测试
2020-02-22 10:30:00 来源: 评论:0 点击:
起步
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 appcoremodeluserUser;
use PHPUnitFrameworkTestCase;
use thinkConfig;
use thinkDb;
// 初始化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:wamp64binphpphp7.2.4php.exe E:/workspace/gift_mall_official/vendor/phpunit/phpunit/phpunit --no-configuration testsThinkableTest E:workspacegift_mall_officialtestsThinkableTest.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 GuzzleHttpClient;
use PHPUnitFrameworkTestCase;
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的尝试,我还是想用自己的整合方式进行单元测试。
相关热词搜索:
上一篇:研发流程优化实践
下一篇:hydra -一款好用的ssh破解密码工具
评论排行
- ·手机“双卡双待”,卡一...(3)