来 ! 玩玩PHPUnit的数据库测试 (上)

clipboard.png

前言

我一辈子的文章都会放在这里,个人博客,我但愿每一行代码,每一段文字都能帮助你。 https://github.com/CrazyCodes...

你们好,我是CrazyCodes,今天咱们来聊聊50%(不彻底统计,没必要纠结比例 😆)的程序员都感受没有啥用的数据库测试。php

实际测试是重中之重,正常下来一个需求应当先写测试用例后实现功能代码,若是没有在开发前作测试,那你能够选择写一个错误的断言,使用错误断言来验证代码是否符合预期,而不是根据功能去写测试,这是写测试的一种逆向思惟。html

啥是数据库测试?

不少人可能玩过单元测试,设定呀,断言呀,等等条件。但单元测试具备局限性,现现在大部分代码与数据库耦合度较高,没法独立进行单元测试,例如要作了登陆模块,大概逻辑以下mysql

clipboard.png

那能够用单元测试的地方有哪些呢?git

  1. 对用户名添加正则表达式(或者是规则)进行单元测试
  2. 对用户密码添加正则表达式(或者是规则)进行单元测试

可是否发现验证用户是否存在就没法使用单元测试进行预期的判断了?这时候就须要作数据库测试了,数据库测试实际很简单,大概的流程以下程序员

clipboard.png

咱们不看官方文档的例子,由于那对新人来讲不少名词难于理解,若是你准备好了,那接下来,让咱们经过实操来初试数据库测试吧!github

准备测试数据

在准备数据前,来看看PHPUnit为咱们准备的几种测试数据文件的格式。正则表达式

Flat XML DataSet (平直 XML 数据集)

<?xml version="1.0" ?>
<dataset>
    <user id="1" username="zhangsan" password="12345" created="2019-03-25 17:15:23" />
    <user id="2" username="lisi" password="12345" created="2019-03-25 12:14:20" />
</dataset>

就是如上这样,上述的结构大概意思以下sql

  • user 表名
  • username user表内的username字段
  • password user表内的pssword字段
  • created user表内的created字段

每个以 /> 结束为一条测试数据数据库

XML DataSet (XML 数据集)

<?xml version="1.0" ?>
<dataset>
    <table name="user">
        <column>id</column>
        <column>username</column>
        <column>password</column>
        <column>created</column>
        <row>
            <value>1</value>
            <value>zhangsan</value>
            <value>123456</value>
            <value>2019-03-25 17:15:23</value>
        </row>
        <row>
            <value>2</value>
            <value>lisi</value>
            <value>123456</value>
            <value>2019-03-25 17:15:23</value>
        </row>
    </table>
</dataset>

上述XML与第一个XML表达形式不一样,但大概是一个意思单元测试

  • 首先声明了使用哪张表 <table name="user">
  • 每行数据的包裹标签为 <row>
  • <value> 标签一一对应标签 <column>

就跟SQL语句

UPDATE table_name SET field1=new-value1, field2=new-value2

同样。什么?你须要创造的测试数据太多?一个一个填会不会累死?那下面就是你的福音了

MySQL XML DataSet (MySQL XML 数据集)

Unit 可直接使用MySQL导出的数据集,你能够在MySQL控制台使用命令

mysqldump --xml -t -u [username] --password=[password] [database] > /path/to/file.xml

这是直接导出指定库的全部表数据,若是想指定库你能够这样作

mysqldump --xml -t -u [username] --password=[password] [database] [table1] [table2] > /path/to/file.xml

导出的数据大概以下

<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <database name="testdatabase">
        <table_data name="user">
               <field name="id">1</field>
               <field name="username">zhangsan</field>
               <field name="password">123456</field>
               <field name="created">2019-03-25 17:15:23</field>
        </table_data>
    </database>
</mysqldump>

YAML DataSet (YAML 数据集)

user:
  -
    id: 1
    username: "zhangsan"
    password: "123456"
    created: 2019-03-25 17:15:23
  -
    id: 2
    username: "lisi"
    password:"123456"
    created: 2019-03-25 17:15:23

相信看到这里,我不用解释你也能看懂了。

其余

更多的文件格式请参照 https://phpunit.readthedocs.i...
并非你喜爱哪一个格式就用哪一个,要根据业务来,经过上面的几种方式,咱们能够看出,相似于动态的数据,例如字段 created 咱们不须要他是一个固定的值,而是根据时间变化,这种状况你只能让

世界上最好的语言 PHP

来帮你了。

<?php
use PHPUnit\Framework\TestCase;
use PHPUnit\DbUnit\TestCaseTrait;

class IsUserTest extends TestCase
{
    use TestCaseTrait;

    protected function getDataSet()
    {
        return new UserTest(
            [
                'user' => [
                    [
                        'id' => 1,
                        'username' => 'zhangsan',
                        'password' => '123456',
                        'created' => '2019-03-25 17:15:23'
                    ],
                    [
                        'id' => 2,
                        'username' => 'lisi',
                        'password' => '123456',
                        'created' => '2019-03-25 17:15:23'
                    ],
                ],
            ]
        );
    }
}
?>

固然你须要实现一个自定义的数据库测试类,官方提供的这个已经够用了,你也能够随意更改以达到你的测试目的

<?php
class UserTest extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
{
    /**
     * @var array
     */
    protected $tables = [];

    /**
     * @param array $data
     */
    public function __construct(array $data)
    {
        foreach ($data AS $tableName => $rows) {
            $columns = [];
            if (isset($rows[0])) {
                $columns = array_keys($rows[0]);
            }

            $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
            $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);

            foreach ($rows AS $row) {
                $table->addRow($row);
            }
            $this->tables[$tableName] = $table;
        }
    }

    protected function createIterator($reverse = false)
    {
        return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
    }

    public function getTable($tableName)
    {
        if (!isset($this->tables[$tableName])) {
            throw new InvalidArgumentException("$tableName is not a table in the current database.");
        }

        return $this->tables[$tableName];
    }
}
?>

准备验证数据

验证数据与测试数据格式同样。都是官方文档的那几种。例如你但愿插入数据库后的结果是

<?xml version="1.0" ?>
<dataset>
    <user id="1" username="zhangsan" password="12345" created="2019-03-25 17:15:23" />
    <user id="2" username="lisi" password="12345" created="2019-03-25 12:14:20" />
</dataset>

那在执行测试时,unit则会将该xml文件对比数据库中的数据。同样则经过测试。就是这么简单。

致谢

充分掌握上述的格式以及官方文档内的demo,概念等,才能将数据库掌握在本身手中。下一章我会根据上述准备的数据准备一次“实战演习”,我已经帮你开了头,剩下的就看你本身的了。

感谢你看到这里,但愿本篇文章能够帮到你。

相关文章
相关标签/搜索