Before running tests, ensure you have:
- PHP 8.1 or higher installed
- MySQL server running
- Composer dependencies installed
Create a separate test database to avoid affecting your development data:
CREATE DATABASE leave_management_test;php artisan testOr using PHPUnit directly:
vendor\bin\phpunitFeature Tests Only:
php artisan test --testsuite=FeatureUnit Tests Only:
php artisan test --testsuite=Unitphp artisan test tests/Feature/AuthenticationTest.phpphp artisan test --filter test_user_can_register_with_valid_dataphp artisan test --coveragetests/
├── Feature/
│ ├── AuthenticationTest.php # Authentication endpoints (13 tests)
│ ├── LeaveRequestTest.php # Leave request CRUD & approval (26 tests)
│ └── LeaveBalanceTest.php # Leave balance calculations (13 tests)
├── Unit/
│ ├── LeaveRequestModelTest.php # LeaveRequest model methods (9 tests)
│ └── UserModelTest.php # User model methods (11 tests)
└── TestCase.php
- Total Tests: 72
- Feature Tests: 52
- Unit Tests: 20
- User registration (valid/invalid scenarios)
- Login (success/failure cases)
- Logout functionality
- User profile retrieval
- Email uniqueness
- Password validation
- Submit leave (full_day, half_day, multi_day)
- Auto-approval for admin users
- Validation errors (reason, dates, periods)
- List requests (role-based filtering)
- View specific request (authorization)
- Approve/reject workflow
- Role-based approval hierarchy
- Error handling for processed requests
- Own balance calculation
- View other users' balance (role-based)
- Balance with approved/pending/rejected leaves
- Half-day leave calculations
- Mixed leave type calculations
- Authorization checks
- Relationship methods
- Status helper methods (isPending, isApproved, isRejected)
- Role helper methods (isAdmin, isHR, isGeneral)
- Day calculation methods
- Date casting
- Data validation
PASS Tests\Feature\AuthenticationTest
✓ user can register with valid data
✓ user can login with valid credentials
...
Tests: 72 passed
Time: 12.34s
FAILED Tests\Feature\LeaveRequestTest > test_hr_can_approve_general_user_leave_request
Expected status code 200 but received 403.
Failed asserting that 403 is identical to 200.
Tests use a separate database configured in phpunit.xml:
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_DATABASE" value="leave_management_test"/>The RefreshDatabase trait is used in all test classes, which:
- Migrates the database before each test
- Rolls back changes after each test
- Ensures test isolation
Solution: Create the test database:
CREATE DATABASE leave_management_test;Solution: Tests are configured for MySQL. Ensure MySQL is running and accessible.
Solution: Check your .env file database credentials match your MySQL configuration.
Solution: Clear config cache:
php artisan config:clear
php artisan cache:clear<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class YourFeatureTest extends TestCase
{
use RefreshDatabase;
public function test_example(): void
{
$response = $this->postJson('/api/your-endpoint', [
'field' => 'value'
]);
$response->assertStatus(200)
->assertJson([
'success' => true
]);
}
}<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class YourUnitTest extends TestCase
{
use RefreshDatabase;
public function test_example(): void
{
// Arrange
$model = Model::factory()->create();
// Act
$result = $model->someMethod();
// Assert
$this->assertTrue($result);
}
}Factories are available for generating test data:
// Create a user
$user = User::factory()->create();
// Create user with specific role
$admin = User::factory()->create(['role' => 'admin']);
// Create leave request
$leave = LeaveRequest::factory()->create();
// Create approved leave
$approvedLeave = LeaveRequest::factory()->approved()->create();
// Create half-day leave
$halfDayLeave = LeaveRequest::factory()->halfDay()->create();For CI/CD pipelines, use:
php artisan test --parallel --coverage --min=80This runs tests in parallel and ensures minimum 80% code coverage.
- Test Isolation: Each test should be independent
- Descriptive Names: Use clear test method names
- Arrange-Act-Assert: Follow AAA pattern
- Factory Usage: Use factories for test data
- Assertions: Use specific assertions (assertJson, assertStatus)
- Clean Up: RefreshDatabase trait handles cleanup automatically
- Check Laravel Testing Docs: https://laravel.com/docs/testing
- Review existing tests for patterns
- Ensure database is properly configured
Happy Testing! 🚀