php 进阶 自测,进阶篇:如何为ThinkPHP5编写优质的单元测试?

前言

在项目开发中,需要使用到ThinkPHP 5,为了编写单元测试,解决了几个难题,特此纪录分享一下。

难点1:TP5自带的单元测试感觉不好用,如何使用纯粹的原生PHPUnit?

在看云上,有TP5官方关于单元测试的使用说明,链接是:https://www.kancloud.cn/manual/thinkphp5/182511

但上面的说明过于简单,对于实际使用帮助有限。

对于一直钟情于自动化单元测试以及PHPUnit原生单元测试的我,决定对此优化一番,引入并在ThinkPHP 5下使用原生PHPUnit。

第一步:准备工作

在tests目录下,创建一个phpunit目录,然后创建两个文件:测试启动文件bootstrap.php和单元测试的配置文件phpunit.xml。

测试启动文件bootstrap.php,可以参考项目的启动文件,复制过来后调整下,例如这样:

// 定义应用目录

define('APP_PATH', __DIR__ . '/../../application/');

define('APP_DEBUG', true); //开启调试模式

define("APP_STATUS", "tests"); //定义为本地环境

define("RUNTIME_PATH", __DIR__ . "/../../runtime/"); //定义缓存目录

require APP_PATH . '/define.php';

// ThinkPHP 引导文件

// 加载基础文件

require __DIR__ . '/../../thinkphp/base.php';

// 加载应用

\think\Loader::addNamespace('app', APP_PATH);

// 兼容旧版本的PHPUnit

if (!class_exists('PHPUnit_Framework_TestCase')) {

class PHPUnit_Framework_TestCase extends PHPUnit\FrameWork\TestCase {

}

}

// 手动再引入一次测试配置

\think\Config::load(APP_PATH . '/tests/test.php');

// 手动引入框架和应用的函数

require_once APP_PATH . '../thinkphp/helper.php';

require_once APP_PATH . 'common.php';

对于phpunit.xml配置文件,可以这样写:

backupStaticAttributes="false"

colors="true"

bootstrap="./bootstrap.php"

convertErrorsToExceptions="true"

convertNoticesToExceptions="true"

convertWarningsToExceptions="true"

processIsolation="false"

stopOnFailure="false"

syntaxCheck="false"

>

./

./application

../../application

第二步:写个简单的demo

下面编写一个简单的测试用例,试运行一下。在phpunit下创建一个demo目录,并创建TestCaseClass.php文件。此时结构如下:

$ tree ./phpunit

./phpunit

├── bootstrap.php

├── demo

│   └── TestCaseClass.php

└── phpunit.xml

TestCaseClass.php文件代码是:

use PHPUnit\Framework\TestCase;

namespace tests\demo;

class TestCaseClass extends \PHPUnit_Framework_TestCase

{

public function testHere()

{

$this->assertTrue(true);

}

}

这样编写成功后,就可以试运行了。

第三步:运行一个简单的PHPUnit测试

$ phpunit ./demo/TestCaseClass.php

PHPUnit 5.7.25 by Sebastian Bergmann and contributors.

. 1 / 1 (100%)

Time: 121 ms, Memory: 10.00MB

OK (1 test, 1 assertion)

后面就可以继续这样编写原生的PHPUnit单元测试啦。

难点2:如何使用PhalApi开源框架的脚本,为TP5项目自动生成测试代码?

下面就要为TP5的项目代码编写单元测试了,但每次都要人工手动重复编写测试代码是一件很累人、很耗时、很低率的工作。有没更好的技能?有!

现在已经成为PhalApi开源框架内置的脚本命令了。PhalApi是一个专注于接口开发的开源框架,因此我们可以把PhalApi的phalapi-buildtest脚本命令整合到ThinkPHP 5 的项目里,

非常重要的链接

脚本命令Github下载地址(需要同时下载这两个文件):

下载后放到tests/phpunit目录下,此时文件结构如下:

$ tree ./phpunit

./phpunit

├── bootstrap.php

├── build_test.php

├── demo

│   └── TestCaseClass.php

├── phalapi-buildtest

└── phpunit.xml

准备好后,就可以开始生成单元测试的代码啦!

例如,可执行:

$ ./phalapi-buildtest ../../application/controller/Site.php 'app\controller\Site' > ./controller/SiteTest.php

生成后,便可执行。

难点3:如何测试controller,以及如何解决input()的参数缓存?

正常情况下,进行单个单元测试时,以下测试代码是可以的:

public function testLogin()

{

$_POST['email'] = 'phpunit123';

$_POST['password'] = '123456';

$_POST['remember'] = '1';

$rs = $this->appcontrollerSite->login();

$this->assertEquals(1, $rs['code']);

}

对应的源代码是:

class Site extends Controller {

public function login() {

$username = input('post.email');

$password = input('post.password');

$remember = input('post.remember/d', 0);

// todo

}

}

但是,如果执行全部单元测试的话,传给controller的$_POST参数就失效了。这是因为ThinkPHP5的Request是一个单例,并且在think\Request::$post变量中缓存了POST参数,导致后面的参数不生效。

为此,需要这样调整传递参数:

public function testLogin()

{

$_POST['email'] = 'phpunit123';

$_POST['password'] = '123456';

$_POST['remember'] = '1';

// 加多这两行,重置POST参数

$params = ['POST' => $_POST];

\think\Request::create('/', 'POST', $params);

$rs = $this->appcontrollerSite->login();

$this->assertEquals(1, $rs['code']);

}

参考

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值