來 ! 玩玩PHPUnit的資料庫測試 (上)
- 2019 年 11 月 7 日
- 筆記

前言
我一生的文章都會放在這裡,我的部落格,我希望每一行程式碼,每一段文字都能幫助你。https://github.com/CrazyCodes/Blog
大家好,我是CrazyCodes,今天我們來聊聊50%(不完全統計,不必糾結比例 ?)的程式設計師都感覺沒有啥用的資料庫測試。
實際測試是重中之重,正常下來一個需求應當先寫測試用例後實現功能程式碼,如果沒有在開發前做測試,那你可以選擇寫一個錯誤的斷言,使用錯誤斷言來驗證程式碼是否符合預期,而不是根據功能去寫測試,這是寫測試的一種逆向思維。
啥是資料庫測試?
很多人可能玩過單元測試,設定呀,斷言呀,等等條件。但單元測試具有局限性,現如今大部分程式碼與資料庫耦合度較高,無法獨立進行單元測試,例如要做了登錄模組,大概邏輯如下

那可以用單元測試的地方有哪些呢? 1. 對用戶名添加正則表達式(或者是規則)進行單元測試 2. 對用戶密碼添加正則表達式(或者是規則)進行單元測試 但是否發現驗證用戶是否存在就無法使用單元測試進行預期的判斷了?這時候就需要做資料庫測試了,資料庫測試實際很簡單,大概的流程如下

我們不看官方文檔的例子,因為那對新人來說很多名詞難於理解,如果你準備好了,那接下來,讓我們通過實操來初試資料庫測試吧!
準備測試數據
在準備數據前,來看看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>
就是如上這樣,上述的結構大概意思如下 – user 表名 – username user表內的username欄位 – password user表內的pssword欄位 – created user表內的created欄位 每一個以 />
結束為一條測試數據
XML DataSet (XML 數據集)
<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
導出的數據大概如下
<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.io/zh_CN/latest/database.html#dataset-datatable 並不是你喜好哪個格式就用哪個,要根據業務來,通過上面的幾種方式,我們可以看出,類似於動態的數據,例如欄位 created 我們不需要他是一個固定的值,而是根據時間變化,這種情況你只能讓
世界上最好的語言 PHP
來幫你了。
[ [ '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' ], ], ] ); } } ?>
當然你需要實現一個自定義的資料庫測試類,官方提供的這個已經夠用了,你也可以隨意更改以達到你的測試目的
$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]; } } ?>
準備驗證數據
驗證數據與測試數據格式一樣。都是官方文檔的那幾種。例如你希望插入資料庫後的結果是
<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,概念等,才能將資料庫掌握在自己手中。下一章我會根據上述準備的數據準備一次「實戰演習」,我已經幫你開了頭,剩下的就看你自己的了。
感謝你看到這裡,希望本篇文章可以幫到你。