为什么我的自定义测试没有被PHPUnit启动?

时间:2019-06-06 15:25:06

标签: phpunit

PHPUnit doc中所述,您可以实现PHPUnit\Framework\Test来编写自定义测试。

听起来不错,但是我怎样才能将这些测试作为我的测试套件的一部分呢?

给出以下测试目录:

+tests/
   |- NormalTestExtendingTestCaseTest.php
   |- CustomTestImplementingTest.php
phpunit.xml

还有我的phpunit.xml文件:

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
>
    <testsuites>
        <testsuite name="My Test Suite">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

PHPUnit仅执行NormalTestExtendingTestCaseTest.php。


CustomTestImplementingTest.php

<?php
use PHPUnit\Framework\TestCase;

class CustomTestImplementingTest implements PHPUnit\Framework\Test
{

    public function count()
    {
        return 1;
    }

    public function run(PHPUnit\Framework\TestResult $result = null)
    {
        if ($result === null) {
            $result = new PHPUnit\Framework\TestResult;
        }

        $result->startTest($this);
        // do something
        $result->endTest($this, $stopTime);

        return $result;
    }
}

2 个答案:

答案 0 :(得分:0)

检查类是否具有正确的继承,正确的名称方法(以'test'开头)和正确的名称空间。

您可能必须运行作曲家dump-autoload。

答案 1 :(得分:0)

我找到了解决此问题的方法:

  1. 自定义测试类应实现suite()方法,以便PHPUnit运行生成的TestSuite(以及我们的测试)
  2. 测试类应声明一个getter方法getName()(即使未在接口PHPUnit\Framework\Test中声明它,或者在执行时引发异常。而且,名称不应为null或其他异常)在执行时被抛出。

所以最后一堂课是

<?php

use PHPUnit\Framework\TestResult;
use PHPUnit\Framework\TestSuite;
use SebastianBergmann\Timer\Timer;
use PHPUnit\Framework\Test;

class CustomTestImplementingTest implements Test {

    protected $name = '';

    /**
     * This method create a TestSuite for this Test
     *
     * @return TestSuite
     * @throws ReflectionException
     */
    public static function suite() {
        $classname = (new \ReflectionClass(static::class))->getShortName();
        $suite = new TestSuite();
        $suite->setName($classname);
        $suite->addTest(new static());
        return $suite;
    }

    /**
     * @return mixed
     */
    public function getName() {
        return $this->name;
    }

    /**
     * @param mixed $name
     */
    public function setName($name): void {
        $this->name = $name;
    }

    public function count() {
        return 1;
    }

    public function run(TestResult $result = null): TestResult {
        if ($result === null) {
            $result = new PHPUnit\Framework\TestResult;
        }
        Timer::start();
        $stopTime = null;
        $result->startTest($this);

        try {
            // do something
        } catch (PHPUnit\Framework\AssertionFailedError $e) {
            $result->addFailure($this, $e, $stopTime);
        } catch (Exception $e) {
            $result->addError($this, $e, $stopTime);
        } finally {
            $stopTime = Timer::stop();
        }

        $result->endTest($this, $stopTime);

        return $result;
    }
}