编写 PHPUnit 测试--异常测试与输出测试

异常测试

例 2.9展示了如何用 @expectedException 标注来测试被测代码中是否抛出了异常。

例 2.9: 使用 @expectedException 标注

<?php
class ExceptionTest extends PHPUnit_Framework_TestCase{
   /**
    * @expectedException InvalidArgumentException
    */
   public function testException()
   {
   }
}?>
phpunit ExceptionTestPHPUnit 4.2.0 by Sebastian Bergmann.
F
Time: 0 seconds, Memory: 4.75Mb
There was 1 failure:
1) ExceptionTest::testException
Expected exception InvalidArgumentException
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

另外,你可以将 @expectedExceptionMessage@expectedExceptionMessageRegExp 和 @expectedExceptionCode 与@expectedException 联合使用,来对异常的讯息与代号进行测试,如例 2.10所示。

例 2.10: 使用 @expectedExceptionMessage、@expectedExceptionMessageRegExp 和 @expectedExceptionCode 标注

<?php
class ExceptionTest extends PHPUnit_Framework_TestCase{
   /**
    * @expectedException        InvalidArgumentException
    * @expectedExceptionMessage Right Message
    */
   public function testExceptionHasRightMessage()
   {
       throw new InvalidArgumentException('Some Message', 10);
   }  
    /**
    * @expectedException              InvalidArgumentException
    * @expectedExceptionMessageRegExp /Right.*/
    */    public function testExceptionMessageMatchesRegExp()
   {
       throw new InvalidArgumentException('Some Message', 10);
   }    
   /**
    * @expectedException     InvalidArgumentException
    * @expectedExceptionCode 20
    */
   public function testExceptionHasRightCode()
   {
       throw new InvalidArgumentException('Some Message', 10);
   }
}?>
phpunit ExceptionTestPHPUnit 4.2.0 by Sebastian Bergmann.
FFF
Time: 0 seconds, Memory: 3.00Mb
There were 3 failures:
1) ExceptionTest::testExceptionHasRightMessage
Failed asserting that exception message 'Some Message' contains 'Right Message'.
2) ExceptionTest::testExceptionMessageMatchesRegExp
Failed asserting that exception message 'Some Message' matches '/Right.*/'.
3) ExceptionTest::testExceptionHasRightCode
Failed asserting that expected exception code 20 is equal to 10.
FAILURES!
Tests: 3, Assertions: 6, Failures: 3.

关于 @expectedExceptionMessage@expectedExceptionMessageRegExp 和 @expectedExceptionCode,分别在“@expectedExceptionMessage”一节“@expectedExceptionMessageRegExp”一节“@expectedExceptionCode”一节有更多相关范例。

此外,还可以用 setExpectedException() 或 setExpectedExceptionRegExp() 方法来设定所预期的异常,如例 2.11所示。

例 2.11: 预期被测代码将引发异常

<?php
class ExceptionTest extends PHPUnit_Framework_TestCase{
   public function testException()
   {
       $this->setExpectedException('InvalidArgumentException');
   }  
    public function testExceptionHasRightMessage()
   {
       $this->setExpectedException(          'InvalidArgumentException', 'Right Message'
       );      
        throw new InvalidArgumentException('Some Message', 10);
   }  
    public function testExceptionMessageMatchesRegExp()
   {
       $this->setExpectedException(          'InvalidArgumentException', '/Right.*/', 10
       );      
        throw new InvalidArgumentException('The Wrong Message', 10);
   }  
    public function testExceptionHasRightCode()
   {
       $this->setExpectedException(          'InvalidArgumentException', 'Right Message', 20
       );      
        throw new InvalidArgumentException('The Right Message', 10);
   }
}?>
phpunit ExceptionTestPHPUnit 4.2.0 by Sebastian Bergmann.
FFFF
Time: 0 seconds, Memory: 3.00Mb
There were 4 failures:
1) ExceptionTest::testException
Expected exception InvalidArgumentException
2) ExceptionTest::testExceptionHasRightMessage
Failed asserting that exception message 'Some Message' contains 'Right Message'.
3) ExceptionTest::testExceptionMessageMatchesRegExp
Failed asserting that exception message 'The Wrong Message' contains '/Right.*/'.
4) ExceptionTest::testExceptionHasRightCode
Failed asserting that expected exception code 20 is equal to 10.
FAILURES!
Tests: 4, Assertions: 8, Failures: 4.

表 2.1中列举了用于对异常进行测试的各种方法。

表 2.1. 用于对异常进行测试的方法

方法含义

void setExpectedException(

string $exceptionName[, 

string $exceptionMessage = '',

 integer $exceptionCode = NULL])

设定预期的$exceptionName$exceptionMessage、和$exceptionCode

void setExpectedExceptionRegExp(

string $exceptionName[,

 string $exceptionMessageRegExp = '',

 integer $exceptionCode = NULL])

设定预期的$exceptionName$exceptionMessageRegExp、和 $exceptionCode
String getExpectedException()返回预期异常的名称

你可以用例 2.12中所示方法来对异常进行测试。

例 2.12: 另一种对异常进行测试的方法

<?php
class ExceptionTest extends PHPUnit_Framework_TestCase {
   public function testException() {
       try {            // ... 预期会引发异常的代码 ...
       }        catch (InvalidArgumentException $expected) {            
       return;
       }        
       $this->fail('预期的异常未出现。');
   }
}?>

当例 2.12中预期会引发异常的代码并没有引发异常时,后面对 fail() 的调用将会中止测试,并通告测试有问题。如果预期的异常出现了,将执行 catch 代码块,测试将会成功结束。对 PHP 错误进行测试

默认情况下,PHPUnit 将测试在执行中触发的 PHP 错误、警告、通知都转换为异常。利用这些异常,就可以,比如说,预期测试将触发 PHP 错误,如例 2.13所示。

PHP 的 error_reporting 运行时配置会对 PHPUnit 将哪些错误转换为异常有所限制。如果在这个特性上碰到问题,请确认 PHP 的配置中没有抑制想要测试的错误类型。

例 2.13: 用 @expectedException 来预期 PHP 错误

<?php
class ExpectedErrorTest extends PHPUnit_Framework_TestCase{
   /**
    * @expectedException PHPUnit_Framework_Error
    */
   public function testFailingInclude()
   {
       include 'not_existing_file.php';
   }
}?>
phpunit -d error_reporting=2 ExpectedErrorTestPHPUnit 4.2.0 by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 5.25Mb
OK (1 test, 1 assertion)

PHPUnit_Framework_Error_Notice 和 PHPUnit_Framework_Error_Warning 分别代表 PHP 通知与 PHP 警告。

对异常进行测试是越明确越好的。对太笼统的类进行测试有可能导致不良副作用。因此,不再允许用 @expectedException 或setExpectedException() 对 Exception 类进行测试。

如果测试依靠会触发错误的 PHP 函数,例如 fopen,有时候在测试中使用错误抑制符会很有用。通过抑制住错误通知,就能对返回值进行检查,否则错误通知将会导致抛出PHPUnit_Framework_Error_Notice

例 2.14: 对会引发PHP 错误的代码的返回值进行测试

<?php
class ErrorSuppressionTest extends PHPUnit_Framework_TestCase{
   public function testFileWriting() {
       $writer = new FileWriter;        
       $this->assertFalse(@$writer->write('/is-not-writeable/file', 'stuff'));
   }
}
class FileWriter{
   public function write($file, $content) {
       $file = fopen($file, 'w');      
        if($file == false) {          
         return false;
       }        // ...
   }
}?>
phpunit ErrorSuppressionTestPHPUnit 4.2.0 by Sebastian Bergmann.
.
Time: 1 seconds, Memory: 5.25Mb
OK (1 test, 1 assertion)

如果不使用错误抑制符,此测试将会失败,并报告fopen(/is-not-writeable/file): failed to open stream: No such file or directory

对输出进行测试

有时候,想要断言,比如说,生成了预期的输出(例如,通过 echo 或 print)。PHPUnit_Framework_TestCase 类使用 PHP 的 输出缓冲 特性来为此提供必要的功能。

例 2.15展示了如何用 expectOutputString() 方法来设定所预期的输出。如果没有产生预期的输出,测试将计为失败。

例 2.15: 对函数或方法的输出进行测试

<?php
class OutputTest extends PHPUnit_Framework_TestCase{
   public function testExpectFooActualFoo()
   {
       $this->expectOutputString('foo');        
       print 'foo';
   }    
   public function testExpectBarActualBaz()
   {
       $this->expectOutputString('bar');      
        print 'baz';
   }
}?>
phpunit OutputTestPHPUnit 4.2.0 by Sebastian Bergmann.
.F
Time: 0 seconds, Memory: 5.75Mb
There was 1 failure:
1) OutputTest::testExpectBarActualBaz
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'bar'
+'baz'
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

表 2.2中列举了用于对输出进行测试的各种方法。



方法含义

void expectOutputRegex

(string $regularExpression)

设定输出预期与 $regularExpression 正则表达式匹配。

void expectOutputString

(string $expectedString)

设定输出预期与 $expectedString 字符串相等。

bool setOutputCallback

(callable $callback)

设定回调函数,用于,比如说,将实际输出规范化。 


本文节选自PHPUnit手册,查看完整手册地址 : 

http://phpunit.de/manual/current/zh_cn/installation.html

版权及转载说明

本站原创、转载文章欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区

本站转载文章版权归原作者所有,如发现本站文章涉嫌侵权请点击「联系我们」反馈,本站将立即给予删除

转载请注明:文章转载自:全分享社区 「http://www.aweb.cc

本文标题:编写 PHPUnit 测试--异常测试与输出测试

本文地址:http://www.aweb.cc/Article/detail/id/153.html

编写 PHPUnit 测试--数据供给器 <<上一篇 下一篇>>PHPUnit测试--命令行测试执行器