來 ! 玩玩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,概念等,才能將數據庫掌握在本身手中。下一章我會根據上述準備的數據準備一次「實戰演習」,我已經幫你開了頭,剩下的就看你本身的了。

感謝你看到這裏,但願本篇文章能夠幫到你。

相關文章
相關標籤/搜索