测试类

作者: 溪水清澈

<?php


/**
 * 测试类基类
 * 继承时, 参考assertEqual写
 */
class TestUnitBase
{
    /**
     * 测试的返回结果, 格式如下:
     * array(
     *      'TestA' => array(
     *          'info'      => TestA方法的相关信息, 参见debug_backtrace()的返回值,
     *          'methods'   => array(
     *              0 => array(
     *                  'pass' => bool 测试通过与否
     *                  'desc' => 第三个参数
     *                  'info' => assertXXX方法的相关信息
     *              ),
     *              1 => ...
     *          )
     *      ),
     *  );
     */
    public $testResult;

    /**
     * 具体的值与期望值判断, 并对结果进行赋值
     */
    final public function assertEqual( $value, $expectedValue = true, $desc = '' )
    {

        $pass = $value == $expectedValue;
        $this -> assignResult( $pass, $desc );

    }

    /**
     * 对结果进行赋值
     * 每执行一个assertXXX,
     * 把这个assertXXX的测试结果放到以testXXX为键的结果数组中.
     */
    final private function assignResult( $result, $desc )
    {
        $tm = $this -> getTestMethod();
        $am = $this -> getAssertMethod();
        $testKey = $tm[ 'function' ];
        if( empty( $this -> testResult[ $testKey ][ 'info' ] ))
        {
            $this -> testResult[ $testKey ][ 'info' ] = $tm;
        }
        $this -> testResult[ $testKey ][ 'methods' ][] = array(
            'pass' => $result,
            'desc' => $desc,
            'info' => $am );
    }

    /**
     * 取得子类中的测试方法的信息
     */
    final private function getTestMethod()
    {
        // 索引3为结果
        $backtrace = debug_backtrace();
        return $backtrace[ 3 ];
    }

    /**
     * 取得assertXXX方法的信息
     */
    final private function getAssertMethod()
    {
        // 索引2为结果
        $backtrace = debug_backtrace();
        return $backtrace[ 2 ];
    }

}

/**
 * 测试管理类, 以类名为参数
 * 自动执行testXXX函数
 */
class TestManage
{
    private $testClassName;
    private $testObject;

    /**
     * 以类名为参数
     */
    public function __construct( $testClassName )
    {
        $this -> testClassName = $testClassName;
    }

    /**
     * 执行测试
     */
    public function exec()
    {
        if( ! $this -> newObject() )
        {
            return false;
        }
        $testMethods = $this -> getAllTestMethods();
        foreach( $testMethods as $method )
        {
            call_user_func( array( $this -> testObject, $method -> name ));
        }
        $this -> result = $this -> testObject -> testResult;
        return $this -> result;
    }

    /**
     * 实例化对象
     */
    private function newObject()
    {
        if( class_exists( $this -> testClassName ))
        {
            $this -> testObject = new $this -> testClassName;
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * 取得测试类的测试方法
     * 暂定为以test开头的公共方法(不论大小写);
     */
    private function getAllTestMethods()
    {
        $ref = new ReflectionClass( $this -> testObject );
        $methods = $ref -> getMethods( ReflectionMethod::IS_PUBLIC );
        foreach( $methods as $method )
        {
            if( 'test' == strtolower( substr( $method -> name, 0, 4 ))
                && $method -> class == $this -> testClassName )
            {
                $ret[] = $method;
            }
        }
        return $ret;
    }

    /**
     * 输出报告
     */
    public function report()
    {
        foreach( $this -> result as $res )
        {
            $class = $res[ 'info' ][ 'class' ];
            $method = $res[ 'info' ][ 'function' ];
            $type = $res[ 'info' ][ 'type' ];
            echo "$class$type$method ## \n";
            foreach( $res[ 'methods' ] as $assert )
            {
                $pass = $assert[ 'pass' ] ? 'pass' : "\terror";
                $desc = ( $assert[ 'pass' ] ? "\t" : '' ) . $assert[ 'desc' ];
                $assertMethod = $assert[ 'info' ][ 'function' ];
                $assertLine = $assert[ 'info' ][ 'line' ];
                echo "\t$assertMethod @ $assertLine\t$pass\t$desc\n";
            }
            echo "\n";
        }
    }
}

// 以下为测试代码
class TestTest extends TestUnitBase
{
    public function testA()
    {
        $this -> assertEqual( 1, 2, '1 eq 2?' );
        $this -> assertEqual( 1, 1, '1 eq 1?' );
        $this -> assertEqual( 1, 2, '1 eq 2?' );
    }

    public function testB()
    {
        $this -> assertEqual( 'abc', 'def', 'eq?' );
    }
}

$test = new TestManage( 'TestTest' );
$test -> exec();
$test -> report();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值