【问题标题】:PHPUnit passing a test with no assertions within configPHPUnit 在配置中通过了没有断言的测试
【发布时间】:2011-10-03 17:17:22
【问题描述】:

我想通过得到以下结果的测试:“这个测试没有执行任何断言”

我知道我可以添加类似assertTrue(true) 的内容,但是是否可以在配置中添加一些内容以使这些测试更清晰地通过?

我很确定这只发生在 PHPUnit 3.5.0 版本之后,引入了 --strict

【问题讨论】:

    标签: phpunit


    【解决方案1】:

    使用@doesNotPerformAssertions annotation

    /**
     * @doesNotPerformAssertions
     */
    public function testCodeWithoutUsingAssertions()
    {
        // do stuff...
    }
    

    【讨论】:

    • 请注意,它不会为此类方法生成覆盖率
    • @simPod 是的,这是一件好事,因为不进行断言仅意味着您正在测试是否捕获到异常。而且,如果您正确地进行了 TDD,那么所有其他代码无论如何都会经过其他测试的测试。所以你不需要其他覆盖。
    • @David 这是错误的。我可以在没有断言的情况下进行测试。例如。一些代码运行并且不抛出。测试不仅仅是断言。
    • 但即使没有断言,我也需要覆盖。我不会泄露“所有其他代码”的覆盖率,所以我知道我专门为什么编写了测试。
    【解决方案2】:

    使用 PHPUnit 7.2,您可以获得另一种选择:

    public function testCodeWithoutUsingAssertions()
    {
        $this->expectNotToPerformAssertions();
        // do stuff...
    }
    

    另见https://github.com/sebastianbergmann/phpunit/pull/3042

    【讨论】:

      【解决方案3】:

      编辑:您有几个选择,具体取决于您使用的版本,是要忽略 所有 有风险的测试还是只忽略几个,以及是否你希望它是永久的还是临时的。

      在 5.6 之前,如果您不想在所有测试中添加虚假断言,则必须避免将 --strict 传递给 PHPUnit 或将 strict="false" 添加到您的 phpunit.xml。此选项的要点是“如果没有做出任何断言,则将测试标记为不完整。”

      在某些时候,PHPUnit 添加了相关的--dont-report-useless-tests 命令行开关和beStrictAboutTestsThatDoNotTestAnything="false" 配置选项。我没有检查它们是替代品还是额外的细粒度版本。

      上述选项会影响所有有风险的测试。使用它们会让你在没有断言的情况下意外编写测试。以下新选项更安全,因为您必须有目的地标记您希望允许的每个有风险的测试。

      PHPUnit 5.6 添加了 @doesNotPerformAssertions 注释以将单个测试用例标记为“无风险”,即使它们不执行任何断言。

      /**
       * @doesNotPerformAssertions
       */
      public function testWithoutAsserting() {
          $x = 5;
      }
      

      PHPUnit 7.2 引入了 TestCase::expectNotToPerformAssertions(),它做同样的事情。

      public function testWithoutAsserting() {
          $this->expectNotToPerformAssertions();
          $x = 5;
      }
      

      【讨论】:

      • 我如何不通过 --strict ?我只是运行 phpunit,所以我猜它在配置 xml 中正确吗?
      • 是的,在<phpunit> 元素中使用strict="false" 或者直接省略它,因为默认应该是false
      • 一种更简洁的方法是将此行放在测试的开头$this->expectNotToPerformAssertions();
      【解决方案4】:

      使用$this->addToAssertionCount(1)。见下文。

      class NoAssertTest extends PHPUnit_Framework_TestCase
      {
          function testWithoutAssertions() {
              $x = 5;
      
              // Increment the assertion count to signal this test passed.
              // This is important if you use a @depends on this test
              $this->addToAssertionCount(1);
          }
      }
      

      【讨论】:

        【解决方案5】:

        如果你有 PHP SimpleTest,另一种方法是使用:

        $this->pass();
        

        这会将测试标记为已完成并通过。

        另一方面,对于您想要失败的测试,您可以使用:

        $this->fail();
        

        例如:

        if (someComplicatedLogicValidation) {
            // Do more stuff and asserts
        } else{
            $this->fail();
        }
        

        我在 PHP 5.5 中试过这个并且工作正常:

        function testThatWorks() {
            $this->pass();
        }
        
        function testThatFails() {
            $this->fail();
        }
        

        输出:

        1) 在 [...ExampleTest.unit.php 第 23 行] 失败 在 testThatFails 在 ExampleTest 在 .../ExampleTest.unit.php 3.02s内失败

        也许方法传递仍然可以在 PHPUnit 中轻松实现。来自 SimpleTest:

        function pass($message = "Pass") {
            if (! isset($this->reporter)) {
                trigger_error('Can only make assertions within test methods');
            }
            $this->reporter->paintPass(
            $message . $this->getAssertionLine());
            return true;
        }
        

        【讨论】:

        • 方法 pass() 在 PHPUnit >= 4.4 中不存在。不确定它以前是否存在过。
        • @awei 我们正在使用 PHP 5,它确实如此,我们曾经有 4.X,它也是如此。将在星期一更新正确的版本号和插件版本。
        • @awei 是的,确实有效,在我的回答中添加了编辑。
        • 您使用的是哪个版本的 PHPUnit?在“phpunit/phpunit”版本中:“~4.4”这不起作用。
        • 这就解释了。你能粘贴你的 SimpleTest->passes() 方法吗?我很想看看里面有什么。
        【解决方案6】:

        在我的情况下,测试没有断言,因为我只是使用prophecy lib 检查所有内容来模拟并检查方法是否按预期被调用...

        默认情况下,PHPUnit 期望 test 至少有一个断言,并警告您放置它。

        只需在测试的任何部分添加这一行就足够了。

        $this->expectNotToPerformAssertions();
        

        但你也可以设计一个在某些情况下有断言或没有断言的测试

        public function testCodeNoAssertions()
        {
            if ($something === true) {
                $this->expectNotToPerformAssertions();
            }
            // do stuff...
        
            if ($somethingElse === true) {
            //do any assertion
            }
        }
        

        总之,这不是错误...这是一个功能。

        【讨论】:

          【解决方案7】:

          PHPUnit 7.2+。 $this->expectNotToPerformAssertions() 可以使用,如果您有可能禁用断言的条件。似乎不在官方文档中,但可以在这里找到:https://github.com/sebastianbergmann/phpunit/pull/3042/files

          public function testCodeNoAssertions()
          {
              $this->expectNotToPerformAssertions();
          }
          

          至少 PHPUnit 7.0+。 @doesNotPerformAssertions 可以使用。当前文档未说明添加此内容的时间。 https://phpunit.readthedocs.io/en/7.0/annotations.html#doesnotperformassertions

          /**
           * @doesNotPerformAssertions
           */
          public function testCodeWithoutUsingAssertions()
          {
          
          }
          

          如果您的测试只是不完整,您应该使用 $this->markTestIncomplete() https://phpunit.readthedocs.io/en/7.0/incomplete-and-skipped-tests.html

          public function testCodeThatIsIncomplete()
          {
              $this->markTestIncomplete('Implementation of this test is not complete.');
          }
          

          如果您想暂时禁用测试,则应使用 $this->markTestSkipped()https://phpunit.readthedocs.io/en/7.0/incomplete-and-skipped-tests.html#skipping-tests

          public function testCodeThatIsDisabledTemporarily()
          {
              $this->markTestSkipped('This test is disabled to test, if it is interfering with other tests.');
          }
          

          【讨论】:

            【解决方案8】:

            我创建了一个超类并在那里放置了类似 SimpleTest 的函数:

            /**
             * Pass a test
             */
            public function pass()
            {
                //phpunit is missing pass()
                $this->assertTrue(true);
            }
            

            那你就可以调用它了

            $this->pass();
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-02-17
              • 1970-01-01
              • 2020-04-26
              • 2011-08-19
              • 2020-08-06
              • 2021-04-20
              • 2013-02-02
              • 1970-01-01
              相关资源
              最近更新 更多