PHPUnit筆記

PHPUnit是一個面向PHP程序員的測試框架,這是一個xUnit的體系結構的單元測試框架。php

複雜的項目,經過單元測試可以快速排查bug,有效減小bug的產生。簡單的項目,使用php自帶的var_dump()print_r()也能很方便的調試bug。html

PHPUnit經過運行測試用例裏的斷言(例如判斷返回結果不爲空),檢查代碼是否符合預期。linux

安裝

安裝方式有兩種。一種是使用phar包,一種是使用Composer。git

一、使用phar包程序員

下載地址 https://phpunit.de/github

有三個版本:web

PHPUnit 6.4 支持PHP 7.0, 和 PHP 7.1。(Current Stable Release)ajax

PHPUnit 5.7 支持 PHP 5.6, PHP 7.0, 和 PHP 7.1。(Old Stable Release)thinkphp

PHPUnit 4.8 支持PHP 5.3~5.6。(No Longer Supported)json

運行方法:

# 通用
php phpunit.phar --version

# linux
chmod +x phpunit.phar
sudo mv phpunit.phar /usr/local/bin/phpunit
phpunit --version

能夠查看版本號。

二、使用Composer
若是用 Composer 來管理項目的依賴關係,只要在項目的composer.json 文件中簡單地加上對 phpunit/phpunit 的依賴關係便可。下面是一個最小化的 composer.json 文件的例子,只定義了一個對 PHPUnit 5.7 的開發時依賴:

{
    "require-dev": {
        "phpunit/phpunit": "5.5.*"
    }
}

要經過 Composer 完成系統級的安裝,能夠運行:

composer global require "phpunit/phpunit=5.5.*"

請確保 path 變量中包含有 ~/.composer/vendor/bin/

配置PhpStorm使用PHPUnit

一、點擊File->Settings->Languages & Frameworks,點擊php,設置PHP開發環境:

二、點擊php->PHPUnitPHPUnit library裏選中Path to phpunit.phar,指定路徑,例如:D:\phpsetup\php\phpunit-5.7.4.phar

編寫第一個測試用例

一、新建文件夾Testcase,編寫SayHello.php:

<?php
 
class SayHello{
 
    public function printHello(){
        echo 'Hello';
        return 'Hello';

    }
}
?>

二、新建測試用例SayHelloTest.php

<?php
 
require_once 'SayHello.php';
 
class SayHelloTest extends PHPUnit_Framework_TestCase {
 
    public function setUp(){ }

    public function tearDown(){ }

    public function testConnectionIsValid(){
        $hi = new SayHello();
        $this->assertTrue($hi->printHello() == 'Hello');
    }
 
}

編寫完成後,切換到phpunit.phar所在目錄命令行執行:

$ php phpunit.phar Testcase/SayHelloTest.php

輸出結果:

PHPUnit 5.7.4 by Sebastian Bergmann and contributors.

.                                                                  1 / 1 (100%)Hello

Time: 130 ms, Memory: 10.00MB

OK (1 test, 1 assertion)

結果代表:
測試經過,1個測試方法,1個斷言,沒有失敗。

這裏注意的是:
一、全部以Test結尾的類均爲測試用例;
二、全部以test開頭的方法均是測試方法,會自動運行;
三、setUp是每一個測試用例最早運行的方法,tearDown是每一個測試用例最後運行的方法;
四、assertTrue用於判斷結果是否爲true。

若是用的PhpStorm,能夠單擊文件,右鍵Run SayHelloTest便可看到相同效果;也能夠針對整個文件夾所有執行,選擇文件夾Testcase右鍵Run Testcase便可。

ThinkPHP3.1集成PHPUnit

集成

須要修改的地方:
一、複製index.php爲phpunit.php,內容增長:

define('APP_PHPUNIT', true);

示例:

<?php
define('APP_DEBUG', true);
header("Content-type: text/html; charset=utf-8");
//define('APP_PATH', './');
define('APP_PATH', __DIR__ .'/');

define('APP_PHPUNIT', true);



require APP_PATH .'Core/ThinkPHP.php';

?>

須要使用絕對路徑。

二、修改ThinkPHP/Lib/Core/App.class.php
run()方法裏App::exec()改成:

(APP_PHPUNIT !== true) && App::exec();//支持phpunit

三、ThinkPHP/Core/Lib/Core/增長AjaxReturnEvent.class.php:

<?php

class AjaxReturnEvent extends Exception {
}

四、修改ThinkPHP/Common/runtime.php:
將2處

CORE_PATH.'Core/Think.class.php',
CORE_PATH.'Core/ThinkException.class.php',  // 異常處理類
CORE_PATH.'Core/Behavior.class.php',

改成:

CORE_PATH.'Core/Think.class.php',
CORE_PATH.'Core/ThinkException.class.php',  // 異常處理類
CORE_PATH.'Core/Behavior.class.php',
CORE_PATH.'Core/AjaxReturnEvent.class.php',

記得是2處。load_runtime_file和build_runtime_cache方法都要修改。

五、修改ThinkPHP/Lib/Core/Action.class.php裏ajaxReturn方法:

switch (strtoupper($type)){
            case 'JSON' :
                // 返回JSON數據格式到客戶端 包含狀態信息
                header('Content-Type:application/json; charset=utf-8');
                if(APP_PHPUNIT === true){throw new AjaxReturnEvent(json_encode($data)); return;}//以支持phpunit捕獲結果
                exit(json_encode($data));
            case 'XML'  :
                // 返回xml格式數據
                header('Content-Type:text/xml; charset=utf-8');
                if(APP_PHPUNIT === true){throw new AjaxReturnEvent(xml_encode($data)); return;}//以支持phpunit捕獲結果
                exit(xml_encode($data));
            case 'JSONP':
                // 返回JSON數據格式到客戶端 包含狀態信息
                header('Content-Type:application/json; charset=utf-8');
                $handler  =   isset($_GET[C('VAR_JSONP_HANDLER')]) ? $_GET[C('VAR_JSONP_HANDLER')] : C('DEFAULT_JSONP_HANDLER');
                if(APP_PHPUNIT === true){throw new AjaxReturnEvent($handler.'('.json_encode($data).');'); return;}//以支持phpunit捕獲結果
                exit($handler.'('.json_encode($data).');');  
            case 'EVAL' :
                // 返回可執行的js腳本
                header('Content-Type:text/html; charset=utf-8');
                if(APP_PHPUNIT === true){throw new AjaxReturnEvent($data); return;}//以支持phpunit捕獲結果
                exit($data);            
            default     :
                // 用於擴展其餘返回格式數據
                tag('ajax_return',$data);
        }

主要作了2件事情:
一、支持phpunit測試模式;
二、防止ajaxReturn裏的exit結束了程序。

示例

目錄結構(示例程序採用了模塊分組):

--example
  |--Common
  |--Conf
  |--ThinkPHP
  |--Lib
    |--Action
    |     |--Weixin
    |     |--Api
    |        |--UserAction.class.php
    |--Model

  |--Runtime
  |--Testcase
    |--Weixin
    |--Api
      |--UserAction.class.php
  |--Tpl
  |--vendor
  |--index.php
  |--phpunit.php

一、Model測試

<?php

define('TEST_PATH', dirname(dirname(__FILE__)));
require TEST_PATH .'/../phpunit.php';

class OrderTest extends PHPUnit_Framework_TestCase {


    public function testGetBillRule(){

        $order_model = D('Orders');
        $this->assertTrue(is_object($order_model) == true);
        $this->assertNotEmpty($order_model->getBillRule());
    }
 
}

二、Api測試

<?php

define('TEST_APP', 'Api');
define('TEST_PATH', dirname(dirname(__FILE__)));
require TEST_PATH .'/../phpunit.php';

class OrderTest extends PHPUnit_Framework_TestCase {
 
    public function setUp() {

        //自動加載
        spl_autoload_register (function ( $class ) {
            include  APP_PATH . 'Lib/Action/'.TEST_APP.'/'  .  $class  .  '.class.php' ;
        });
    }
 
    public function tearDown(){

    }

    public function testModule(){
        $obj = new OrderAction();
        $this->assertTrue(is_array($obj->getBillRule()) == true);
    }
    
    public function testApi(){
        try{
            $obj = new OrderAction();
            $obj->getBillRule(); //因爲TP裏的ajaxReturn會使用exit結束程序,這裏使用異常來獲得返回的內容
        }catch(AjaxReturnEvent $e){
            $res = json_decode($e->getMessage(), treu);
            $this->assertNotEmpty($res);
        }
    }
 
}

參考

一、開始使用 PHPUnit – PHP測試框架
http://phpunit.cn/getting-started.html
二、web3d/TPUnit: ThinkPHP PHPUnit框架集成
https://github.com/web3d/TPUnit/
三、[PHP]PHPUnit安裝配置及樣例 | CoinIdea的技術分享博客
http://blog.coinidea.com/web%e5%bc%80%e5%8f%91/php-1088.html
四、《xUnit Test Patterns》學習筆記系列 - CoderZh - 博客園
http://www.cnblogs.com/coderzh/archive/2010/01/23/xUnit-Test-Patterns.html

(未完待續)

相關文章
相關標籤/搜索