-
Identify what to test. Read the target class in src/. Determine: public method signatures, static vs instance, private properties, constructor initialisation, and any early-return guards (e.g. empty-string checks).
- Verify the class exists and is loadable before writing tests.
-
Create the test file at the appropriate path under tests/ (e.g., tests/SwiftTest.php or tests/PluginTest.php). Use this exact file header:
<?php
declare(strict_types=1);
namespace Detain\MyAdminSwift\Tests;
use Detain\MyAdminSwift\Plugin;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
For the global Swift class, replace the use line with use Swift;.
-
Write structural tests first (do not skip these):
testClassExists() — $this->assertTrue(class_exists(ClassName::class))
testCanBeInstantiated() — new ClassName(); $this->assertInstanceOf(...)
testClassNamespace() — use ReflectionClass::getNamespaceName()
testStaticPropertiesExist() — iterate expected property names via $ref->getStaticProperties()
testPublicMethodList() — collect $ref->getMethods(IS_PUBLIC) filtered to getDeclaringClass()->getName() === ClassName::class, sort, assert exact list
-
Write method-signature tests for every public method:
public function testFooMethodSignature(): void
{
$ref = new ReflectionClass(Swift::class);
$method = $ref->getMethod('foo');
$params = $method->getParameters();
$this->assertCount(2, $params);
$this->assertSame('container', $params[0]->getName());
$this->assertFalse($params[0]->isDefaultValueAvailable());
$this->assertSame('', $params[1]->getDefaultValue());
}
Verify static/public/instance as appropriate with isStatic(), isPublic().
-
Write property-access tests using reflection for private properties:
$swift = new Swift();
$ref = new ReflectionClass($swift);
$prop = $ref->getProperty('storage_url');
$prop->setAccessible(true);
$this->assertNull($prop->getValue($swift));
$prop->setValue($swift, 'https://storage.example.com/v1/AUTH_test');
$this->assertSame('https://storage.example.com/v1/AUTH_test', $swift->get_url());
-
Write behaviour tests using anonymous class stubs when a method calls methods on an injected subject:
$loader = new class {
public $requirements = [];
public function add_requirement(string $name, string $path): void
{
$this->requirements[$name] = $path;
}
};
$event = new GenericEvent($loader);
Plugin::getRequirements($event);
$this->assertArrayHasKey('class.Swift', $loader->requirements);
$this->assertSame(
'/../vendor/detain/myadmin-swift-backups/src/Swift.php',
$loader->requirements['class.Swift']
);
-
Add a @dataProvider for methods that need multiple input variants. Provider methods MUST be public static:
public function testSetV1AuthUrlWithVariousFormats(string $url): void { ... }
public static function urlProvider(): array
{
return [
'https url' => ['https://auth.example.com/auth/v1.0'],
'empty string' => [''],
];
}
-
Add @covers docblock to the class:
class PluginTest extends TestCase
For global classes: @covers \Swift.
-
Run tests and fix any failures:
./vendor/bin/phpunit tests/SwiftTest.php
Confirm zero failures and zero errors before finishing.
-
Class 'Swift' not found — tests/bootstrap.php manually requires src/Swift.php outside of Composer autoloading. If you create a new test file for Swift, ensure phpunit.xml.dist (or your run command) uses tests/bootstrap.php as the bootstrap. Run: ./vendor/bin/phpunit --bootstrap tests/bootstrap.php tests/SwiftTest.php.
-
Call to undefined function getcurlpage() — the stub in tests/bootstrap.php only loads when bootstrap runs. Confirm phpunit.xml.dist has bootstrap="tests/bootstrap.php". If running ad-hoc, pass --bootstrap tests/bootstrap.php.
-
Cannot access private property — call $prop->setAccessible(true) before getValue()/setValue(). PHPUnit 9.6 on PHP 8.1+ still requires this; it is not deprecated until PHP 8.2 and not removed.
-
ReflectionException: Method foo does not exist — you are testing a method name that differs from the actual source. Run grep -n 'public function' src/Swift.php to get the exact names.
-
Failed asserting that array has the key 'class.Swift' when testing getRequirements — verify your anonymous stub's add_requirement signature matches (string $name, string $path) exactly; a variadic signature will store args differently.
-
Data provider not found — provider method must be public static function (not instance method). PHPUnit 9 will throw InvalidArgumentException: Data provider ... is not static otherwise.