adroit11/laravel-tests
Reusable Laravel testing package with publishable test stubs, custom assertions, and helper utilities. Drop into Laravel 10/11 (PHP 8.1+) and run with PHPUnit or Pest to speed up common feature and integration testing setups.
Installation
composer require adroit11/laravel-tests
Publish the package configuration (if needed):
php artisan vendor:publish --provider="Adroit11\LaravelTests\LaravelTestsServiceProvider"
First Use Case: Reusable Test Boilerplate
TestCase) and traits for common test scenarios (e.g., authentication, API testing, database transactions).tests/TestCase.php:
use Adroit11\LaravelTests\TestCase as BaseTestCase;
class TestCase extends BaseTestCase { ... }
use Adroit11\LaravelTests\Traits\WithDatabaseTransactions;
use Adroit11\LaravelTests\Traits\WithAuthentication;
class UserTest extends TestCase
{
use WithDatabaseTransactions, WithAuthentication;
public function test_user_creation()
{
$user = User::factory()->create();
$this->assertDatabaseHas('users', ['id' => $user->id]);
}
}
Key Files to Review
config/laravel-tests.php (customize default behaviors).tests/Feature/ or tests/Unit/ (organize tests using the provided structure).Traits for Common Logic
Use traits to avoid repetition in tests (e.g., WithDatabaseTransactions, WithAuthentication).
Example:
use Adroit11\LaravelTests\Traits\WithFactories;
class ModelTest extends TestCase
{
use WithFactories;
public function test_factory_creation()
{
$post = Post::factory()->create();
$this->assertInstanceOf(Post::class, $post);
}
}
Data Providers for Parameterized Tests Leverage the package’s support for data providers (if included) to test multiple inputs:
use Adroit11\LaravelTests\Traits\WithDataProviders;
class UserTest extends TestCase
{
use WithDataProviders;
public function test_user_roles()
{
$this->dataProvider('roles')
->assertDatabaseHas('users', ['role' => $this->role]);
}
protected function roles()
{
return [
['role' => 'admin'],
['role' => 'editor'],
];
}
}
Mocking HTTP Requests
Use the WithHttpTesting trait to mock API responses:
use Adroit11\LaravelTests\Traits\WithHttpTesting;
class ApiTest extends TestCase
{
use WithHttpTesting;
public function test_api_response()
{
$this->mockApiResponse('GET', '/users', ['users' => []]);
$response = $this->getJson('/api/users');
$response->assertJson(['users' => []]);
}
}
Authentication Helpers
Simplify auth testing with actingAs() or actingAsUser():
use Adroit11\LaravelTests\Traits\WithAuthentication;
class AuthTest extends TestCase
{
use WithAuthentication;
public function test_protected_route()
{
$user = User::factory()->create();
$this->actingAs($user);
$this->get('/protected')->assertOk();
}
}
Transaction-Based Tests Ensure tests run in isolation:
use Adroit11\LaravelTests\Traits\WithDatabaseTransactions;
class MigrationTest extends TestCase
{
use WithDatabaseTransactions;
public function test_migration_rollback()
{
// Test logic here
$this->assertDatabaseMissing('failed_table', ['id' => 1]);
}
}
Seeding for Tests
Use WithDatabaseSeeding to load fixtures:
use Adroit11\LaravelTests\Traits\WithDatabaseSeeding;
class SeederTest extends TestCase
{
use WithDatabaseSeeding;
protected function getSeeds()
{
return [UserSeeder::class];
}
public function test_seeded_data()
{
$this->assertDatabaseHas('users', ['email' => 'test@example.com']);
}
}
Extend the base TestCase to add project-specific helpers:
class TestCase extends \Adroit11\LaravelTests\TestCase
{
protected function createTestUser()
{
return User::factory()->create(['email' => 'test@example.com']);
}
protected function assertResponseValidation($response, $errors)
{
$response->assertJsonValidationErrors($errors);
}
}
Trait Conflicts
WithFaker).use Adroit11\LaravelTests\Traits\{WithDatabaseTransactions as Transactions};
Database Transactions & Seeding
WithDatabaseTransactions and WithDatabaseSeeding, ensure the package doesn’t double-seed data.getSeeds() carefully or disable seeding in transactions:
public function setUp(): void
{
parent::setUp();
$this->withoutSeeding(); // Disable seeding if needed
}
Mocking Quirks
Http testing.withoutMiddleware() or withoutEvents() if tests fail:
$this->withoutMiddleware()->get('/test');
Configuration Overrides
config/laravel-tests.php:
'assertions' => [
'timeout' => 5.0, // Default: 2.0
],
Enable Debug Mode
Add this to TestCase to log test failures:
protected function tearDown(): void
{
if ($this->hasFailures()) {
\Log::debug('Test failed:', ['trace' => $this->getTrace()]);
}
parent::tearDown();
}
Isolate Tests
Use refreshDatabase() or artisan('migrate:fresh') in setUp() for critical tests:
public function setUp(): void
{
$this->artisan('migrate:fresh');
parent::setUp();
}
Check for Deprecated Methods The package may use Laravel-specific methods that change across versions. Fix: Check the release notes for breaking changes.
Add Custom Traits
Extend the package by creating your own traits in app/Traits/TestTraits:
namespace App\Traits;
use Adroit11\LaravelTests\TestCase;
trait WithCustomAssertions
{
protected function assertSoftDeleted($model)
{
$this->assertTrue($model->trashed());
}
}
Override Base Test Case
Replace the entire TestCase if the package’s base class is too restrictive:
// tests/TestCase.php
use Orchestra\Testbench\TestCase as BaseTestCase;
class TestCase extends BaseTestCase { ... }
Integrate with Pest
If using Pest, alias the package’s traits in pest.php:
uses(Adroit11\LaravelTests\Traits\WithDatabaseTransactions::class)->in('tests');
Skip Transactions for Non-DB Tests
Use withoutTransactions() for unit tests:
public function test_non_db_logic()
{
$this->withoutTransactions();
// Test logic here
}
Parallelize Tests
Combine with laravel-shift/parallel-tests to run tests concurrently:
vendor/bin/parallel-tests
How can I help you explore Laravel packages today?