wyrihaximus/test-utilities
A set of PHP test utilities for package development: a PHPUnit TestCase with helpers like random namespaces and temp directories, plus ready-made configuration defaults for PHPStan and Rector (paths and docblock-to-attribute conversions).
Installation:
composer require wyrihaximus/test-utilities --dev
Add to your composer.json under require-dev if not using --dev.
First Use Case:
Extend WyriHaximus\TestUtilities\TestCase in your test class for built-in utilities:
use WyriHaximus\TestUtilities\TestCase;
class MyTest extends TestCase
{
public function testRandomNamespace()
{
$namespace = $this->randomNamespace();
$this->assertStringContainsString('\\', $namespace);
}
}
Key Features to Explore:
$this->randomDirectory() for temp file/dir tests.RectorConfig for docblock-to-attribute conversion.TestCase for all tests needing utilities.class FileUploadTest extends TestCase
{
public function testFileUpload()
{
$tempDir = $this->randomDirectory();
$tempFile = $tempDir . '/test.txt';
file_put_contents($tempFile, 'test');
$this->assertFileExists($tempFile);
}
}
RectorConfig for project-wide refactoring.rector.php):
<?php
declare(strict_types=1);
use WyriHaximus\TestUtilities\RectorConfig;
return RectorConfig::configure(__DIR__ . '/../src');
etc/src/tests paths by default.phpstan.neon):
includes:
- vendor/wyrihaximus/test-utilities/extension.neon
$this->randomNamespace(); // e.g., `\Test\Random\12345`
$this->randomDirectory(); // e.g., `/tmp/php-test-12345`
$this->randomString(10); // e.g., `aB3x9KpL2`
$this->randomEmail(); // e.g., `test+123@example.com`
randomDirectory() with Storage facades (if using Laravel).public function testStorageUpload()
{
Storage::put($this->randomFile(), 'test');
$this->assertTrue(Storage::exists($this->randomFile()));
}
randomString() for unique command inputs.public function testCustomCommand()
{
$input = $this->randomString();
$this->artisan('command:name', ['input' => $input])
->assertExitCode(0);
}
public function testModelCreation()
{
$user = User::factory()->create([
'email' => $this->randomEmail(),
]);
$this->assertDatabaseHas('users', ['email' => $user->email]);
}
Http tests for unique routes/data.public function testApiEndpoint()
{
$route = 'api/v1/users/' . $this->randomString();
$this->get($route)->assertStatus(200);
}
Temp Directory Cleanup:
randomDirectory() creates dirs in /tmp by default. Ensure your CI/CD cleans them up.$this->assertDirectoryIsEmpty() or manually delete after tests.Rector Conflicts:
^2.2.1) may cause dependency conflicts with other packages.^2.3.0 (as seen in v12.0.0) and resolve conflicts via composer why-not.PHPStan False Positives:
extension.neon or report issues to the package.Namespace Collisions:
Test\\MyProject\\).Laravel Storage Paths:
randomDirectory() paths may not resolve correctly in Laravel’s storage context.storage_path($this->randomDirectory()) for Laravel-specific tests.Slow Tests:
ergebnis/phpunit-slow-test-detector (included via dependencies) to identify bottlenecks../vendor/bin/phpunit --testdox-html slow-tests.html
Rector Dry Runs:
./vendor/bin/rector process src --dry-run
PHPStan Debugging:
./vendor/bin/phpstan analyse --level=max --error-format=github src
Custom Test Case Methods:
TestCase and override methods:
class CustomTestCase extends TestCase
{
protected function randomLaravelModel(): Model
{
return Model::factory()->create();
}
}
Rector Rules:
RectorConfig:
return RectorConfig::configure(__DIR__)
->withRules([
new YourCustomRule(),
]);
PHPStan Extensions:
extends: vendor/wyrihaximus/test-utilities/extension.neon
includes:
- your-custom-extension.neon
Test Utilities:
TestCase via traits or service providers:
use function WyriHaximus\TestUtilities\randomString;
$this->assertStringMatchesFormat('/^[a-z0-9]{10}$/', randomString(10));
Service Provider Booting:
refreshDatabase() or refreshTestingDatabase() in TestCase:
protected function setUp(): void
{
parent::setUp();
$this->refreshDatabase();
}
Artisan Commands:
$this->mock(Artisan::class)->shouldReceive('call')->once();
Event Testing:
randomString() for event payloads:
Event::fake();
$this->dispatch(new YourEvent($this->randomString()));
Event::assertDispatched(YourEvent::class);
Queue Testing:
randomString() for unique jobs:
$job = new YourJob($this->randomString());
$this->assertQueued($job);
How can I help you explore Laravel packages today?