項目中初試PHP單元測試


只能叫初試,前面雖然做了一些PHPUnit與團隊所用框架的整合,但在整個團隊還沒有人可以主動推動這個事情,而作為Leader最重要的一種能力應該是“讓正確的事情發生”,所以今天開始着手對現有代碼的Model進行單元測試用例和代碼的編寫。

Db測試用例選擇了MysqlDump工具生成Mysql專用xml格式文件存儲,這樣對開發人員來說應該是最方便的。生成的文件類似格式如下:

<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="bbg_mall">
	<table_structure name="admin">
		<field Field="id" Type="int(11) unsigned" Null="NO" Key="PRI" Extra="auto_increment"  />
		<field Field="username" Type="varchar(20)" Null="NO" Key="" Extra=""  />
		<field Field="password" Type="varchar(32)" Null="NO" Key="" Default="" Extra=""  />
		<field Field="login_time" Type="int(10)" Null="NO" Key="" Default="0" Extra="" />
		<field Field="login_num" Type="int(11)" Null="NO" Key="" Default="0" Extra="" />
		<field Field="pid" Type="smallint(6)" Null="YES" Key="" Default="0" Extra=""  />
		<key Table="admin" Non_unique="0" Key_name="PRIMARY" Seq_in_index="1" Column_name="id" Collation="A" Cardinality="21" Null="" Index_type="BTREE" Comment="" Index_comment="" />
		<key Table="admin" Non_unique="1" Key_name="member_id" Seq_in_index="1" Column_name="id" Collation="A" Cardinality="21" Null="" Index_type="BTREE" Comment="" Index_comment="" />
		<options Name="admin" Engine="InnoDB" Version="10" Row_format="Compact" Rows="21" Avg_row_length="780" Data_length="16384" Max_data_length="0" Index_length="16384" Data_free="0" Auto_increment="45" Create_time="2015-11-20 11:10:32" Collation="utf8_general_ci" Create_options="" Comment="" />
	</table_structure>
	<table_data name="admin">
	<row>
		<field name="id">1</field>
		<field name="username">admin</field>
		<field name="password">324d1907d9ca6733d399b87affe48c74</field>
		<field name="login_time">1448011176</field>
		<field name="login_num">1276</field>
		<field name="pid">0</field>
	</row>
	</table_data>
</database>
</mysqldump>


相關命令:

 mysqldump -uroot -p --xml your_db_name admin > test/data/Application/Admin/Model/admin.xml 

測試什么呢?

無非是增刪改查的各種場景,相對於常規框架如TP底層提供的“增刪改”,在DbModel中封裝過一次后,一般要求能過濾掉異常情況,確保按正常邏輯作用。

“查”則主要是判斷各種復雜的sql查詢及數據拼裝后,與預期的結果是否相符。

php這種動態類型語言,最大的問題就是,很適合一個人開發,但一旦到團隊環境中,基於數組的各種隨機數據結構,是導致開發效率低下和維護成本上升的最大因素。

單元測試在這種場景下,更多的像是一種證明,告訴團隊其他成員我的代碼執行后要返回這個格式的結果,我可以證明這一點,具體返回的數據格式,你去找具體的測試用例一看便知。

測試代碼

<?php

namespace Admin\Model;

/**
 * Generated by PHPUnit_SkeletonGenerator on 2016-06-01 at 15:17:36.
 */
class AdminTest extends \TimeCheer\Test\Database\TestCase
{

    /**
     * @var Admin
     */
    protected $object;

/**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
        parent::setUp();
        
        $this->object = new Admin;
    }

    protected function getDataSet()
    {
        return $this->createMySQLXMLDataSet(TEST_PATH . '/data/Application/Admin/Model/admin.xml');
    }

/**
     * @covers Admin\Model\Admin::getList
     * @todo   Implement testGetList().
     */
    public function testGetList()
    {
        $this->assertEquals(1, $this->getConnection()->getRowCount('admin'), "Pre-Condition");
    }

/**
     * @covers Admin\Model\Admin::add
     * @todo   Implement testAdd().
     */
    public function testAdd()
    {
        $this->assertFalse($this->object->add([]));
//TODO 更多條件測試
    }

    /**
     * @covers Admin\Model\Admin::update
     * @todo   Implement testUpdate().
     */
    public function testUpdate()
    {
        $this->assertFalse($this->object->update([]));
        $result = $this->object->update(['id' => '-2']);
        $this->assertFalse($result);
//TODO 更多條件測試
    }

/**
     * @covers Admin\Model\Admin::del
     * @todo   Implement testDel().
     */
    public function testDel()
    {
        $this->assertTrue($this->object->del(1));
    }
    
    /**
     * @covers Admin\Model\Admin::del
     * @todo   Implement testDel().
     */
    public function testDel2()
    {
        $this->assertFalse($this->object->del(0));
    }

測試的效果

  1. 完善每個方法的過濾機制,確保正確的事情發生、不正確的事情不會發生;
  2. 意外的發現DbModel框架底層update方法對執行結果的判斷不足的bug,即當mysql未發生實際的數據更新時,sql語句本身還是返回true,但affected_rows為0,作為框架來說,必須能正確處理這種情況。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM