Test Coverage Analyzer
| Analyzer ID | Category | Severity | Time To Fix |
|---|---|---|---|
test-coverage | 💻 Code Quality | Medium | 30 minutes |
What This Checks
Validates that critical application modules have corresponding test files. Recursively scans four key directories and checks each PHP class against your tests/ directory:
- Missing
tests/directory entirely - Models (
app/Models) without matching test files - Controllers (
app/Http/Controllers) without matching test files, including nested subdirectories likeApi/ - Services (
app/Services) without matching test files - Policies (
app/Policies) without matching test files
Automatically skipped: Abstract/Base-prefixed classes, traits, enums, and interfaces are excluded from the count. Within app/Services, DTOs (*Payload, files under a DTOs/ subdirectory) and exception classes (*Exception, files under an Exceptions/ subdirectory) are also excluded — these utility types have no independently testable business logic.
Flexible test matching: Test files don't need to exactly mirror the class name. PascalCase boundary matching handles all common Laravel naming conventions:
| Pattern | Test file | Matches class |
|---|---|---|
| Exact | UserTest.php | User.php |
| Suffix | ManagePostControllerTest.php | PostController.php |
| Prefix | UserModelTest.php | User.php |
| Reverse prefix | EmailVerificationTest.php | EmailVerificationPromptController.php |
The reverse-prefix rule accommodates Laravel Breeze's convention of naming tests after features rather than individual controller classes (e.g., a single EmailVerificationTest can cover EmailVerificationPromptController and EmailVerificationNotificationController).
Per-directory breakdown: Results include a per-layer summary so you can see exactly which areas need attention:
2 of 4 critical files have tests (50% coverage). Models: 1/2, Controllers: 1/1, Services: 0/1
Coverage Thresholds
| Coverage | Result | Issue Severity |
|---|---|---|
| >= 75% | Pass | - |
| 25–74% | Warning | Low |
| < 25% | Warning | Medium |
Why It Matters
- Unreliable Deployments: Untested code is more likely to contain bugs that reach production
- Regression Prevention: Without tests, code changes can break existing functionality silently
- Confidence in Deployments: Adequate test coverage enables faster, safer deployments
- Code Documentation: Tests serve as living documentation of expected behavior
How to Fix
Quick Fix (5 minutes)
Create your first test:
# Generate a test for a specific feature
php artisan make:test UserRegistrationTest
# Generate a unit test
php artisan make:test Models/UserTest --unitProper Fix (30 minutes)
1. Ensure critical modules have test coverage:
// tests/Feature/Http/Controllers/UserControllerTest.php
use Illuminate\Foundation\Testing\RefreshDatabase;
class UserControllerTest extends TestCase
{
use RefreshDatabase;
public function test_index_returns_users(): void
{
User::factory()->count(3)->create();
$response = $this->getJson('/api/users');
$response->assertOk()
->assertJsonCount(3, 'data');
}
}2. Add model tests:
// tests/Unit/Models/UserTest.php
use Illuminate\Database\Eloquent\Relations\HasMany;
class UserTest extends TestCase
{
public function test_user_has_orders_relationship(): void
{
$user = User::factory()->create();
$this->assertInstanceOf(HasMany::class, $user->orders());
}
}3. Run coverage report:
php artisan test --coverage --min=80References
Related Analyzers
- Test Quality - Checks test files for quality issues
- Test Data Management - Validates test data practices
- Missing Error Tracking - Detects missing error tracking