【问题标题】:phpunit custom asserts help neededphpunit 自定义断言需要帮助
【发布时间】:2012-02-16 11:25:08
【问题描述】:

我正在尝试在this tutorial 之后向 phpunit 添加自定义断言,以验证作为字符串返回的复数(例如

“-123+456i”

通过我正在测试的方法)到实部和虚部的定义精度。我已经放了一个 Complex.php 类来将字符串解析为实部和虚部,并将以下断言类放在一起作为 complexAssert.php:

require_once 'PHPUnit/Framework/Assert.php';
include_once getcwd().'/custom/Complex.php';

class complexAssert extends PHPUnit_Framework_Assert {

    public function assertComplexEquals($expected, $actual, $message = '', $delta = 0)
    {
        $expectedComplex = new Complex($expected);
        $actualComplex = new Complex($actual);

        if (!($actualComplex->getReal() >= ($expectedComplex - $delta) &&
            $actualComplex->getReal() <= ($expectedComplex + $delta))) {
            return $this->fail($message);
        }

        if (!($actualComplex->getImaginary() >= ($expectedComplex - $delta) &&
            $actualComplex->getImaginary() <= ($expectedComplex + $delta))) {
            return $this->fail($message);
        }

    }
}

我的单元测试脚本:

require_once getcwd().'/custom/complexAssert.php';
require_once 'testDataFileIterator.php';

class EngineeringTest extends PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider providerIMSUM
     */
    public function testIMSUM()
    {
        $args = func_get_args();
        $expectedResult = array_pop($args);
        $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args);
        $this->assertComplexEquals($expectedResult, $result);
    }

    public function providerIMSUM()
    {
        return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data');
    }
}

当我只是做一个 assertEquals 时,单元测试没有错误(但失败)......但现在我添加了包含并更改为我的新断言,它崩溃声称它不能调用未定义的方法assertComplexEquals()。

有没有人用自定义断言成功地扩展了 phpunit,并且可以看到我做错了什么?

【问题讨论】:

  • 你最好关注官方phpunit.de/manual/current/en/…
  • 虽然与此问题无关,但您可能希望使用__DIR__(PHP 5.3+)或dirname(__FILE__),而不是依赖于在程序运行时可以更改的当前工作目录。
  • @David Harkness:我敢打赌在他的情况下getcwd() != __DIR__
  • @zerkms - 这很有可能,但使用getcwd() 的危险在于它可能会根据环境(测试与生产)而改变,但无论如何包含其他模块通常都需要工作什么环境是活跃的。最好依赖当前脚本的位置或自动加载的包含路径。
  • @David Harkness:是的,但目前 OP 还依赖于他的新断言(这是库的东西)和他的复数实现(实际上是应用程序部分的东西)的相对位置。而这也不是什么好事

标签: php phpunit assert


【解决方案1】:

显然,让$this-&gt;someCustomAssertion 工作的唯一方法是扩展PHPUnit_Framework_TestCase 并在那里创建包装方法,或者静态调用您的自定义断言。

例如,Zend 框架只是用附加方法(断言)扩展 PHPUnit_Framework_TestCase

【讨论】:

    【解决方案2】:

    最后,我选择不扩展现有的断言,而是修改我复杂的断言逻辑以返回一个简单的布尔值,然后可以使用 assertTrue() 进行测试,并带有可以使用简单的检索的错误消息getMessage() 用于显示在 phpunit 结果中。说实话,用这种方式感觉好多了

    include_once __DIR__.'/Complex.php';
    
    class complexAssert {
    
        private $_errorMessage = '';
    
        public function assertComplexEquals($expected, $actual, $delta = 0)
        {
            $expectedComplex = new Complex($expected);
            $actualComplex = new Complex($actual);
    
            if ($actualComplex->getReal() < ($expectedComplex->getReal() - $delta) ||
                $actualComplex->getReal() > ($expectedComplex->getReal() + $delta)) {
                $this->_errorMessage = 'Mismatched Real part: ' .
                                       $actualComplex->getReal() . 
                                       ' !== ' . 
                                       $expectedComplex->getReal();
                return FALSE;
            }
    
            if ($actualComplex->getImaginary() < ($expectedComplex->getImaginary() - $delta) ||
                $actualComplex->getImaginary() > ($expectedComplex->getImaginary() + $delta)) {
                $this->_errorMessage = 'Mismatched Imaginary part: ' .
                                       $actualComplex->getImaginary() . 
                                       ' !== ' . 
                                       $expectedComplex->getImaginary();
                return FALSE;
            }
    
            return TRUE;
        }
    
        public function getErrorMessage() {
            return $this->_errorMessage;
        }
    }
    

    我的单元测试脚本:

    //  Custom assertion class for handling precision of Complex numbers
    require_once __DIR__.'/../../custom/complexAssert.php';
    //  Data Provider handler
    require_once 'testDataFileIterator.php';
    
    class EngineeringTest extends PHPUnit_Framework_TestCase
    {
        /**
         * @dataProvider providerIMSUM
         */
        public function testIMSUM()
        {
            $args = func_get_args();
            $expectedResult = array_pop($args);
            $result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args);
            $complexAssert = new complexAssert();
            $this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),
                              $complexAssert->getErrorMessage());
        }
    
        public function providerIMSUM()
        {
            return new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data');
        }
    }
    

    并且记录的phpunit结果足够清晰:

    3) EngineeringTest::testIMSUB with data set #7 ('-12.34-5.67i', '-123.45-67.89', '#NUM!')
    Mismatched String: 111.11 !== #NUM!
    Failed asserting that false is true.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      • 2016-03-05
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      相关资源
      最近更新 更多