Testing
Unit Testing
Unit tests verify the smallest parts of your application (methods, functions, classes) in isolation. Use Pest for all unit tests. Place unit tests in the tests/Unit directory.
// Example: User model unit test
it('gets the full name', function () {
$user = new User(['first_name' => 'John', 'last_name' => 'Doe']);
expect($user->full_name)->toBe('John Doe');
});
- Use descriptive test names.
- Mock dependencies to isolate the unit under test.
- Test edge cases and invalid input.
Feature Testing
Feature tests verify the behavior of your application as a whole, including HTTP requests, database interactions, and middleware. Place feature tests in the tests/Feature directory.
it('registers a user', function () {
$response = $this->post('/register', [
'name' => 'Jane Doe',
'email' => 'jane@example.com',
'password' => 'password',
'password_confirmation' => 'password',
]);
$response->assertRedirect('/home');
expect(User::where('email', 'jane@example.com'))->toBeTruthy();
});
- Use Pest's HTTP helpers (
get,post,put,delete). - Assert responses, redirects, and database changes.
- Test authentication, authorization, and validation.
Integration Testing
Integration tests verify that multiple parts of your application work together (e.g., controllers, models, services). Use integration tests for complex workflows.
it('allows a user to create a post', function () {
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->post('/posts', [
'title' => 'Test Post',
'body' => 'This is a test.',
]);
$response->assertStatus(201);
expect(Post::where('title', 'Test Post'))->toBeTruthy();
});
Mocking
Use mocking to isolate tests from external dependencies (e.g., services, APIs). Use Pest's mocking capabilities or Laravel's built-in mocking tools.
it('gets the name using a mock', function () {
$user = Mockery::mock(User::class);
$user->shouldReceive('getName')->andReturn('John Doe');
expect($user->getName())->toBe('John Doe');
});
- Mock services, repositories, and events.
- Use dependency injection for easier mocking.
Best Practices
- Write tests for all new features and bug fixes.
- Use factories and seeders for test data.
- Run tests automatically in CI/CD pipelines.
- Use descriptive test names and group related tests in files.
- Aim for high code coverage, but prioritize meaningful tests over coverage percentage.
Example: Pest Test File Structure
// tests/Feature/InvoiceTest.php
it('creates an invoice', function () {
// ...
});
it('calculates the invoice total correctly', function () {
// ...
});