为什么我的定制测试不是由PHPUnit启动的?

为什么我的定制测试不是由PHPUnit启动的?,phpunit,Phpunit,如中所述,您可以实现PHPUnit\Framework\Test来编写自定义测试 听起来不错,但是如何将这些测试作为测试套件的一部分来启动呢 给定以下测试目录: +tests/ |- NormalTestExtendingTestCaseTest.php |- CustomTestImplementingTest.php phpunit.xml 和我的phpunit.xml文件: <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSc

如中所述,您可以实现
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;
    }
}

检查类是否具有正确的继承、正确的名称方法(以“test”开头)和正确的命名空间


您可能需要运行composer转储自动加载

检查类是否具有正确的继承、正确的名称方法(以“test”开头)和正确的命名空间


您可能需要运行composer转储自动加载

我找到了这个问题的解决方案:

  • 自定义测试类应该实现一个
    suite()
    方法,以便PHPUnit运行生成的测试套件(与我们的测试一起)
  • 测试类应该声明一个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;
        }
    }
    

    我找到了这个问题的解决方案:

  • 自定义测试类应该实现一个
    suite()
    方法,以便PHPUnit运行生成的测试套件(与我们的测试一起)
  • 测试类应该声明一个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;
        }
    }
    

    当我的类实现
    Test
    而不是
    TestCase
    时,我希望
    run
    方法被称为
    Test…()
    方法。当我的类实现
    Test
    而不是
    TestCase
    时,我希望
    run
    方法被称为
    Test…()
    方法。