laravel-tester
Generates modern maintainable Laravel applications unit and feature (integration) tests with a focus on performance by default and for best testing style practices.
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
Laravel Tester
Instructions
Models Testing Policy
- DO NOT create unit tests for Laravel Eloquent models.
- Rationale:
- Laravel's Eloquent ORM is extensively tested by the Laravel team
- Testing basic CRUD operations, relationships, and standard functionality provides no value
- Models are excluded from code coverage metrics (see phpunit.xml)
- What NOT to test:
- Basic relationships (hasOne, hasMany, belongsTo, etc.)
- Simple CRUD operations (create, update, delete, find)
- Standard Eloquent functionality
- Factory creation without custom logic
- Basic fillable/guarded attributes
- Standard casting functionality
- Exceptions — What TO test:
- Custom business logic methods
- Complex accessors/mutators with business rules
- Custom scopes with specific logic
- Observer behavior and side effects
- Mass assignment protection (if critical)
- Where to test model functionality instead:
- Feature tests via HTTP endpoints and workflows
- Integration tests for model interactions
- Observer tests for event handlers
- Action/Service tests for business logic
Framework
- Pest PHP - Modern testing framework with BDD-style syntax
- Mutation Testing with Infection for test quality assurance
- Architectural Testing to enforce code structure rules
Test Structure
tests/
├── Feature/ # Integration tests
│ ├── Auth/
│ ├── MentorPrograms/
│ └── Pages/
├── Unit/ # Unit tests
│ ├── Actions/
│ ├── Models/
│ ├── Observers/
│ └── Support/
├── Pest.php # Pest configuration
└── TestCase.php # Base test case
Running Tests
All tests must be run in a Docker container. Feature tests do not need to mutate.
With Docker
# Run all tests
docker compose exec app ./vendor/bin/pest
# Run with coverage
docker compose exec app ./vendor/bin/pest --coverage
# Run mutation testing
docker compose exec app ./vendor/bin/pest --mutate --covered-only --parallel --min=100
# Run specific test file
docker compose exec app ./vendor/bin/pest tests/Unit/ExampleTest.php
Local Environment
# Ensure test database is configured in .env.testing
./vendor/bin/pest
./vendor/bin/pest --coverage
./vendor/bin/pest --mutate --covered-only --parallel --min=100
Test Configuration
- Database: Uses RefreshDatabase trait for clean test state
- Environment: Configured in phpunit.xml with testing-specific settings
-
Coverage: Reports generated in
coverage/directory - Memory Limit: 512M for test execution
Writing Tests
Basic Test Structure
<?php
declare(strict_types=1);
// For mutation testing (optional)
mutates(YourClass::class);
describe('Feature Description', function (): void {
beforeEach(function (): void {
// Setup code
$this->user = User::factory()->create();
});
it('describes what it tests', function (): void {
$result = someFunction();
expect($result)->toBe('expected_value');
});
});
Testing Actions (Laravel Actions Pattern)
it('handles the action correctly', function (): void {
$action = new YourAction();
$result = $action->handle($request, $parameters);
expect($result)
->toBeInstanceOf(RedirectResponse::class)
->and($result->getTargetUrl())
->toBe(route('expected.route'));
});
Architectural Testing
The project enforces architectural rules via tests/Unit/ArchTest.php:
- No debugging functions in production code
- Models must extend Eloquent Model
- Page actions must have 'Page' suffix
- Enums must be proper enum classes
Common Commands
# Code quality checks
./vendor/bin/phpstan analyse
./vendor/bin/pint --test
./vendor/bin/rector process --dry-run
# Fix code issues
./vendor/bin/pint
./vendor/bin/rector process
# Generate IDE helpers
php artisan ide-helper:generate
php artisan ide-helper:models
# Clear caches
php artisan config:clear
php artisan cache:clear
php artisan view:clear
Code Quality Tools
- Laravel Pint - Code formatting based on Laravel preset with strict rules
- PHPStan (Level 5) - Static analysis with Larastan for Laravel-specific checks
- Rector - Automated code modernization for PHP 8.4 and Laravel 12.0
- Cognitive Complexity - Limits complexity (class: 85, function: 8)
Development Tools
- Telescope: Laravel debugging assistant (enabled in testing)
- Log Viewer: Web-based log viewing interface
- IDE Helpers: Comprehensive IDE support with auto-generated helpers
- Xdebug: Available in Docker development environment
Pest
Testing
- If you need to verify a feature is working, write or update a Unit / Feature test.
Pest Tests
- All tests must be written using Pest. Use
php artisan make:test --pest <name>. - You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files - these are core to the application.
- Tests should test all of the happy paths, failure paths, and weird paths.
- Tests live in the
tests/Featureandtests/Unitdirectories. - Pest tests look and behave like this: it('is true', function () { expect(true)->toBeTrue(); });
Running Tests
- Run the minimal number of tests using an appropriate filter before finalizing code edits.
- To run all tests:
php artisan test. - To run all tests in a file:
php artisan test tests/Feature/ExampleTest.php. - To filter on a particular test name:
php artisan test --filter=testName(recommended after making a change to a related file). - When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing.
Pest Assertions
-
When asserting status codes on a response, use the specific method like
assertForbiddenandassertNotFoundinstead of usingassertStatus(403)or similar, e.g.: it('returns all', function () { $response = $this->postJson('/api/docs', []);$response->assertSuccessful(); });
Mocking
- Mocking can be very helpful when appropriate.
- When mocking, you can use the
Pest\Laravel\mockPest function, but always import it viause function Pest\Laravel\mock;before using it. Alternatively, you can use$this->mock()if existing tests do. - You can also create partial mocks using the same import or self method.
Datasets
- Use datasets in Pest to simplify tests which have a lot of duplicated data. This is often the case when testing validation rules, so consider going with this solution when writing tests for validation rules.
Pest 4
- Pest v4 is a huge upgrade to Pest and offers: browser testing, smoke testing, visual regression testing, test sharding, and faster type coverage.
- Browser testing is incredibly powerful and useful for this project.
- Browser tests should live in
tests/Browser/. - Use the
search-docstool for detailed guidance on utilizing these features.
Browser Testing
- You can use Laravel features like
Event::fake(),assertAuthenticated(), and model factories within Pest v4 browser tests, as well asRefreshDatabase(when needed) to ensure a clean state for each test. - Interact with the page (click, type, scroll, select, submit, drag-and-drop, touch gestures, etc.) when appropriate to complete the test.
- If requested, test on multiple browsers (Chrome, Firefox, Safari).
- If requested, test on different devices and viewports (like iPhone 14 Pro, tablets, or custom breakpoints).
- Switch color schemes (light/dark mode) when appropriate.
- Take screenshots or pause tests for debugging when appropriate.
Example Tests
$this->actingAs(User::factory()->create());
$page = visit('/sign-in'); // Visit on a real browser...
$page->assertSee('Sign In')
->assertNoJavascriptErrors() // or ->assertNoConsoleLogs()
->click('Forgot Password?')
->fill('email', 'nuno@laravel.com')
->click('Send Reset Link')
->assertSee('We have emailed your password reset link!')
Notification::assertSent(ResetPassword::class);
});
$pages->assertNoJavascriptErrors()->assertNoConsoleLogs();
Test Enforcement
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use
php artisan testwith a specific filename or filter.
Laravel Pint Code Formatter
- You must run
vendor/bin/pint --dirtybefore finalizing changes to ensure your code matches the project's expected style. - Do not run
vendor/bin/pint --test, simply runvendor/bin/pintto fix any formatting issues.
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-01-26
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!