cdn77/test-utils

Cdn77 Test Utils for PHP

0.5.2 2024-08-29 07:55 UTC

This package is auto-updated.

Last update: 2024-08-29 07:56:31 UTC


README

GitHub Actions Code Coverage Downloads Packagist Infection MSI

内容

安装

  • 将此项目作为composer开发依赖项要求
composer require --dev cdn77/test-utils

特性

存根

通过反射创建对象以绕过构造函数的工厂。

<?php

class MyEntity 
{
    /** @var string */
    private $property1;

    /** @var string */
    private $property2;

    public function __construct(string $property1, string $property2) 
    {
        $this->property1 = $property1;
        $this->property2 = $property2;
    }

    public function salute() : string 
    {
        return sprintf('Hello %s!', $this->property2);
    }
}

当测试方法 salute() 时,您只需要测试类设置了 property2,您不想担心 property1。因此,在您的测试中,您可以使用 Stub::create() 初始化 MyEntity,如下所示

$myEntity = Stub::create(MyEntity::class, ['property2' => 'world']);

self::assertSame('Hello world!', $myEntity->salute());

当类构造函数有更多参数且其中大部分不是您测试所需的参数时,这非常有用。

可以扩展存根

$myEntity = Stub::create(MyEntity::class, ['property2' => 'world']);
$myEntity = Stub::extends($myEntity, ['property1' => 'value']);

// property 1 and 2 are set now
self::assertSame('Hello world!', $myEntity->salute());

测试检查

测试检查用于断言测试符合您的套件标准(是否为final,是否扩展正确的TestCaseBase等)

要运行它们,例如创建一个类似于以下示例的测试用例

<?php

use Cdn77\TestUtils\TestCheck\TestCheck;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversNothing;
use PHPUnit\Framework\Attributes\Group;

 #[CoversNothing]
 #[Group('integration')]
final class SuiteComplianceTest extends TestCaseBase
{
    /** @dataProvider providerChecks */
    public function testChecks(TestCheck $check) : void
    {
        $check->run($this);
    }

    /** @return Generator<string, array{callable(self): TestCheck}> */
    public static function providerChecks() : Generator
    {
        $testDir = ROOT_PROJECT_DIR . '/tests';
        $testFilePathNames = \Symfony\Component\Finder\Finder::create()
            ->in($testDir)
            ->files()
            ->name('*Test.php');

        yield 'Every test has group' => [
            new EveryTestHasGroup($testFilePathNames),
        ];
        
        ...
    }
}

每个测试都有一个组

断言所有测试都有一个 #[Group('x')] 属性

final class FooTest extends TestCase

✔️

use PHPUnit\Framework\Attributes\Group;

 #[Group('unit')]
final class FooTest extends TestCase

在测试提供程序中配置

yield 'Every test has group' => [
    new EveryTestHasGroup($testFiles),
];

每个测试具有与被覆盖类相同的命名空间

断言所有测试都与它们测试的类具有相同的命名空间。
考虑src命名空间 Ns 和测试命名空间 Ns/Tests,那么对于测试 Ns/Tests/UnitTest 必须存在类 Ns/Unit

您可以使用 #[CoversClass] 属性将测试与测试类链接。
使用 #[CoversNothing] 属性跳过此检查。

不要忘记在phpunit配置文件中启用 requireCoverageMetadata="true"

namespace Ns;

final class Unit {} 

namespace Ns\Tests;

final class NonexistentUnitTest extends TestCase {}
namespace Ns\Tests\Sub;

final class UnitTest extends TestCase {}

✔️

namespace Ns\Tests;

final class UnitTest extends TestCase {}
namespace Ns\Tests\Sub;

use PHPUnit\Framework\Attributes\CoversClass;

 #[CoversClass('\Ns\Unit')]
final class UnitTest extends TestCase {}

在测试提供程序中配置

yield 'Every test has same namespace as tested class' => [
    new EveryTestHasSameNamespaceAsCoveredClass($testFiles),
];

每个测试都继承自testcase基类

考虑您有一个所有测试的共同基类,并且希望每个测试都扩展它。

abstract class TestCaseBase extends \PHPUnit\Framework\TestCase {}

final class FooTest extends \PHPUnit\Framework\TestCase

✔️

final class FooTest extends TestCaseBase

在测试提供程序中配置

yield 'Every test inherits from TestCase Base Class' => [
    new EveryTestInheritsFromTestCaseBaseClass(
        $testFiles,
        TestCaseBase::class
    ),
];

每个测试都是final

断言所有测试都是final,因此它们不能被扩展

class FooTest extends TestCase

✔️

final class FooTest extends TestCase

在测试提供程序中配置

yield 'Every test is final' => [
    new EveryTestIsFinal($testFiles),
];