【http://www.phpunit.cn/manual/5.7/zh_cn/appendixes.annotations.html】

所谓标注,是指某些编程语言中允许加在源代码中的一种特殊格式的语法元数据。PHP 并没有专门的语言特性来支持对源代码进行标注,然而 PHP 社区早已经形成惯例,通过在文档注释块中使用诸如 @annotation arguments 这样的标签来为源代码加上标注。在 PHP 中,文档注释块是可反射的:可以对函数、方法、类以及属性调用相应级别的反射 API getDocComment() 方法来获取相应的文档注释块。诸如 PHPUnit 这样的应用程序在运行时用这些信息来配置其行为。

注意

PHP中的文档注释块必须以 /** 开头,以 */ 结尾。任何其他形式的注释中出现的标注都将被忽略。

本附录列出了 PHPUnit 所支持的所有标注种类。

@author

@author 标注是 @group 标注(参见 “@group”一节)的别名,允许基于作者对测试进行过滤。

@after

@after 标注用于指明此方法应当在测试用例类中的每个测试方法运行完成之后调用。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @after
*/
public function tearDownSomeFixtures()
{
// ...
} /**
* @after
*/
public function tearDownSomeOtherFixtures()
{
// ...
}
}

@afterClass

@afterClass 标注用于指明此静态方法应该于测试类中的所有测试方法都运行完成之后调用,用于清理共享基境。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @afterClass
*/
public static function tearDownSomeSharedFixtures()
{
// ...
} /**
* @afterClass
*/
public static function tearDownSomeOtherSharedFixtures()
{
// ...
}
}

@backupGlobals

全局变量的备份与还原操作可以对某个测试用例类中的所有测试彻底禁用,像这样:

use PHPUnit\Framework\TestCase;

/**
* @backupGlobals disabled
*/
class MyTest extends TestCase
{
// ...
}

@backupGlobals 标注也可以用在测试方法这一级别。这样可以对备份与还原操作进行更细粒度的配置:

use PHPUnit\Framework\TestCase;

/**
* @backupGlobals disabled
*/
class MyTest extends TestCase
{
/**
* @backupGlobals enabled
*/
public function testThatInteractsWithGlobalVariables()
{
// ...
}
}

@backupStaticAttributes

如果指定了 @backupStaticAttributes 标注,那么将在每个测试之前备份所有已声明的类的静态属性的值,并在测试完成之后全部恢复。它可以用在测试用例类或测试方法级别:

use PHPUnit\Framework\TestCase;

/**
* @backupStaticAttributes enabled
*/
class MyTest extends TestCase
{
/**
* @backupStaticAttributes disabled
*/
public function testThatInteractsWithStaticAttributes()
{
// ...
}
}

注意

受限于 PHP 的内部实现,在某些情况下即使使用了 @backupStaticAttributes 也可能有个别静态值出现意料外的延续,并污染后继测试。

详细信息参见 “全局状态”一节

@before

@before 标注用于指明此方法应当在测试用例类中的每个测试方法开始运行之前调用。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @before
*/
public function setupSomeFixtures()
{
// ...
} /**
* @before
*/
public function setupSomeOtherFixtures()
{
// ...
}
}

@beforeClass

@beforeClass 标注用于指明此静态方法应该于测试类中的所有测试方法都运行完成之后调用,用于建立共享基境。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @beforeClass
*/
public static function setUpSomeSharedFixtures()
{
// ...
} /**
* @beforeClass
*/
public static function setUpSomeOtherSharedFixtures()
{
// ...
}
}

@codeCoverageIgnore*

@codeCoverageIgnore, @codeCoverageIgnoreStart and @codeCoverageIgnoreEnd 标注用于从覆盖率分析中排除掉某些代码行。

用法参见“略过代码块”一节

@covers

在测试代码中用 @covers 标注来指明测试方法想要对哪些方法进行测试:

/**
* @covers BankAccount::getBalance
*/
public function testBalanceIsInitiallyZero()
{
$this->assertEquals(0, $this->ba->getBalance());
}

如果提供了此标注,则代码覆盖率信息中只考虑指定的这些方法。

表 B.1列出了 @covers 标注的语法。

表 B.1. 用于指明测试覆盖哪些方法的标注

Annotation (标注) 描述
@covers ClassName::methodName 指明所标注的测试方法覆盖指定的方法。
@covers ClassName 指明所标注的测试方法覆盖给定类的全部方法。
@covers ClassName<extended> 指明所标注的测试方法覆盖给定类以及其所有父类与接口的全部方法。
@covers ClassName::<public> 指明所标注的测试方法覆盖给定类的所有 public 方法。
@covers ClassName::<protected> 指明所标注的测试方法覆盖给定类的所有 protected 方法。
@covers ClassName::<private> 指明所标注的测试方法覆盖给定类的所有 private 方法。
@covers ClassName::<!public> 指明所标注的测试方法覆盖给定类的所有非 public 方法。
@covers ClassName::<!protected> 指明所标注的测试方法覆盖给定类的所有非 protected 方法。
@covers ClassName::<!private> 指明所标注的测试方法覆盖给定类的所有非 private 方法。
@covers ::functionName 指明所标注的测试方法覆盖给定的全局函数。

@coversDefaultClass

@coversDefaultClass 标注用于指定一个默认的命名空间或类名,这样就不用在每个 @covers 标注中重复长名称。参见例 B.1

例 B.1: 用 @coversDefaultClass 缩短标注

<?php
use PHPUnit\Framework\TestCase; /**
* @coversDefaultClass \Foo\CoveredClass
*/
class CoversDefaultClassTest extends TestCase
{
/**
* @covers ::publicMethod
*/
public function testSomething()
{
$o = new Foo\CoveredClass;
$o->publicMethod();
}
}
?>

@coversNothing

在测试代码中用 @coversNothing 标注来指明所标注的测试用例不需要记录任何代码覆盖率信息。

这可以用于集成测试。例子可参见例 11.3

这个标注可以用在类级别或者方法级别,并且会覆盖掉任何 @covers 标注。

@dataProvider

测试方法可以接受任意参数。这些参数可以由数据供给器方法(例 2.5中的 provider())提供。所要使用的数据供给器方法用 @dataProvider 标注来指定。

更多细节参见“数据供给器”一节

@depends

PHPUnit支持对测试方法之间的显式依赖关系进行声明。这种依赖关系并不是定义在测试方法的执行顺序中,而是允许生产者(producer)返回一个测试基境(fixture)的实例,并将此实例传递给依赖于它的消费者(consumer)们。例 2.2展示了如何用 @depends 标注来表达测试方法之间的依赖关系。

更多细节参见“测试的依赖关系”一节

@expectedException

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

更多细节参见“对异常进行测试”一节

@expectedExceptionCode

@expectedExceptionCode 标注与 @expectedException 联合使用,可以对抛出异常的代码作出断言,这样可以缩小具体异常的范围。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @expectedException MyException
* @expectedExceptionCode 20
*/
public function testExceptionHasErrorcode20()
{
throw new MyException('Some Message', 20);
}
}

为了方便测试并减少冗余,可以用"@expectedExceptionCode ClassName::CONST"这样的语法将指定类常量作为 @expectedExceptionCode

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @expectedException MyException
* @expectedExceptionCode MyClass::ERRORCODE
*/
public function testExceptionHasErrorcode20()
{
throw new MyException('Some Message', 20);
}
}
class MyClass
{
const ERRORCODE = 20;
}

@expectedExceptionMessage

@expectedExceptionMessage 标注的运作方式类似于 @expectedExceptionCode ,用它可以对异常的错误讯息作出断言。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @expectedException MyException
* @expectedExceptionMessage Some Message
*/
public function testExceptionHasRightMessage()
{
throw new MyException('Some Message', 20);
}
}

预期讯息可以是异常讯息的子串。在只需要断言传入的特定名称或参数确实出现于异常中时这个特性很有用,这样就无需在测试中关注完整的异常讯息。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @expectedException MyException
* @expectedExceptionMessage broken
*/
public function testExceptionHasRightMessage()
{
$param = "broken";
throw new MyException('Invalid parameter "'.$param.'".', 20);
}
}

为了方便测试同时减少冗余,可以用"@expectedExceptionMessage ClassName::CONST"这样的语法将指定类常量作为 @expectedExceptionMessage。在“@expectedExceptionCode”一节中可以看到范例。

@expectedExceptionMessageRegExp

预期讯息也可以通过 @expectedExceptionMessageRegExp 标注以正则表达式来指定。当无法用子串来完成对给定讯息的匹配时,这种方式就非常有用了。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @expectedException MyException
* @expectedExceptionMessageRegExp /Argument \d+ can not be an? \w+/
*/
public function testExceptionHasRightMessage()
{
throw new MyException('Argument 2 can not be an integer');
}
}

@group

测试可以用 @group 标注来标记为属于一个或多个组,就像这样:

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @group specification
*/
public function testSomething()
{
} /**
* @group regresssion
* @group bug2204
*/
public function testSomethingElse()
{
}
}

测试可以基于组来选择性的执行,使用命令行测试执行器的 --group and --exclude-group 选项,或者使用对应的 XML 配置文件指令。

@large

@large 标注是 @group large 的别名。

如果安装了 PHP_Invoker 组件包并启用了严格模式,一个执行时间超过60秒的大型(large)测试将视为失败。这个超时限制可以通过 XML 配置文件的 timeoutForLargeTests 属性进行配置。

@medium

@medium 标注是 @group medium 的别名。中型(medium)测试不能依赖于标记为 @large 的测试。

如果安装了 PHP_Invoker 组件包并启用了严格模式,一个执行时间超过10秒的中型(medium)测试将视为失败。这个超时限制可以通过 XML 配置文件的 timeoutForMediumTests 属性进行配置。

@preserveGlobalState

在单独的进程中运行测试时,PHPUnit 会尝试保持来自父进程的全局状态(通过在父进程序列化全局状态然后在子进程反序列化的方式)。这当父进程包含非可序列化的全局内容时可能会导致问题。为了修正这种问题,可以用 @preserveGlobalState 标注来禁止 PHPUnit 保持全局状态。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testInSeparateProcess()
{
// ...
}
}

@requires

@requires 标注用于在常规前提条件(例如 PHP 版本或所安装的扩展)不满足时跳过测试。

完整的可能用法以及例子见表 7.3

@runTestsInSeparateProcesses

指明单个测试类内的所有测试要各自运行在独立的 PHP 进程中。

use PHPUnit\Framework\TestCase;

/**
* @runTestsInSeparateProcesses
*/
class MyTest extends TestCase
{
// ...
}

注意:“@preserveGlobalState”一节 默认情况下,PHPUnit 会尝试通过在父进程序列化全局状态然后在子进程反序列化的方式在子进程中保持来自父进程的全局状态。这当父进程包含非可序列化的全局内容时可能会导致问题。关于如何修正此问题的信息参见“@preserveGlobalState”一节

@runInSeparateProcess

明某个测试要运行在独立的 PHP 进程中。

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
/**
* @runInSeparateProcess
*/
public function testInSeparateProcess()
{
// ...
}
}

注意:“@preserveGlobalState”一节 默认情况下,PHPUnit 会尝试通过在父进程序列化全局状态然后在子进程反序列化的方式在子进程中保持来自父进程的全局状态。这当父进程包含非可序列化的全局内容时可能会导致问题。关于如何修正此问题的信息参见“@preserveGlobalState”一节

@small

@small 标注是 @group small 的别名。小型(small)测试不能依赖于标记为 @medium@large 的测试。

如果安装了 PHP_Invoker 组件包并启用了严格模式,一个执行时间超过1秒的小型(small)测试将会视为失败。这个超时限制可以通过 XML 配置文件的 timeoutForSmallTests 属性进行配置。

注意

需要启用运行时间限制的测试必须显式地标注为 @small@medium@large

@test

除了用 test 作为测试方法名称的前缀外,还可以在方法的文档注释块中用 @test 标注来将其标记为测试方法。

/**
* @test
*/
public function initialBalanceShouldBe0()
{
$this->assertEquals(0, $this->ba->getBalance());
}

@testdox


@ticket


@uses

@uses 标注用来指明那些将会在测试中执行到但同时又不打算让其被测试所覆盖的代码。在对代码单元进行测试时所必须的值对象就是个很好的例子。

/**
* @covers BankAccount::deposit
* @uses Money
*/
public function testMoneyCanBeDepositedInAccount()
{
// ...
}

在严格覆盖模式中,意外覆盖的代码将导致测试判定为失败,这个标注就显得特别有用。关于严格覆盖模式的更多信息,参见“意外的代码覆盖”一节

PHPUnit-附录 B. 标注的更多相关文章

  1. PHPUnit 手册

    PHPUnit 手册 Sebastian Bergmann 版权 © 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 ...

  2. PHPUnit 手册(转)

    PHPUnit 手册 PHPUnit 手册 Sebastian Bergmann 版权 © 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, ...

  3. PHP PHPUnit的简单使用

    1.window安装pear的教程:http://jingyan.baidu.com/article/ca41422fd8cf3d1eae99ed3e.html 2.在工作目录下,放两个文件: 1)C ...

  4. phpunit学习 3:

    16:17 2015/12/11phpunit学习 3:单元测试的大概步骤是:编写待测试类,编写测试用例类,编写测试类,测试.1.如果你有多个类,多个测试类的test类,那么可以编写一个AllTest ...

  5. phpunit测试学习 1:一点简单的扼要有用的东西的总结 一点入门认识

    16:45 2015/12/8phpunit测试学习 1:一点简单的扼要有用的东西的总结  一点入门认识 具体的入门安装和入门实践请参照文中的推荐博客或网上其他博客推荐博客,我感觉这几篇博客写得很不错 ...

  6. PHPUNIT 单元测试

    在windows上的安装可以参考其手册 首先下载phpunit.phar文件 1. 为php的二进制可执行文件建立 一个目录,如C:\bin 2. 将C:\bin添加到系统环境变量中, 3. 打开命令 ...

  7. 开始使用PHPUnit单元测试

    何为单元测试: 指对软件中的基本单元进行测试,如函数.方法等,以检查其返回值或行为是否符合预期:实际中软件是很复杂的,由许多组件构成,执行流程连贯在一起,要进行单元片段的测试,就需要为其提供执行上下文 ...

  8. 【夯实PHP基础】PHPUnit -- PHP测试框架

    本文地址 分享提纲: 1.概述 2.安装 3.编写第一个测试用例 4.PHPUnit高级 5.参考 1.概述 1)[测试框架] 它是一款轻量级的PHP测试框架,是一个xUnit的体系结构的单元测试框架 ...

  9. phpunit

    教程及文档: https://www.jianshu.com/p/abcca5aa3ad6 http://www.phpunit.cn/manual/current/zh_cn/phpunit-boo ...

随机推荐

  1. Cannot declare class app\home\controller\Cases because the name is already in use

    Cannot declare class app\home\controller\Cases because the name is already in use 命名空间冲突了 use 模型类的时候 ...

  2. [转载]利用memcached在多台服务器之间共享PHP的session数据

    原文地址:利用memcached在多台服务器之间共享PHP的session数据作者:a1049709658 最近我的几篇文章都是是最近项目的一点心得^^ 这个项目一开始就设计的"很大&quo ...

  3. ip 淘宝ip库 精简版

    <?php header('Content-type: text/html; charset=utf-8'); //根据ip获取城市.网络运营商等信息 function findCityByIp ...

  4. Ajax常用实例

    摘录自:http://www.cnblogs.com/gaopeng527/p/4459622.html 1. 级联下拉列表 例1.1 级联下拉列表. (1)编写AjaxRequest.js文件,并将 ...

  5. git学习网址

    git的学习网址:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/

  6. mybatis一级缓存二级缓存

    一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...

  7. redis 安装实战(10步完成安装)

    1 下载zip :https://redis.io/download   ---->redis-4.0.6 2 上传:利用wcp 上传到/usr/local/soft/ 3 解压:tar -zv ...

  8. Azure CLI对ASM,ARM资源的基本操作

    本文主要介绍Windows Azure CLI对ASM及ARM资源的基本操作 1.在windows的CMD或Powershell环境下,输入命令:azure,可以查看到当前操作的模式为ASM还是ARM ...

  9. python_18_反射

    什么是反射? -- 通过输入字符串来获取和修改 类(属性+方法),用字符串来映射内存对象,用于人机交互 反射有哪几种方法? -- getattr()                   --获取字符串 ...

  10. java1.8--1.8入门介绍

    在我之前的工作中,一直使用的是java6.所以即使现在java已经到了1.8,对于1.7增加的新特性我也基本没使用的.在整理一系列1.8的新特性的过程中,我也会添加上1.7增加的特性. 下面的整理可能 ...