Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AlexanderDamont1/Stratus/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Stratus POS uses PHPUnit 11 as its test runner, configured via phpunit.xml in the project root. Laravel Breeze ships with a suite of feature tests covering the full authentication flow.
Running tests
The recommended way to run the test suite is:
This command:
- Clears the config cache with
php artisan config:clear to ensure no stale configuration is used during tests
- Runs
php artisan test, which wraps PHPUnit with Laravel-specific output formatting
You can also invoke PHPUnit directly:
Test structure
tests/
├── Feature/ # Integration tests — test full HTTP requests, DB interactions, etc.
└── Unit/ # Unit tests — test individual classes and methods in isolation
| Suite | Directory | When to use |
|---|
| Feature | tests/Feature/ | Test routes, controllers, middleware, and multi-layer interactions |
| Unit | tests/Unit/ | Test pure logic in models, services, or helpers in isolation |
Prefer feature tests for most Stratus functionality. They give you higher confidence by exercising the full stack, and Laravel’s testing helpers make HTTP testing straightforward.
Running specific tests
Run a single test class:
php artisan test --filter ProfileTest
Run a single test method:
php artisan test --filter "ProfileTest::test_profile_information_can_be_updated"
Run all tests in a directory:
php artisan test tests/Feature/Auth
Run with verbose output:
php artisan test --verbose
Writing tests
Feature test example
Feature tests extend Tests\TestCase and can make HTTP requests against the application. The following example mirrors the actual profile test in the codebase (tests/Feature/ProfileTest.php):
tests/Feature/ProfileTest.php
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ProfileTest extends TestCase
{
use RefreshDatabase;
public function test_profile_information_can_be_updated(): void
{
$user = User::factory()->create();
$response = $this
->actingAs($user)
->patch('/profile', [
'name' => 'Test User',
'email' => 'test@example.com',
]);
$response
->assertSessionHasNoErrors()
->assertRedirect('/profile');
$user->refresh();
$this->assertSame('Test User', $user->name);
$this->assertSame('test@example.com', $user->email);
$this->assertNull($user->email_verified_at);
}
}
Unit test example
<?php
namespace Tests\Unit;
use App\Models\User;
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase
{
public function test_password_is_hidden_from_serialization(): void
{
$user = new User(['password' => 'secret']);
$this->assertArrayNotHasKey('password', $user->toArray());
}
}
Using factories
The User model ships with UserFactory via the HasFactory trait. Use it to generate test users:
use App\Models\User;
// Basic user
$user = User::factory()->create();
// User with specific attributes
$user = User::factory()->create([
'email' => 'test@example.com',
]);
// Unverified user (email_verified_at is null)
$user = User::factory()->unverified()->create();
// User that is not persisted to the database
$user = User::factory()->make();
// Multiple users
$users = User::factory()->count(10)->create();
Tests that write to the database should use the RefreshDatabase trait. This wraps each test in a transaction that is rolled back on completion, keeping tests isolated.
Using Faker
Faker is available in factories and tests for generating realistic fake data.
use Faker\Factory as Faker;
$faker = Faker::create();
$email = $faker->unique()->safeEmail(); // e.g. john.doe@example.org
$name = $faker->name(); // e.g. Jane Smith
$price = $faker->randomFloat(2, 1, 999); // e.g. 42.50
In a factory, Faker is already available via $this->faker:
database/factories/UserFactory.php
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'),
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): static
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
Mocking with Mockery
Mockery is included for mocking dependencies in unit tests.
use Mockery;
$mock = Mockery::mock(PaymentGateway::class);
$mock->shouldReceive('charge')
->once()
->with(1000)
->andReturn(true);
// Bind the mock into the service container
$this->app->instance(PaymentGateway::class, $mock);
Laravel also has first-class support for mocking via $this->mock():
$this->mock(PaymentGateway::class, function (MockInterface $mock) {
$mock->shouldReceive('charge')->once()->andReturn(true);
});
For facades (e.g. Mail, Event, Queue), prefer Laravel’s built-in fake helpers over Mockery:Mail::fake();
Event::fake();
Queue::fake();
Code coverage
Generate an HTML coverage report (requires Xdebug or PCOV):
php artisan test --coverage
Output a coverage report to a directory:
php artisan test --coverage-html coverage/
Enforce a minimum coverage threshold:
php artisan test --coverage --min=80
Code coverage requires either the Xdebug or PCOV PHP extension. PCOV is significantly faster for coverage collection and is recommended for CI environments.