Installation:
composer require windwalker/test ^4.0
Add to composer.json under require-dev if only needed for testing:
"windwalker/test": "^4.0"
First Use Case:
Use the TestCase base class for your PHPUnit tests:
use Windwalker\Test\TestCase;
class ExampleTest extends TestCase
{
public function testBasicAssertion()
{
$this->assertTrue(true);
}
}
Where to Look First:
src/TestCase.php for base class methods.src/Traits/ for reusable test traits (e.g., HasDatabaseTransactions, HasHttpClient).Base Test Class:
Extend TestCase for shared setup/teardown:
class UserTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$this->user = User::factory()->create();
}
}
Database Transactions:
Use HasDatabaseTransactions trait to rollback after tests:
use Windwalker\Test\Traits\HasDatabaseTransactions;
class UserTest extends TestCase
{
use HasDatabaseTransactions;
// Tests automatically rollback DB changes
}
HTTP Testing:
Leverage HasHttpClient for API tests:
use Windwalker\Test\Traits\HasHttpClient;
class ApiTest extends TestCase
{
use HasHttpClient;
public function testGetUser()
{
$response = $this->get('/api/user');
$this->assertEquals(200, $response->status());
}
}
Mocking Services:
Use createMock() or getMockBuilder() from PHPUnit (inherited):
$mockService = $this->createMock(ServiceInterface::class);
$mockService->method('doWork')->willReturn(true);
Assertion Helpers:
Extend PHPUnit assertions with custom helpers (e.g., assertJsonStructure):
$this->assertJsonStructure([
'data' => [
'id',
'name',
],
], $response->json());
Laravel Integration:
Use windwalker/test alongside Laravel’s Illuminate/Foundation/Testing for hybrid testing:
use Illuminate\Foundation\Testing\RefreshDatabase;
use Windwalker\Test\TestCase;
class HybridTest extends TestCase
{
use RefreshDatabase; // Laravel's trait
}
Custom Assertions:
Add assertions to TestCase for project-specific logic:
protected function assertUserHasRole(User $user, string $role)
{
$this->assertTrue($user->roles()->where('name', $role)->exists());
}
Test Data Factories: Use Laravel’s factories or custom factories in tests:
$user = User::factory()->create(['email' => 'test@example.com']);
Trait Conflicts:
Avoid mixing HasDatabaseTransactions with Laravel’s RefreshDatabase unless intentional (they handle rollbacks differently).
Mocking Laravel Services:
Use partialMock() for Laravel services to preserve existing methods:
$mockAuth = $this->partialMock(Auth::class, ['check']);
Assertion Order:
PHPUnit stops on first failed assertion. Use try-catch for multi-step validations:
try {
$this->assertTrue($condition1);
$this->assertTrue($condition2);
} catch (AssertionFailedError $e) {
$this->fail("Multiple conditions failed: " . $e->getMessage());
}
Database Transactions:
Nested transactions may cause issues. Use beginTransaction()/rollBack() manually if needed:
DB::beginTransaction();
try {
// Test logic
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
$this->fail($e->getMessage());
}
TestCase Logging:
Enable debug mode in TestCase constructor:
public function __construct()
{
parent::__construct();
$this->debug = true; // Logs assertions and setup/teardown
}
Dumping Data:
Use dd() or dump() from Laravel’s Tests/TestCase (if extended):
$this->dump($user->toArray()); // Dumps and continues
Slow Tests:
Profile with --filter to identify bottlenecks:
phpunit --filter testSlowFeature
Custom Traits:
Extend TestCase with project-specific traits:
trait HasCustomAssertions
{
protected function assertResponseHasError($response, string $field)
{
$this->assertArrayHasKey('errors', $response->json());
$this->assertArrayHasKey($field, $response->json()['errors']);
}
}
Test Helpers:
Add static methods to TestCase for reusable logic:
protected static function createTestUser(): User
{
return User::factory()->create(['email' => 'test@example.com']);
}
Configuration:
Override getEnvironmentSetUp() for global test setup:
protected function getEnvironmentSetUp($app)
{
$app['config']->set('app.debug', true);
}
Parallel Testing:
Use --parallel flag with PHPUnit 9+ (ensure HasDatabaseTransactions is compatible):
phpunit --parallel
How can I help you explore Laravel packages today?