tp5 phpunit_PHPUnit 5概述-新增功能? 怎么了?

tp5 phpunit

This post has been peer reviewed by Cláudio Ribeiro and Thomas Punt. Many thanks to the reviewers who keep SitePoint’s content perpetually excellent!

该帖子已由CláudioRibeiro和Thomas Punt进行了同行评审 非常感谢审阅者,他们使SitePoint的内容永久出色!



It was January 2016 when the PHPUnit development team announced the release of PHPUnit 5.0.

在2016年1月,PHPUnit开发团队宣布发布PHPUnit 5.0。

Color pen on paper, putting checkmarks into some boxes and red X-es into others

While several minor version have already been released since, PHPUnit’s major version 5 has introduced several new functionalities and deprecated a few others. In this article, we’ll take a look at the most notable changes.

此后已经发布了几个次要版本,但PHPUnit的主要版本5引入了几个新功能,并且不推荐使用其他一些功能。 在本文中,我们将介绍最显着的变化。

要求 (Requirements)

PHPUnit 5 requires PHP 5.6. They have dropped support for PHP 5.3, 5.4, and 5.5 as they are not actively supported by the PHP project, according to their release process. You can see the full list of required PHP extensions here.

PHPUnit 5需要PHP 5.6。 根据其发布过程 ,由于PHP项目未积极支持它们,他们已放弃了对PHP 5.3、5.4和5.5的支持。 您可以在此处查看所需PHP扩展的完整列表。

新的断言方法 (New Assertion Methods)

Three assertion methods including assertFinite(), assertInfinite() and assertNan() have been added to the stack.

包括assertFinite()assertInfinite()assertNan()三种断言方法已添加到堆栈中。

assertFinite() asserts that the expected value is a finite value, meaning it is a legal number within the allowed range for a PHP float on the platform on which the test runs. Behind the scenes, it uses PHP’s built-in function is_finite, to check if the constraint is met.

assertFinite()断言期望值是一个有限值,这意味着它是在测试运行平台上PHP浮动允许范围内的合法数字。 在后台,它使用PHP的内置函数is_finite来检查是否满足约束。

Consider the following test:

考虑以下测试:

<?php
class FiniteTest extends PHPUnit_Framework_Testcase
{
    public function testFinite()
    {
        $this->assertFinite(INF);
    }
}

The above test would fail since INF is a PHP constant, representing an infinite value.

由于INF是一个PHP常量,表示一个无限值,因此上述测试将失败。

assertInfinite() verifies whether the actual value is an infinite number (either positive or negative), meaning a value too big to fit into a float on the current platform. This method uses PHP’s is_infinite function.

assertInfinite()验证实际值是否为无穷大(正数或负数),这意味着该值太大而无法容纳当前平台上的浮点数。 此方法使用PHP的is_infinite函数。

<?php
class InfiniteTest extends PHPUnit_Framework_Testcase
{
    public function testInfinite()
    {
        $this->assertInfinite(INF);
    }
}

The above assertion would give us the green light since INF is an infinite value.

由于INF为无穷大,因此上述断言将为我们开绿灯。

The third assertion is assertNan(), which fails if the expected value is not a NAN value. As you probably know, NAN means: not a number, which is the result of an invalid calculation in PHP, like acos(8).

第三个断言是assertNan() ,如果期望值不是NAN值,则它将失败。 您可能知道, NAN意思是: 不是数字 ,这是PHP中无效计算的结果,例如acos(8)

<?php
class NanTest extends PHPUnit_Framework_Testcase
{
    public function testNan()
    {
        $this->assertNan(14);
    }
}

The above test also fails, because the actual value is 14 while the expected value is a NAN.

上面的测试也失败了,因为实际值为14而预期值为NAN

All the above methods take the same arguments: the first argument is the actual value, and the second one (which is optional) is the message to print if the assertion fails.

以上所有方法都采用相同的参数:第一个参数是实际值,第二个参数(可选)是在断言失败时要打印的消息。

深度克隆传入的对象 (Deep Cloning of Passed-in Objects)

In PHPUnit versions prior to 5.0, a passed object (by using @depends) is passed as-is, meaning it is a reference to the actual object (not a clone). Consider the following code:

在5.0之前PHPUnit版本中,传递的对象(使用@depends )按@depends传递,这意味着它是对实际对象(不是克隆)的引用。 考虑以下代码:

<?php

class Foo
{
    public $bars = [];
}

class Bar
{
    public $name;

    function __construct($name)
    {
        $this->name = $name;
    }
}

class FooTest extends PHPUnit_Framework_TestCase
{
    public function testProducer()
    {
        $foo = new Foo();
        $foo->bars[] = new Bar('James');
        $foo->bars[] = new Bar('Kirk');
        $foo->bars[] = new Bar('Rob');

        $this->assertEquals(3, count($foo->bars));
        $this->assertEquals('Rob', $foo->bars[2]->name);

        return $foo;
    }

    /**
     * @depends testProducer
     */
    public function testFirstDependent($foo)
    {
        $foo->bars[0]->name = 'Lars';
        $this->assertEquals('Kirk', $foo->bars[1]->name);
    }

    /**
     * @depends testProducer
     */
    public function testSecondDependent($foo)
    {
        $this->assertEquals('James', $foo->bars[0]->name);
    }
}

Here’s the story: we have a class named Foo, which stores instances of class Bar. In our test class, we have three test methods: testProducer(), testFirstDependent(), and testSecondDependent(). The last two methods depend on the return value of testProducer().

这是故事:我们有一个名为Foo的类,该类存储Bar类的实例。 在我们的测试类中,我们有三种测试方法: testProducer()testFirstDependent()testSecondDependent() 。 最后两种方法取决于testProducer()的返回值。

When using @depends, $foo is passed by reference, meaning both dependent tests receive the same instance of the object. This means any modifications on the object within one of the test methods will affect the object within the other test method.

当使用@depends$foo通过引用传递,这意味着两个依赖测试都接收对象的相同实例。 这意味着对其中一种测试方法中的对象所做的任何修改都会影响另一种测试方法中的对象。

That said, testFirstDependent() changes $foo->bars[0]->name to James. This causes testSecondDependent() to fail, since $foo->bars[0] has been already modified by testFirstDependent().

也就是说, testFirstDependent()$foo->bars[0]->name更改为James 。 这导致testSecondDependent()失败,因为$foo->bars[0]已被testFirstDependent()修改。

This is the test result in PHPUnit version 4.8.24:

这是PHPUnit版本4.8.24中的测试结果:

PHPUnit 4.8.24 by Sebastian Bergmann and contributors.

..F

Time: 75 ms, Memory: 5.00Mb

There was 1 failure:

1) FooTest::testSecondDependent
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'James'
+'Lars'

/var/www/phpunit-example/tests/FooTest.php:47

FAILURES!
Tests: 3, Assertions: 4, Failures: 1.

Since PHPUnit 5.0, passed objects can be deeply cloned by using @depends clone. If we run the above the test (with @depends clone annotation in version 5.0 onwards), we’ll get a green light since each test is modifying and asserting its own copy of the passed object.

从PHPUnit 5.0开始,可以使用@depends clone深度克隆传递的对象。 如果我们在测试之上运行(在版本5.0及更高版本中使用@depends clone批注),则由于每项测试都在修改并声明其自己的传递对象副本,因此我们将获得@depends clone

<?php

// ...

class FooTest extends PHPUnit_Framework_TestCase
{
    public function testProducer()
    {
        $foo = new Foo();
        $foo->bars[] = new Bar('James');
        $foo->bars[] = new Bar('Kirk');
        $foo->bars[] = new Bar('Rob');

        $this->assertEquals(3, count($foo->bars));
        $this->assertEquals('Rob', $foo->bars[2]->name);

        return $foo;
    }

    /**
     * @depends clone testProducer
     */
    public function testFirstDependent($foo)
    {
        $foo->bars[0]->name = 'Lars';
        $this->assertEquals('Kirk', $foo->bars[1]->name);
    }

    /**
     * @depends clone testProducer
     */
    public function testSecondDependent($foo)
    {
        $this->assertEquals('James', $foo->bars[0]->name);
    }
}

Here’s the test result in PHPUnit version 5.3.2:

这是PHPUnit版本5.3.2中的测试结果:

PHPUnit 5.3.2 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 86 ms, Memory: 3.50Mb

OK (3 tests, 4 assertions)

传递带有预期的模拟对象 (Passing Mock Objects with Expectations)

Since PHPUnit 5.0, we can pass mock objects along with their expectations (an expectation asserts when and how a certain method is called) to the dependent test methods. This is not thoroughly possible in PHPUnit’s versions prior to version 5.0. Also, we can pass mock objects to the dependent test methods, but without any expectations. Consider the following example:

由于PHPUnit的5.0,我们可以与他们的期望 (期望值断言时和一定的方法是如何被调用),以在从属试验方法沿着通过模拟对象。 在PHPUnit 5.0之前的版本中,这不可能完全实现。 同样,我们可以将模拟对象传递给依赖的测试方法,但是没有任何期望。 考虑以下示例:

<?php
class fooTest extends PHPUnit_Framework_TestCase
{
    public function testProducer()
    {
        $fooMock = $this->getMock('Foo');

        $fooMock->expects($this->once())
                ->methods('bar')
                ->will($this->returnValue(true));

        return $fooMock;
    }

    /**
     * @depends clone testProducer
     */
    public function testDependant($mock)
    {
        // This will fail in versions prior to 5.0.0 as the actual value will be NULL
        $this->assertTrue(true, $mock->bar())
    }
}

The above test would fail in PHPUnit versions prior to 5.0, because we’re expecting true while the actual value is null. The reason is that the testProducer method returns the mock object without the expectations, meaning all methods will return null.

在5.0之前PHPUnit版本中,上述测试将失败,因为我们期望当实际值为null时为true 。 原因是testProducer方法返回的模拟对象没有期望值,这意味着所有方法都将返回null

PHPUnit 4.8.24 by Sebastian Bergmann and contributors.

.F

Time: 74 ms, Memory: 5.00Mb

There was 1 failure:

1) MockTest::testDependent
Failed asserting that null is true.

/var/www/phpunit-example/tests/MockTest.php:31

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

PHPUnit 5 will give us the green light since all mocks are passed along with their expectations.

PHPUnit 5将为我们开绿灯,因为所有模拟都随其期望而传递。

PHPUnit 5.3.2 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 57 ms, Memory: 3.75Mb

OK (2 tests, 2 assertions)

现在必须将白名单文件用于代码保护 (Whitelisting File for Code Coverage Is Now Mandatory)

Since PHPUnit 5.0, it is mandatory to configure a whitelist for code coverage analysis. In versions prior to 5.0, we only get a warning that no whitelist has been configured for code coverage, but the report would be generated anyway:

从PHPUnit 5.0开始,必须配置白名单以进行代码覆盖率分析。 在5.0之前的版本中,我们仅收到警告,未针对代码覆盖率配置白名单,但无论如何都会生成报告:

PHPUnit 4.8.24 by Sebastian Bergmann and contributors.
Warning:    No whitelist configured for code coverage

...........

Time: 2.42 seconds, Memory: 15.50Mb

OK (11 tests, 27 assertions)

Generating code coverage reports in HTML format ... done

Since version 5.0, we get an error and no code coverage would be generated:

从5.0版开始,我们会收到错误消息,并且不会生成代码覆盖率:

PHPUnit 5.3.2 by Sebastian Bergmann and contributors.

Error:         No whitelist configured, no code coverage will be generated

We should always configure the whitelist in phpunit.xml:

我们应该始终在phpunit.xml配置白名单:

<filter>
  <whitelist processUncoveredFilesFromWhitelist="true">
    <directory suffix=".php">/path/to/files</directory>
    <file>/path/to/file</file>
    <exclude>
      <directory suffix=".php">/path/to/files</directory>
      <file>/path/to/file</file>
    </exclude>
  </whitelist>
</filter>

创建少构造类模拟的便捷方法 (Convenient Way of Creating Constructor-Less Mocks)

In PHPUnit 5 we can directly create a mock with a disabled constructor by using getMockWithoutInvokingTheOriginalConstructor() method. This method is actually a wrapper for the disableOriginalConstructor() method:

在PHPUnit 5中,我们可以使用getMockWithoutInvokingTheOriginalConstructor()方法直接使用禁用的构造函数创建一个模拟。 此方法实际上是disableOriginalConstructor()方法的包装器:

<?php
public function getMockWithoutInvokingTheOriginalConstructor($originalClassName)
    {
        return $this->getMockBuilder($originalClassName)
                    ->disableOriginalConstructor()
                    ->getMock();
    }

According to the above source code we can use it like this:

根据上面的源代码,我们可以像这样使用它:

<?php
class MockTest extends PHPUnit_Framework_TestCase
{
    // ...
    protected $mock;
    public function setUp()
    {
        $this->mock = $this->getMockWithoutInvokingTheOriginalConstructor('Foo');
        $this->mock->expects($this->any())
             ->method('bar')
             ->will($this->returnValue(true));
    }
    // ...
}

命令行中的新选项 (New Options in the Command-Line)

PHPUnit 5 has introduced several options in the command line. One of these options is --reverse-list, which allows test failures to be sorted in reverse, so the first failure is printed at the bottom. This option is really handy when several tests depend on one test to pass, and if we fix the first one, the rest might be resolved automatically.

PHPUnit 5在命令行中引入了几个选项。 这些选项之一是--reverse-list ,它允许对测试失败进行反向排序,因此第一个失败会显示在底部。 当多个测试依赖于一个测试通过时,此选项非常方便,如果我们修复了第一个测试,则其他选项可能会自动解决。

The other new option is --whitelist, to configure a whitelist for code coverage analysis:

另一个新选项是--whitelist ,为代码覆盖率分析配置白名单:

phpunit --whitelist /path/to/php/files

There’s another option, which might be handy in some cases: --atleast-version. This option takes a number as the minimum PHPUnit version, and checks if the current version is greater than this value. We can use it to run the tests only if a certain version of PHPUnit is installed:

还有另一种选择,在某些情况下可能会很方便:-- --atleast-version 。 此选项将数字作为最低PHPUnit版本,并检查当前版本是否大于此值。 仅当安装了特定版本PHPUnit时,我们才可以使用它来运行测试:

phpunit --atleast-version 5.3 && phpunit --whitelist path/to/php/files

删除功能 (Removed Functionality)

Functionality that was marked deprecated in PHPUnit 4 has been removed in version 5.

PHPUnit 4中标记为不推荐使用的功能已在版本5中删除。

The following assertions have been removed:

以下断言已被删除:

  • assertSelectCount()

    assertSelectCount()

  • assertSelectRegExp()

    assertSelectRegExp()

  • assertSelectEquals()

    assertSelectEquals()

  • assertTag()

    assertTag()

  • assertNotTag()

    assertNotTag()

The --strict command-line option and strict attribute in the configuration file no longer exist.

配置文件中的--strict命令行选项和strict属性不再存在。

PHPUnit_Selenium is no longer bundled in the PHAR distributions and all the related settings in the configuration file have been removed.

PHPUnit_Selenium不再捆绑在PHAR发行版中,并且配置文件中的所有相关设置都已删除。

To see the full list of the added, changed and removed functionality and bug fixes, you may visit this page.

要查看已添加,已更改和已删除功能以及错误修复的完整列表,请访问此页面

结语 (Wrapping Up)

PHPUnit has dramatically changed some features, and thereby confused some developers who weren’t ready for it – we hope our post helps clear things up. A few assertions have been added to the stack and a few others have been deprecated. PHPUnit 5 has dropped support for PHP versions prior to 5.6. PHPUnit 6 has been scheduled for February 3, 2017 and will no longer support PHP 5.

PHPUnit极大地改变了某些功能,从而使一些尚未准备好进行开发的开发人员感到困惑–我们希望我们的帖子能帮助您解决问题。 一些断言已添加到堆栈中,而另一些断言已被弃用。 PHPUnit 5不再支持5.6之前PHP版本。 PHPUnit 6计划于2017年2月3日发布,将不再支持PHP 5。

Have you upgraded to PHPUnit 5 yet? If you have any comments or suggestions, or if there’s anything we missed in this article, please let us know in the comments!

您是否已升级到PHPUnit 5? 如果您有任何意见或建议,或者我们在本文中未填写任何内容,请在评论中告知我们!

翻译自: https://www.sitepoint.com/an-overview-of-phpunit-5-whats-new-whats-coming/

tp5 phpunit

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值