Skip to content

Repository files navigation

Cdn77 TestUtils

GitHub ActionsCode CoverageDownloadsPackagistInfection MSI

Contents

Installation

  • Require this project as composer dev dependency:
composer require --dev cdn77/test-utils

Features

Stub

Factory to create object through Reflection in order to bypass the constructor.


<?phpclass MyEntity {
/** @var string */private$property1;
/** @var string */private$property2;
publicfunction__construct(string$property1, string$property2) {
$this->property1 = $property1;
$this->property2 = $property2;
}
publicfunctionsalute() : string {
returnsprintf('Hello %s!', $this->property2);
}
}

When testing method salute(), you only need the tested class to have property2 set, you don't want to worry about property1. Therefore in your test you can initialize MyEntity using Stub::create() like this:

$myEntity = Stub::create(MyEntity::class, ['property2' => 'world']);
self::assertSame('Hello world!', $myEntity->salute());

It comes handy when class constructor has more arguments and most of them are not required for your test.

It is possible to extend stubs:

$myEntity = Stub::create(MyEntity::class, ['property2' => 'world']);
$myEntity = Stub::extends($myEntity, ['property1' => 'value']);
// property 1 and 2 are set nowself::assertSame('Hello world!', $myEntity->salute());

Test Checks

Test Checks are used to assert that tests comply with your suite's standards (are final, extend correct TestCaseBase etc.)

To run them, e.g. create a test case like in the following example:

<?phpuseCdn77\TestUtils\TestCheck\TestCheck;
usePHPUnit\Framework\TestCase;
usePHPUnit\Framework\Attributes\CoversNothing;
usePHPUnit\Framework\Attributes\Group;
#[CoversNothing]
#[Group('integration')]
finalclass SuiteComplianceTest extends TestCaseBase
{
/** @dataProvider providerChecks */publicfunctiontestChecks(TestCheck$check) : void
{
$check->run($this);
}
/** @return Generator<string, array{callable(self): TestCheck}> */publicstaticfunctionproviderChecks() : Generator
{
$testDir = ROOT_PROJECT_DIR . '/tests';
$testFilePathNames = \Symfony\Component\Finder\Finder::create()
->in($testDir)
->files()
->name('*Test.php');
yield'Every test has group' => [
newEveryTestHasGroup($testFilePathNames),
];
...
}
}

Every test has group

Asserts that all tests have a #[Group('x')] attribute

finalclass FooTest extends TestCase

✔️

usePHPUnit\Framework\Attributes\Group;
#[Group('unit')]
finalclass FooTest extends TestCase

Configured in test provider as

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

Every test has same namespace as covered class

Asserts that all test share same namespace with class they're testing.
Consider src namespace Ns and test namespace Ns/Tests then for test Ns/Tests/UnitTest must exist class Ns/Unit.

You can use #[CoversClass] attribute to link test with tested class.
Use #[CoversNothing] attribute to skip this check.

Don't forget to enable requireCoverageMetadata="true" in phpunit config file.

namespaceNs;
finalclass Unit {} 

namespaceNs\Tests;
finalclass NonexistentUnitTest extends TestCase {}
namespaceNs\Tests\Sub;
finalclass UnitTest extends TestCase {}

✔️

namespaceNs\Tests;
finalclass UnitTest extends TestCase {}
namespaceNs\Tests\Sub;
usePHPUnit\Framework\Attributes\CoversClass;
#[CoversClass('\Ns\Unit')]
finalclass UnitTest extends TestCase {}

Configured in test provider as

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

Every test inherits from testcase base class

Consider you have a base for all tests and want each of them extend it.

abstractclass TestCaseBase extends \PHPUnit\Framework\TestCase {}

finalclass FooTest extends \PHPUnit\Framework\TestCase

✔️

finalclass FooTest extends TestCaseBase

Configured in test provider as

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

Every test is final

Asserts all tests are final so they cannot be extended

class FooTest extends TestCase

✔️

finalclass FooTest extends TestCase

Configured in test provider as

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

About

Test Utils for PHP to facilitate writing tests

Topics

Resources

Stars

2 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages