PHPUnit
- http://phpunit.de/manual/current/en/index.html
- http://phpunit.de/manual/3.4/en/index.html
- http://phpunit.de/manual/3.7/zh_cn/index.html
http://www.ltesting.net/ceshi/open/kydycsgj/phpunit/
是在PHP5下面对JUnit3系列版本的完整移植 (JUnit - Kent Beck)
require_once 'PHPUnit/Framework.php'是必须的,另外,你需要在测试用例脚本中包含你需要测试的代码
除了F外,一个测试用例还有I(未完成),S (跳过),E (错误)三种状态
PHPUnit的代码覆盖率报告需要另一个优秀的Extension——XDebug(http://www.xdebug.org )支持。
PHPUnit 3.1.3 by Sebastian Bergmann.
.F
Time:
0 seconds
There
was 1 failure:
1)
testArrayContainsAnElement(ArrayTest)
Failed
asserting that <integer:1> matches expected value <integer:0>.
/home/wiki/apache/htdocs1.5.0/ArrayTest.php:29
FAILURES!
Tests:
2, Failures: 1.
点号 代表一个用例通过(即assert系列函数都通过),F表示第二个测试用例未通
http://phpunit.de/manual/3.7/zh_cn/index.html
第 1 章 自动化测试
使用自动化测试的目的是少犯错。
第 2 章 PHPUnit 的目标
PHPUnit 侧重于相互隔离而非执行快速。
测试应当有良好的粒度划分,每个测试应当只测试一个对象的一个方面。
第 3 章 安装 PHPUnit
第 4 章 编写 PHPUnit 测试
基本惯例与步骤:
- 针对类
Class
的测试写在类ClassTest
中。 ClassTest
(通常)继承自PHPUnit_Framework_TestCase
。- 测试都是命名为
test*
的公用方法。
另外,你可以在方法的文档注释块(docblock)中使用 @test
标注将其标记为测试方法。
- 在测试方法内,类似于
assertEquals()
(参见“断言”一节)这样的断言方法用来对实际值与预期值的匹配做出断言。
测试的依赖关系
PHPUnit支持对测试方法之间的显式依赖关系进行声明。用@depends标注来表达依赖关系
/**
* @depends testOne
*/
测试可以使用多于一个 @depends 标注。PHPUnit 不会更改测试的运行顺序,因此你需要自行保证某个测试所依赖的所有测试均出现于这个测试之前。
拥有多个 @depends 标注的测试,其第一个参数是第一个生产者提供的基境fixture,第二个参数是第二个生产者提供的基境,以此类推。
数据供给器
@dataProvider 标注来指定使用哪个数据供给器方法。数据供给器方法必须声明为 public,其返回值要么是一个数组,其每个元素也是数组;要么是一个实现了 Iterator 接口的对象,在对它进行迭代时每步产生一个数组。
/**
* @dataProvider provider
*/
如果测试同时从 @dataProvider 方法和一个或多个 @depends 测试接收数据,那么来自于数据供给器的参数将先于来自所依赖的测试的。来自于所依赖的测试的参数对于每个数据集都是一样的。
对异常进行测试
用 @expectedException 标注来测试被测代码中是否抛出了异常。可以将 @expectedExceptionMessage 和 @expectedExceptionCode 与 @expectedException 联合使用,来对异常的讯息与代号进行测试
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Right Message
* @expectedExceptionCode 20
*/
可以用 setExpectedException() 方法来设定所预期的异常
对 PHP 错误进行测试
默认情况下,PHPUnit 将测试在执行中触发的 PHP 错误、警告、通知都转换为异常。PHP 的 error_reporting 运行时配置会对 PHPUnit 将哪些错误转换为异常有所限制。PHPUnit_Framework_Error_Notice 和 PHPUnit_Framework_Error_Warning 分别代表 PHP 通知与 PHP 警告。对异常进行测试是越明确越好的。对太笼统的类进行测试有可能导致不良副作用。因此,不再允许用 @expectedException 或 setExpectedException() 对 Exception 类进行测试。
对输出进行测试
PHPUnit_Framework_TestCase
类使用 PHP 的 输出缓冲 特性来为此提供必要的功能。xpectOutputString() 方法来设定所预期的输出。
表4.2. 用于对输出进行测试的方法
方法 |
含义 |
void expectOutputRegex(string $regularExpression) |
设定输出预期与 $regularExpression 正则表达式匹配。 |
void expectOutputString(string $expectedString) |
设定输出预期与 $expectedString 字符串相等。 |
bool setOutputCallback(callable $callback) |
设定回调函数,用于,比如说,将实际输出规范化。 |
断言
- assertArrayHasKey()
- assertClassHasAttribute()
- assertClassHasStaticAttribute()
- assertContains()
- assertContainsOnly()
- assertContainsOnlyInstancesOf()
- assertCount()
- assertEmpty()
- assertEqualXMLStructure()
- assertEquals()
- assertFalse()
- assertFileEquals()
- assertFileExists()
- assertGreaterThan()
- assertGreaterThanOrEqual()
- assertInstanceOf()
- assertInternalType()
- assertJsonFileEqualsJsonFile()
- assertJsonStringEqualsJsonFile()
- assertJsonStringEqualsJsonString()
- assertLessThan()
- assertLessThanOrEqual()
- assertNull()
- assertObjectHasAttribute()
- assertRegExp()
- assertStringMatchesFormat()
- assertStringMatchesFormatFile()
- assertSame()
- assertSelectCount()
- assertSelectEquals()
- assertSelectRegExp()
- assertStringEndsWith()
- assertStringEqualsFile()
- assertStringStartsWith()
- assertTag()
- assertThat()
- assertTrue()
- assertXmlFileEqualsXmlFile()
- assertXmlStringEqualsXmlFile()
- assertXmlStringEqualsXmlString()
第 5 章 命令行测试执行器
对于每个测试的运行,PHPUnit 命令行工具输出一个字符来指示进展:
. 当测试成功时输出。
F 当测试方法运行过程中一个断言失败时输出。
E 当测试方法运行过程中产生一个错误时输出。
S 当测试被跳过时输出。
I 当测试被标记为不完整或未实现时输出。
PHPUnit 区分 失败(failure) 与 错误(error)。失败指的是被违背了的 PHPUnit 断言,例如一个失败的 assertEquals() 调用。错误指的是意料之外的异常(exception)或 PHP 错误。
命令行选项
phpunit --help
PHPUnit 3.7.0 by Sebastian Bergmann.
Usage: phpunit [switches] UnitTest [UnitTest.php]
phpunit [switches] <directory>
--log-junit <file> Log test execution in JUnit XML format to file.
--log-tap <file> Log test execution in TAP format to file.
--log-json <file> Log test execution in JSON format.
--coverage-clover <file> Generate code coverage report in Clover XML format.
--coverage-html <dir> Generate code coverage report in HTML format.
--coverage-php <file> Serialize PHP_CodeCoverage object to file.
--coverage-text=<file> Generate code coverage report in text format.
Default to writing to the standard output.
--testdox-html <file> Write agile documentation in HTML format to file.
--testdox-text <file> Write agile documentation in Text format to file.
--filter <pattern> Filter which tests to run.
--testsuite <pattern> Filter which testsuite to run.
--group ... Only runs tests from the specified group(s).
--exclude-group ... Exclude tests from the specified group(s).
--list-groups List available test groups.
--test-suffix ... Only search for test in files with specified
suffix(es). Default: Test.php,.phpt
--loader <loader> TestSuiteLoader implementation to use.
--printer <printer> TestSuiteListener implementation to use.
--repeat <times> Runs the test(s) repeatedly.
--tap Report test execution progress in TAP format.
--testdox Report test execution progress in TestDox format.
--colors Use colors in output.
--stderr Write to STDERR instead of STDOUT.
--stop-on-error Stop execution upon first error.
--stop-on-failure Stop execution upon first error or failure.
--stop-on-skipped Stop execution upon first skipped test.
--stop-on-incomplete Stop execution upon first incomplete test.
--strict Run tests in strict mode.
-v|--verbose Output more verbose information.
--debug Display debugging information during test execution.
--process-isolation Run each test in a separate PHP process.
--no-globals-backup Do not backup and restore $GLOBALS for each test.
--static-backup Backup and restore static attributes for each test.
--bootstrap <file> A "bootstrap" PHP file that is run before the tests.
-c|--configuration <file> Read configuration from XML file.
--no-configuration Ignore default configuration file (phpunit.xml).
--include-path <path(s)> Prepend PHP's include_path with given path(s).
-d key[=value] Sets a php.ini value.
-h|--help Prints this usage information.
--version Prints the version and exits.
第 6 章 基境(fixture)
PHPUnit 支持共享建立基境的代码。PHPUnit 支持共享建立基境的代码。在运行某个测试方法前,会调用一个名叫 setUp() 的模板方法。 setUp() 是创建测试所用对象的地方。当测试方法运行结束后,不管是成功还是失败,都会调用另外一个名叫 tearDown() 的模板方法。tearDown() 是清理测试所用对象的地方。setUpBeforeClass() 与 tearDownAfterClass() 模板方法将分别在测试用例类的第一个测试运行之前和测试用例类的最后一个测试运行之后调用。
全局状态
PHPUnit 用一种对全局变量与超全局变量($GLOBALS, $_ENV, $_POST, $_GET, $_COOKIE, $_SERVER, $_FILES, $_REQUEST)进行更改不会影响到其他测试的方式来运行所有测试。可以选择将这种隔离扩展到类的静态属性。
注意
对类的静态属性的备份与还原操作其实现方案需要 PHP 5.3(或更高版本).
对全局变量和类的静态属性的备份与还原操作其实现方案使用了 serialize() 与 unserialize()。
某些 PHP 自身提供的类,比如 PDO ,其实例对象无法序列化,因此如果把这样一个对象存放在比如说 $GLOBALS 数组内时,备份操作就会出问题。
第 7 章 组织测试
当 PHPUnit 命令行测试执行器指向一个目录时,它会在目录下查找 *Test.php 文件。
用文件系统来编排测试套件
把所有测试用例源文件放在一个测试目录中。通过对测试目录进行递归遍历,PHPUnit 能自动发现并运行测试。
用 XML 配置来编排测试套件
<phpunit>
<testsuites>
<testsuite name="Object_Freezer">
<directory>Tests</directory>
<file>Tests/Freezer/StorageTest.php</file>
</testsuite>
</testsuites>
</phpunit>
第 8 章 数据库测试
pear install phpunit/DbUnit
DbUnit 目前支持 MySQL、PostgreSQL、Oracle 和 SQLite。通过集成 Zend Framework 或者 Doctrine 2,可以访问其他数据库系统,比如 IBM DB2 或者 Microsoft SQL Server。
第 9 章 不完整的测试与跳过的测试
不完整的测试
PHPUnit_Framework_IncompleteTest 是一个标记接口,用于将异常(由测试方法抛出)标记为测试不完整或目前尚未实现而导致的结果。PHPUnit_Framework_IncompleteTestError 是这个界面的标准实现。
表 9.1. 用于不完整的测试的 API
方法 |
含义 |
void markTestIncomplete() |
将当前测试标记为不完整。 |
void markTestIncomplete(string $message) |
将当前测试标记为不完整,并用 $message 作为说明信息。 |
跳过测试
表 9.2. 用于跳过测试的 API
方法 |
含义 |
void markTestSkipped() |
将当前测试标记为跳过。 |
void markTestSkipped(string $message) |
将当前测试标记为不完整,并用 $message 作为说明信息。 |
用 @requires 来跳过测试
除了上述方法,还可以用 @requires
标注来表达测试用例的一些常见前提条件。
/**
* @requires extension mysqli
*/
/**
* @requires PHP 5.3
*/
第 10 章 测试替身
第 11 章 测试实践
第 12 章 测试驱动开发
第 13 章 行为驱动开发
第 14 章 代码覆盖率分析
PHPUnit 的代码覆盖率功能使用了 PHP_CodeCoverage 组件,这反过来又利用了 Xdebug 扩展为 PHP 提供的语句覆盖率功能。
第 15 章 测试的其他用途
敏捷文档
跨团队测试
第 16 章 骨架(Skeleton)生成器
PHPUnit 骨架生成器(Skeleton Generator)是用来从成品代码类中生成骨架测试类(或反之)的工具。可以用如下命令安装:
pear install phpunit/PHPUnit_SkeletonGenerator
第 17 章 PHPUnit 与 Selenium
第 18 章 日志记录
测试结果(XML)
PHPUnit 所生成的测试结果 XML 日志文件是基于 JUnit task for Apache Ant 所使用的 XML 日志的。
测试结果(TAP)
Test Anything Protocol (TAP) 是 Perl 与测试模块之间所使用的简单的基于文本的接口。
测试结果(JSON)
JavaScript 对象表示法(JSON)是轻量级的数据交换格式。
代码覆盖率(XML)
PHPUnit 所生成的 XML 格式代码覆盖率信息日志记录是不严格地基于 Clover 所使用的 XML 日志的。
代码覆盖率(TEXT)
以易于常人了解(human-readable)的格式生成代码覆盖率,输出到命令行或保存成文本文件。
第 19 章 扩展 PHPUnit
从 PHPUnit_Framework_TestCase 派生子类
从 PHPUnit_Extensions_TestDecorator 派生子类
附录 A. 断言
表 A.1列出了所有断言种类。
附录 B. 标注
所谓标注,是指某些编程语言中允许加在源代码中的一种特殊形式的语法元数据。本附录列出了 PHPUnit 所支持的所有标注种类。
附录 C. XML 配置文件
PHPUnit
<phpunit> 元素的属性用于配置 PHPUnit 的核心功能。