• PHPUnit笔记


    PHPUnit是一个面向PHP程序员的测试框架,这是一个xUnit的体系结构的单元测试框架。

    复杂的项目,通过单元测试能够快速排查bug,有效减少bug的产生。简单的项目,使用php自带的var_dump()print_r()也能很方便的调试bug。

    PHPUnit通过运行测试用例里的断言(例如判断返回结果不为空),检查代码是否符合预期。

    安装

    安装方式有两种。一种是使用phar包,一种是使用Composer。

    1、使用phar包

    下载地址 https://phpunit.de/

    有三个版本:

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

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

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

    运行方法:

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

    可以查看版本号。

    2、使用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

    1、点击File->Settings->Languages & Frameworks,点击php,设置PHP开发环境:

    2、点击php->PHPUnitPHPUnit library里选中Path to phpunit.phar,指定路径,例如:D:phpsetupphpphpunit-5.7.4.phar

    编写第一个测试用例

    1、新建文件夹Testcase,编写SayHello.php:

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

    2、新建测试用例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个断言,没有失败。

    这里注意的是:
    1、所有以Test结尾的类均为测试用例;
    2、所有以test开头的方法均是测试方法,会自动运行;
    3、setUp是每个测试用例最先运行的方法,tearDown是每个测试用例最后运行的方法;
    4、assertTrue用于判断结果是否为true。

    如果用的PhpStorm,可以单击文件,右键Run SayHelloTest即可看到相同效果;也可以针对整个文件夹全部执行,选择文件夹Testcase右键Run Testcase即可。

    ThinkPHP3.1集成PHPUnit

    集成

    需要修改的地方:
    1、复制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';
    
    ?>
    

    需要使用绝对路径。

    2、修改ThinkPHP/Lib/Core/App.class.php
    run()方法里App::exec()改为:

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

    3、ThinkPHP/Core/Lib/Core/增加AjaxReturnEvent.class.php:

    <?php
    
    class AjaxReturnEvent extends Exception {
    }
    

    4、修改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方法都要修改。

    5、修改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件事情:
    1、支持phpunit测试模式;
    2、防止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
    
    

    1、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());
        }
     
    }
    

    2、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);
    		}
        }
     
    }
    
    
    

    参考

    1、开始使用 PHPUnit – PHP测试框架
    http://phpunit.cn/getting-started.html
    2、web3d/TPUnit: ThinkPHP PHPUnit框架集成
    https://github.com/web3d/TPUnit/
    3、[PHP]PHPUnit安装配置及样例 | CoinIdea的技术分享博客
    http://blog.coinidea.com/web开发/php-1088.html
    4、《xUnit Test Patterns》学习笔记系列 - CoderZh - 博客园
    http://www.cnblogs.com/coderzh/archive/2010/01/23/xUnit-Test-Patterns.html

    (未完待续)

  • 相关阅读:
    第一篇博文
    重拾javascript系列-JS声明详解之var
    重拾Javascript系列
    AtCoder DP Contest 26题
    DP题
    一众数论
    字符编码
    C# DateTime类型和sqlserver DateTime精度不同
    vs2015中的数据库架构对比工具(New Schema Comparison)
    SqlServer常用语句
  • 原文地址:https://www.cnblogs.com/52fhy/p/6208624.html
Copyright © 2020-2023  润新知