來(lái) ! 玩玩PHPUnit的數(shù)據(jù)庫(kù)測(cè)試 (上)

前言
我一生的文章都會(huì)放在這里,我的博客,我希望每一行代碼,每一段文字都能幫助你。https://github.com/CrazyCodes...
大家好,我是CrazyCodes,今天我們來(lái)聊聊50%(不完全統(tǒng)計(jì),不必糾結(jié)比例 ?)的程序員都感覺(jué)沒(méi)有啥用的數(shù)據(jù)庫(kù)測(cè)試。
實(shí)際測(cè)試是重中之重,正常下來(lái)一個(gè)需求應(yīng)當(dāng)先寫(xiě)測(cè)試用例后實(shí)現(xiàn)功能代碼,如果沒(méi)有在開(kāi)發(fā)前做測(cè)試,那你可以選擇寫(xiě)一個(gè)錯(cuò)誤的斷言,使用錯(cuò)誤斷言來(lái)驗(yàn)證代碼是否符合預(yù)期,而不是根據(jù)功能去寫(xiě)測(cè)試,這是寫(xiě)測(cè)試的一種逆向思維。
啥是數(shù)據(jù)庫(kù)測(cè)試?
很多人可能玩過(guò)單元測(cè)試,設(shè)定呀,斷言呀,等等條件。但單元測(cè)試具有局限性,現(xiàn)如今大部分代碼與數(shù)據(jù)庫(kù)耦合度較高,無(wú)法獨(dú)立進(jìn)行單元測(cè)試,例如要做了登錄模塊,大概邏輯如下

那可以用單元測(cè)試的地方有哪些呢?
對(duì)用戶(hù)名添加正則表達(dá)式(或者是規(guī)則)進(jìn)行單元測(cè)試
對(duì)用戶(hù)密碼添加正則表達(dá)式(或者是規(guī)則)進(jìn)行單元測(cè)試
但是否發(fā)現(xiàn)驗(yàn)證用戶(hù)是否存在就無(wú)法使用單元測(cè)試進(jìn)行預(yù)期的判斷了?這時(shí)候就需要做數(shù)據(jù)庫(kù)測(cè)試了,數(shù)據(jù)庫(kù)測(cè)試實(shí)際很簡(jiǎn)單,大概的流程如下

我們不看官方文檔的例子,因?yàn)槟菍?duì)新人來(lái)說(shuō)很多名詞難于理解,如果你準(zhǔn)備好了,那接下來(lái),讓我們通過(guò)實(shí)操來(lái)初試數(shù)據(jù)庫(kù)測(cè)試吧!
準(zhǔn)備測(cè)試數(shù)據(jù)
在準(zhǔn)備數(shù)據(jù)前,來(lái)看看PHPUnit為我們準(zhǔn)備的幾種測(cè)試數(shù)據(jù)文件的格式。
Flat XML DataSet (平直 XML 數(shù)據(jù)集)
<?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>就是如上這樣,上述的結(jié)構(gòu)大概意思如下
user 表名
username user表內(nèi)的username字段
password user表內(nèi)的pssword字段
created user表內(nèi)的created字段
每一個(gè)以 /> 結(jié)束為一條測(cè)試數(shù)據(jù)
XML DataSet (XML 數(shù)據(jù)集)
<?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與第一個(gè)XML表達(dá)形式不同,但大概是一個(gè)意思
首先聲明了使用哪張表
<table name="user">每行數(shù)據(jù)的包裹標(biāo)簽為
<row><value>標(biāo)簽一一對(duì)應(yīng)標(biāo)簽<column>
就跟SQL語(yǔ)句
UPDATE table_name SET field1=new-value1, field2=new-value2一樣。什么?你需要?jiǎng)?chuàng)造的測(cè)試數(shù)據(jù)太多?一個(gè)一個(gè)填會(huì)不會(huì)累死?那下面就是你的福音了
MySQL XML DataSet (MySQL XML 數(shù)據(jù)集)
Unit 可直接使用MySQL導(dǎo)出的數(shù)據(jù)集,你可以在MySQL控制臺(tái)使用命令
mysqldump --xml -t -u [username] --password=[password] [database] > /path/to/file.xml這是直接導(dǎo)出指定庫(kù)的所有表數(shù)據(jù),如果想指定庫(kù)你可以這樣做
mysqldump --xml -t -u [username] --password=[password] [database] [table1] [table2] > /path/to/file.xml導(dǎo)出的數(shù)據(jù)大概如下
<?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 數(shù)據(jù)集)
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相信看到這里,我不用解釋你也能看懂了。
其他
更多的文件格式請(qǐng)參照 https://phpunit.readthedocs.i...
并不是你喜好哪個(gè)格式就用哪個(gè),要根據(jù)業(yè)務(wù)來(lái),通過(guò)上面的幾種方式,我們可以看出,類(lèi)似于動(dòng)態(tài)的數(shù)據(jù),例如字段 created 我們不需要他是一個(gè)固定的值,而是根據(jù)時(shí)間變化,這種情況你只能讓
世界上最好的語(yǔ)言 PHP
來(lái)幫你了。
<?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'
],
],
]
);
}
}
?>當(dāng)然你需要實(shí)現(xiàn)一個(gè)自定義的數(shù)據(jù)庫(kù)測(cè)試類(lèi),官方提供的這個(gè)已經(jīng)夠用了,你也可以隨意更改以達(dá)到你的測(cè)試目的
<?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];
}
}
?>準(zhǔn)備驗(yàn)證數(shù)據(jù)
驗(yàn)證數(shù)據(jù)與測(cè)試數(shù)據(jù)格式一樣。都是官方文檔的那幾種。例如你希望插入數(shù)據(jù)庫(kù)后的結(jié)果是
<?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>那在執(zhí)行測(cè)試時(shí),unit則會(huì)將該xml文件對(duì)比數(shù)據(jù)庫(kù)中的數(shù)據(jù)。一樣則通過(guò)測(cè)試。就是這么簡(jiǎn)單。
致謝
充分掌握上述的格式以及官方文檔內(nèi)的demo,概念等,才能將數(shù)據(jù)庫(kù)掌握在自己手中。下一章我會(huì)根據(jù)上述準(zhǔn)備的數(shù)據(jù)準(zhǔn)備一次“實(shí)戰(zhàn)演習(xí)”,我已經(jīng)幫你開(kāi)了頭,剩下的就看你自己的了。
感謝你看到這里,希望本篇文章可以幫到你。
