由于TP测试框架更偏向于黑盒测试(实际上我们使用的是灰盒测试),因此在对数据库进行测试的时候,我们没有办法(或者是不方便)使用mock。所以我们使用TP测试框架的时候对数据操作进行测试的时候,我们需要为数据库的基境进行搭建。
> 1. 黑盒测试:测试人员不需要了解代码如何工作,只需要根据指定输入,断言输出。
> 2. 白盒测试:测试人员需要了解代码,用来帮助测试的进行。
> 3. 灰盒测试:黑盒和白盒的中间,使用黑盒方法的同时使用白盒测试。
TP的官方测试框架主要使用灰盒的测试方法,如果需要使用mock的话,可以使用快速入门中提到的测试库。
## 安装DBUnit。
使用thinkUnit的时候安装的PHPUNIT依赖中是没有DBUNIT的。因此如果我们要对数据库进行测试的话,那么就需要安装DBUnit了。
可以在composer中的require-dev中添加以下的依赖:
`"phpunit/dbunit": ">=1.2"`
然后更新composer即可。
`composer update`
## 编写测试用例
安装完DBUnit之后,我们就需要重新编写测试用例了。不过,TP本身的测试库并没有提供数据库测试的测试用例基类,因此需要我们自己编写。
```
<?php
namespace tests;
use PHPUnit_Extensions_Database_TestCase;
use think\testing\ApplicationTrait;
use think\testing\AssertionsTrait;
use think\testing\CrawlerTrait;
class ClientTest extends PHPUnit_Extensions_Database_TestCase{
use ApplicationTrait, AssertionsTrait, CrawlerTrait;
protected $baseUrl = 'http://localhost';
//获得连接
public function getConnection(){
//数据库的连接
}
// 获得初始数据
public function getDataSet(){
// 基境的建立
}
// 具体的测试用例
}
```
## 将数据库配置从测试类中抽离
在上面的例子中,我们每一个测试类都需要获得连接,读取数据库的配置。
在通常情况下,我们希望能够将数据库配置设为全局,这样就算数据库配置修改的话,也只需要修改全局一个配置。
在thinkphp的根目录下,有一个phpunit的配置文件,phpunit.xml文件,我们只需要再phpunit.xml中添加如下的信息:
```
<phpunit>
......其他配置
......
<php>
<var name="DB_DSN" value="mysql:dbname=你的数据库名;host=localhost" />
<var name="DB_USER" value="用户名" />
<var name="DB_PASSWD" value="密码" />
<var name="DB_DBNAME" value="数据库名" />
</php>
</phpunit>
```
而后在getConnection方法为:
```
if ($this->conn === null) {
if (self::$pdo == null) {
self::$pdo = new \PDO( $GLOBALS['DB_DSN'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD'] );
}
$this->conn = $this->createDefaultDBConnection(self::$pdo, $GLOBALS['DB_DBNAME']);
}
return $this->conn;
```
> 再走一步:但是这样的话,我们每个方法也需要写这样重复的内容。因此,我们还可以将其抽象为父类,然后再需要使用数据库的测试类中继承该类。