PHPUnit桥接

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.4,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

PHPUnit桥接

PHPUnit Bridge提供了报告遗留测试和废弃代码使用情况的实用程序,以及时间敏感测试和网络敏感测试的帮助程序。

它具有以下功能:

  • 强制测试使用一致的区域设置(C)(如果创建区域敏感的测试,请使用PHPUnit的setLocale ()方法);
  • Auto-registerclass_exists加载Doctrine注释(当使用时);
  • 它显示了应用程序中使用的已弃用特性的整个列表;
  • 按需显示弃用的堆栈跟踪;
  • 提供了一个ClockMock而且DnsMock用于时间和网络敏感测试的Helper类;
  • 提供不嵌入的PHPUnit的修改版本欧宝娱乐app下载地址symfony / yaml也不预言为了防止与这些依赖项发生冲突;

安装

1
编写器require—dev“欧宝娱乐app下载地址symfony / phpunit-bridge: *”

请注意

如果在Symfony应用程序外部安装此组件,则必须要求欧宝娱乐app下载地址供应商/ autoload.php文件,以启用Composer提供的类自动加载机制。读这篇文章欲知详情。

请注意

PHPUnit桥设计用于使用Symfony组件的所有维护版本,甚至跨不同的主要版本。欧宝娱乐app下载地址您应该始终使用其最新的稳定主版本,以获得最准确的弃用报告。

如果你打算PHPUnit桥接并且使用常规的PHPUnit脚本(不是Symfony提供的修改后的PHPUnit脚本),您必须注册一个新的欧宝娱乐app下载地址测试监听器被称为欧宝娱乐app下载地址SymfonyTestsListener

1 2 3 4 5 6 7 8 9 10 11
<!——http://phpunit.de/manual/6.0/en/appendixes.configuration.html——><phpunit)xmlns: xsi“http://www.w3.org/2001/XMLSchema-instance”xsi: noNamespaceSchemaLocation“https://schema.phpunit.de/6.0/phpunit.xsd”><!——……--><听众><侦听器“欧宝娱乐app下载地址Symfony \ \ PhpUnit) \ SymfonyTestsListener桥”/>听众>phpunit)>

使用

另请参阅

本文解释了如何在任何PHP应用程序中使用PhpUnitBridge特性作为独立组件。读了测试文章,以了解如何在Symfony应用程序中使用它。欧宝娱乐app下载地址

一旦组件被安装,asimple-phpunit脚本在供应商/目录运行测试。这个脚本包装了原始的PHPUnit二进制文件,以提供更多的功能:

1 2
cd我的项目//供应商/ bin / simple-phpunit

在运行你的PHPUnit测试之后,你会得到一个类似于下面的报告:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
phpunit -c应用程序的phpunit。配置从<项目> / app / phpunit.xml。经销  .................时间:1.77秒,内存:5.75Mb OK(17个测试,21个断言)剩余的弃用通知(2)getEntityManager自Symfony 2.1以来已弃用。欧宝娱乐app下载地址请使用getManager: 2x 1xDefaultControllerTest:: testpublicurl from AppBundle\Tests\Controller 1xBlogControllerTest::testIndex来自AppBundle\Tests\Controller

总结内容包括:

Unsilenced
报告在没有建议的情况下触发的弃用通知@-silencing运营商
遗产
弃用通知表示显式测试某些遗留特性的测试。
剩余的/其他
弃用通知是所有其他(非遗留)通知,按消息、测试类和方法分组。

请注意

如果你不想用simple-phpunit脚本,注册以下内容PHPUnit事件监听器在PHPUnit配置文件中获得相同的关于弃用的报告(该报告由PHP错误处理程序被称为DeprecationErrorHandler):

1 2 3 4 5
<!——phpunit.xml.dist——><!——……--><听众><侦听器“欧宝娱乐app下载地址Symfony \ \ PhpUnit) \ SymfonyTestsListener桥”/>听众>

并行运行测试

修改后的PHPUnit脚本允许通过提供包含多个测试套件的目录来并行运行测试phpunit.xml.dist

1 2 3 4 5 6 7
├──tests/│├──Functional/││├──…││├──phpunt .xml.dist│├──Unit/││├──…││├─phpunt .xml.dist
1
/ /供应商/ bin / simple-phpunit测试

修改后的PHPUnit脚本将递归地遍历所提供的目录,最多可遍历3个子目录或环境变量指定的值欧宝娱乐app下载地址SYMFONY_PHPUNIT_MAX_DEPTH,寻找phpunit.xml.dist文件,然后并行运行它找到的每个套件,收集它们的输出,并在各自的部分中显示每个测试套件的结果。

触发弃用通知

使用以下命令可以触发弃用通知:

1
@trigger_error (“您的弃用信息”, E_USER_DEPRECATED);

没有@-silencing运营商,用户将需要选择退出弃用通知。默认情况下,沉默可以交换这种行为,并允许用户在准备好应对这些错误时选择加入(通过添加一个自定义错误处理程序,就像这个桥所提供的那样)。未静音时,弃用通知将出现在Unsilenced部分的弃用报告。

将测试标记为遗产

有三种方法将测试标记为遗留:

  • 推荐)加上@group遗留类或方法的注释;
  • 的类名开始遗产前缀;
  • 使其方法名以testLegacy * ()而不是测试* ()

请注意

如果数据提供程序调用的代码通常会触发弃用,则可以在其名称前加上provideLegacygetLegacy为了平息这些反对意见。如果您的数据提供程序没有执行废弃的代码,那么不需要选择特殊的命名,因为数据提供程序提供的测试被标记为遗留的。

还要注意,选择两个遗留前缀之一将不会将使用此数据提供程序的测试标记为遗留测试。您仍然必须显式地将它们标记为遗留测试。

配置

如果需要检查单元测试触发的特定弃用的堆栈跟踪,则可以设置欧宝娱乐app下载地址SYMFONY_DEPRECATIONS_HELPER环境变量到与此弃用消息匹配的正则表达式,并用/.例如,使用:

12 3 4 5 6 7 8 9 10 11 12
<!——http://phpunit.de/manual/6.0/en/appendixes.configuration.html——><phpunit)xmlns: xsi“http://www.w3.org/2001/XMLSchema-instance”xsi: noNamespaceSchemaLocation“https://schema.phpunit.de/6.0/phpunit.xsd”><!——……--><php><服务器的名字“KERNEL_DIR”价值“应用程序/”/><env的名字“欧宝娱乐app下载地址SYMFONY_DEPRECATIONS_HELPER”价值“foobar /”/>php>phpunit)>

PHPUnit)将停止您的测试套件一旦弃用通知被触发,其消息包含“foobar”字符串。

使测试失败

默认情况下,任何非遗留标记或任何非“@-silenced”_弃用通知将使测试失败。另外,设置欧宝娱乐app下载地址SYMFONY_DEPRECATIONS_HELPER到任意值(例如:320)将使测试仅在达到较高数量的弃用通知(0为默认值)。您也可以设置该值“弱”这将使桥忽略任何弃用通知。这对于由于向后兼容性原因而必须使用弃用接口的项目非常有用。

在维护库时,一旦依赖项引入了新的弃用,就让测试套件失败是不可取的,因为这会将修复该弃用的负担转移到恰好在带有该弃用的新供应商发布后不久提交了pull请求的任何贡献者身上。为了缓解这一问题,您可以使用更严格的需求,希望依赖关系不会在补丁版本中引入弃用,或者甚至提交Composer锁文件,这将产生另一类问题。图书馆将经常使用欧宝娱乐app下载地址SYMFONY_DEPRECATIONS_HELPER =弱正因为如此。这样做的缺点是允许引入弃用的贡献,但是:

  • 忘记修复被弃用的调用,如果有任何;
  • 属性标记适当的测试@group遗留注释。

通过使用“weak_vendors”对象之外触发的弃用供应商目录将使测试套件失败,而由其中的库触发的弃用则不会,这为您提供了两全其美的方法。

禁用弃用助手

设置欧宝娱乐app下载地址SYMFONY_DEPRECATIONS_HELPER环境变量为禁用完全禁用弃用帮助程序。这对于使用该组件提供的其他特性而不会得到与弃用相关的错误或消息非常有用。

编写关于弃用的断言

在向代码中添加弃用项时,您可能喜欢编写测试来验证它们是否按要求被触发。为此,桥接提供@expectedDeprecation可以在测试方法上使用的注释。它要求您传递预期的消息,该消息以与PHPUnit)的assertStringMatchesFormat ()方法。如果你期望一个给定的测试方法有多个弃用消息,你可以多次使用注释(顺序很重要):

1 2 3 4 5 6 7 8 9 10
/ * * *@group遗留*@expectedDeprecation此“%s”方法已弃用。*@expectedDeprecation“%s”方法的第二个参数已弃用。* /公共函数testDeprecatedCode(){@trigger_error (“这种‘Foo’方法已弃用。”, E_USER_DEPRECATED);@trigger_error (“Bar”方法的第二个参数已弃用。”, E_USER_DEPRECATED);}

显示完整的堆栈跟踪

默认情况下,PHPUnit桥只显示弃用消息。若要显示与弃用相关的完整堆栈跟踪,请设置的值欧宝娱乐app下载地址SYMFONY_DEPRECATIONS_HELPER到匹配弃用消息的正则表达式。

例如,如果抛出以下弃用通知:

1 2
1x: Doctrine\Common\ClassLoader已弃用。1 xEntityTypeTest::安装从Symfony\欧宝娱乐app下载地址桥\学说\测试\形式\类型

运行以下命令将显示完整的堆栈跟踪:

1
欧宝娱乐app下载地址SYMFONY_DEPRECATIONS_HELPER ='/Doctrine\\Common\\ClassLoader已弃用\./'/供应商/ bin / simple-phpunit

对时间敏感的测试

用例

如果你有这种与时间相关的测试:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
使用PHPUnit)框架TestCase使用欧宝娱乐app下载地址组件秒表秒表MyTest扩展TestCase公共函数testSomething()秒表秒表();秒表->开始(“event_name”);睡眠(10);持续时间秒表->停止(“event_name”->getDuration ();->assertequal (10000持续时间);}}

你使用了欧宝娱乐app下载地址Symfony秒表组件要计算进程的持续时间,这里是10秒。但是,根据服务器负载或本地计算机上运行的进程的不同美元的持续时间例如,可以是10.000023秒而不是十年代

这种测试被称为瞬态测试:它们根据虚假和外部环境随机失败。它们经常在使用公共持续集成服务时造成麻烦,例如特拉维斯CI

时钟嘲笑

ClockMock类允许您模拟PHP的内置时间函数时间()()睡眠()usleep ()而且函数().另外,函数日期()是模拟的,因此如果没有指定时间戳,则使用模拟时间。

具有可选时间戳参数的其他函数,默认为时间()仍将使用系统时间而不是模拟时间。这意味着您可能需要更改测试中的某些代码。例如,而不是新的DateTime (),你应该使用DateTime: createFromFormat(“U”,时间())使用被嘲笑的时间()函数。

使用ClockMock类中添加@group时效性注释到它的类或方法。方法执行PHPUnit时,此注释才有效供应商/ bin / simple-phpunit脚本或在PHPUnit配置中注册以下监听器时:

1 2 3 4 5
<!——phpunit.xml.dist——><!——……--><听众><侦听器“\欧宝娱乐app下载地址 Symfony \ \ PhpUnit) \ SymfonyTestsListener桥”/>听众>

请注意

如果你不想用@group时效性注释,您可以注册ClockMock通过调用ClockMock:注册(__CLASS__进行)而且ClockMock: withClockMock(真正的)在考试之前ClockMock:: withClockMock(假)考试后。

因此,以下保证工作,不再是一个瞬态测试:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
使用PHPUnit)框架TestCase使用欧宝娱乐app下载地址组件秒表秒表/ * * *@group对时间敏感的* /MyTest扩展TestCase公共函数testSomething()秒表秒表();秒表->开始(“event_name”);睡眠(10);持续时间秒表->停止(“event_name”->getDuration ();->assertequal (10000持续时间);}}

这就是全部!

谨慎

基于时间的函数模拟遵循PHP名称空间解析规则因此,“完全限定函数调用”(例如\(时间))不能被嘲笑。

@group时效性注释相当于调用ClockMock:注册(MyTest::类).如果要模拟在不同类中使用的函数,请显式地使用ClockMock:注册(MyClass::类)

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
//使用time()函数被模拟的类名称空间应用程序MyClass公共函数getTimeInHours()返回时间()/3600;}}//显式模拟外部time()函数的测试名称空间应用程序测试使用应用程序MyClass使用PHPUnit)框架TestCase使用欧宝娱乐app下载地址PhpUnit)ClockMock/ * * *@group对时间敏感的* /MyTest扩展TestCase公共函数testGetTimeInHours(){ClockMock::注册(MyClass::类);我的MyClass ();结果我的->getTimeInHours ();->assertequal() /(时间3600结果);}}

提示

的额外好处ClockMock阶级就是时间瞬间流逝。使用PHP的睡眠(10)将使您的测试等待10秒(或多或少)。相比之下,ClockMock类将内部时钟向前推进给定的秒数,而无需实际等待该时间,因此您的测试将快10秒执行。

DNS-sensitive测试

建立网络连接的测试(例如检查DNS记录的有效性)可能由于网络条件而执行缓慢且不可靠。因此,该组件还提供了以下PHP函数的模拟:

用例

方法的示例如下checkMX选项电子邮件测试电子邮件域有效性的约束:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
使用PHPUnit)框架TestCase使用欧宝娱乐app下载地址组件验证器约束电子邮件MyTest扩展TestCase公共函数testEmail()验证器=……约束电子邮件([“checkMX”= >真正的]);结果验证器->validate (“foo@example.com”约束);/ /……}}

为了避免进行真正的网络连接,请添加@dns-sensitive类的注释,并使用DnsMock: withMockedHosts ()要配置您希望获得的给定主机的数据:

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
使用PHPUnit)框架TestCase使用欧宝娱乐app下载地址组件验证器约束电子邮件/ * * *@groupdns-sensitive * /MyTest扩展TestCase公共函数testEmails(){DnsMock::withMockedHosts ([“example.com”= > [[“类型”= >“MX”]]]);验证器=……约束电子邮件([“checkMX”= >真正的]);结果验证器->validate (“foo@example.com”约束);/ /……}}

withMockedHosts ()方法配置定义为一个数组。键是模拟的主机,值是返回的相同格式的DNS记录数组dns_get_record,可以模拟不同的网络情况:

12 3 4 5 6 7 8 9 10 11 12
DnsMock::withMockedHosts ([“example.com”=> [[“类型”= >“一个”“知识产权”= >“为1.2.3.4”,], [“类型”= >“AAAA”“ipv6”= >“::12”,],],]);

故障排除

@group时效性而且@group dns-sensitive注释“按照约定”工作,并假设测试类的名称空间可以通过删除测试\部分来自test名称空间。例如,如果您的测试用例完全限定类名(FQCN)是应用\ \看\ DummyWatchTest测试,它假设测试的类名称空间为App \看

如果此约定不适用于您的应用程序,请在phpunit.xml文件,例如在HttpKernel组件

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<!——http://phpunit.de/manual/4.1/en/appendixes.configuration.html——><phpunit)xmlns: xsi“http://www.w3.org/2001/XMLSchema-instance”xsi: noNamespaceSchemaLocation“https://schema.phpunit.de/4.1/phpunit.xsd”><!——……--><听众><侦听器“欧宝娱乐app下载地址Symfony \ \ PhpUnit) \ SymfonyTestsListener桥”><参数><数组><元素关键“时效性”><字符串>欧宝娱乐app下载地址Symfony \ \ HttpFoundation组件字符串>元素>数组>参数>侦听器>听众>phpunit)>

在底层,PHPUnit侦听器将模拟函数注入测试类的名称空间。为了按预期工作,侦听器必须在被测试的类运行之前运行。默认情况下,当找到注释并运行相应的测试时,将创建模拟函数。这取决于您的测试是如何构造的,可能为时已晚。在这种情况下,您需要在您的数据库中声明测试类的名称空间phpunit.xml.dist

1 2 3 4 5 6 7 8 9 10 11
<!——phpunit.xml.dist——><!——……--><听众><侦听器“欧宝娱乐app下载地址Symfony \ \ PhpUnit) \ SymfonyTestsListener桥”><参数><数组><元素关键“时效性”><字符串>Acme \ MyClassTest字符串>元素>数组>参数>侦听器>听众>

修改PHPUnit脚本

3.2

修改后的PHPUnit脚本在该组件的3.2版本中引入。

这个桥提供了PHPUnit的修改版本,您可以使用它来调用bin / simple-phpunit命令。它具有以下特点:

  • 不嵌入欧宝娱乐app下载地址symfony / yaml也不预言为了防止与这些依赖项发生冲突;
  • 使用PHPUnit 4.8时运行的PHP <=5.5, PHPUnit 5.7时运行的PHP >=5.6和PHPUnit 6.5时运行的PHP >=7.2;
  • 控件时收集并重放跳过的测试欧宝娱乐app下载地址SYMFONY_PHPUNIT_SKIPPED_TESTS定义了Env var: Env var应该指定一个文件名,该文件名将用于存储第一次运行时跳过的测试,并在第二次运行时重播它们;
  • 当给定一个目录作为参数时,并行执行测试套件,扫描该目录phpunit.xml.dist档案最高可达欧宝娱乐app下载地址SYMFONY_PHPUNIT_MAX_DEPTH级别(指定为env变量,默认为3.);

脚本将它构建的修改后的PHPUnit写入一个目录,该目录可以由欧宝娱乐app下载地址SYMFONY_PHPUNIT_DIREnv变量,或者在与simple-phpunit如果没有提供。

如果你已经通过Composer安装了桥接器,你可以调用e.g.来运行它:

1
供应商/ bin / simple-phpunit

提示

属性可以改变PHPUnit的基本版本欧宝娱乐app下载地址SYMFONY_PHPUNIT_VERSION的Env varphpunit.xml.dist文件(如。<服务器名="SYMFONY欧宝娱乐app下载地址_PHPUNIT_VERSION" value="5.5"/>).这是首选的方法,因为它可以提交到您的版本控制存储库。

也可以设置欧宝娱乐app下载地址SYMFONY_PHPUNIT_VERSION作为一个真正的环境变量(没有定义在dotenv文件)。

提示

如果你还需要的话预言(但不欧宝娱乐app下载地址symfony / yaml),然后设置欧宝娱乐app下载地址SYMFONY_PHPUNIT_REMOVE环境变量欧宝娱乐app下载地址symfony / yaml

代码覆盖侦听器

默认情况下,使用以下规则计算代码覆盖率:如果执行了一行代码,则将其标记为覆盖。因此,执行一行代码的测试被标记为“覆盖一行代码”。这可能会产生误导。

考虑下面的例子:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
酒吧公共函数barMethod()返回“酒吧”;}}喷火私人酒吧公共函数__construct(酒吧酒吧->酒吧=酒吧;}公共函数fooMethod()->酒吧->barMethod ();返回“酒吧”;}}扩展PHPUnit)框架TestCase公共函数测验()酒吧酒吧();喷火Foo (酒吧);->assertSame (“酒吧”喷火->fooMethod ());}}

脚:测试方法执行两者的每一行代码喷火而且酒吧类,但酒吧没有经过真正的测试。的CoverageListener旨在通过添加适当的@covers每个测试类上的注释。

类型的测试类@covers注释,这个侦听器什么也不做。方法来查找与测试相关的代码测试类名的一部分:我\名称空间\ \脚测试->我\名称空间\ Foo

安装

将以下配置添加到phpunit.xml.dist文件:

1 2 3 4 5 6 7 8 9 10 11
<!——http://phpunit.de/manual/6.0/en/appendixes.configuration.html——><phpunit)xmlns: xsi“http://www.w3.org/2001/XMLSchema-instance”xsi: noNamespaceSchemaLocation“https://schema.phpunit.de/6.0/phpunit.xsd”><!——……--><听众><侦听器“欧宝娱乐app下载地址Symfony \ \ PhpUnit) \ CoverageListener桥”/>听众>phpunit)>

如果用于查找相关代码的逻辑太简单或不适合您的应用程序,您可以使用自己的SUT(系统测试)求解器:

1 2 3 4 5 6 7
<听众><侦听器“欧宝娱乐app下载地址Symfony \ \ PhpUnit) \ CoverageListener桥”><参数><字符串>我的\ \ SutSolver:名称空间:解决字符串>参数>侦听器>听众>

我的\ \ SutSolver:名称空间:解决可以是任何PHP可调用对象,并接收当前测试作为其第一个参数。

最后,监听器还可以在SUT求解器没有找到SUT时显示警告消息:

1 2 3 4 5 6 7 8
<听众><侦听器“欧宝娱乐app下载地址Symfony \ \ PhpUnit) \ CoverageListener桥”><参数></><布尔>真正的布尔>参数>侦听器>听众>
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。