2026-04-21 17:56:04 +02:00
# Testing Guide for MineSeeker
MineSeeker-specific testing setup and workflows. For general PHPUnit/Symfony testing, see [Symfony Testing Docs ](https://symfony.com/doc/current/testing.html ).
2026-04-28 08:10:18 +02:00
## Example of the current tests
``` shell
$ bin/phpunit ( master->origin/master| ✚1…2⚑1)
PHPUnit 13.1.7 by Sebastian Bergmann and contributors.
Runtime: PHP 8.5.5
Configuration: /var/www/splendid/Mine/phpunit.dist.xml
................................................................. 65 / 71 ( 91%)
...... 71 / 71 ( 100%)
Time: 00:07.319, Memory: 86.50 MB
OK ( 71 tests, 227 assertions)
Faker seed used: 918823
```
2026-04-21 17:56:04 +02:00
## Quick Start
``` bash
# One-time setup
make test-db-setup
# Run tests
make test
```
---
## Test Database Configuration
MineSeeker uses a **separate test database ** (`mineseeker_test` ) with automatic transaction rollback for isolated tests.
### Stack
- **PHPUnit 13** - Testing framework
- **[Zenstruck Foundry ](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html )** - Factory library for test fixtures
- **[DAMA Doctrine Test Bundle ](https://github.com/dmaicher/doctrine-test-bundle )** - Transaction isolation (rollback after each test)
### Configuration
* * `phpunit.dist.xml` **:
``` xml
<env name= "DATABASE_URL" value= "postgresql://...mineseeker_test..." />
<env name= "DAMA_DISABLE_STATIC_CONNECTION" value= "0" />
```
* * `config/bundles.php` **:
``` php
Zenstruck\Foundry\ZenstruckFoundryBundle :: class => [ 'dev' => true , 'test' => true ],
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle :: class => [ 'test' => true ],
```
---
## Setup
### One-time Setup
``` bash
make test-db-setup
```
Creates `mineseeker_test` database and runs migrations.
### Reset Test Database
``` bash
make test-db-reset
```
Drops and recreates test database (useful after schema changes).
---
## Running Tests
``` bash
# All tests
make test
# Specific file
vendor/bin/phpunit tests/Controller/ProfileControllerTest.php
# Specific method
vendor/bin/phpunit --filter testCreateUser
# With test names
vendor/bin/phpunit --testdox
```
---
## MineSeeker Factories
See * * [FACTORIES.md ](./FACTORIES.md )** for complete factory API.
### Available Factories
| Factory | Entity | Location |
|---------|--------|----------|
| `UserFactory` | Registered users | `tests/Factory/UserFactory.php` |
| `GamerFactory` | Anonymous players | `tests/Factory/GamerFactory.php` |
| `PlayedGameFactory` | Game records | `tests/Factory/PlayedGameFactory.php` |
| `StepFactory` | Game moves | `tests/Factory/StepFactory.php` |
| `GridFactory` | 16× 16 game grids | `tests/Factory/GridFactory.php` |
| `GridRowFactory` | Grid rows | `tests/Factory/GridRowFactory.php` |
| `WebAuthnCredentialFactory` | Passkey credentials | `tests/Factory/WebAuthnCredentialFactory.php` |
| `ContactMessageFactory` | Contact messages | `tests/Factory/ContactMessageFactory.php` |
### Example
``` php
use App\Tests\Factory\PlayedGameFactory ;
use App\Tests\WebTestCase ;
class GameTest extends WebTestCase
{
public function testGameCreation () : void
{
$game = PlayedGameFactory :: new ()
-> withRegisteredPlayers ()
-> redWins ()
-> create ();
self :: assertEquals ( 26 , $game -> redPoints );
}
}
```
---
## Test Structure
All tests extend `App\Tests\WebTestCase` :
``` php
< ? php declare ( strict_types = 1 );
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Tests\Controller ;
use App\Tests\Factory\UserFactory ;
use App\Tests\WebTestCase ;
class MyControllerTest extends WebTestCase
{
public function testExample () : void
{
$user = UserFactory :: createOne ();
$client = static :: createClient ();
2026-04-28 08:10:18 +02:00
2026-04-21 17:56:04 +02:00
$client -> request ( 'GET' , '/profile' );
2026-04-28 08:10:18 +02:00
2026-04-21 17:56:04 +02:00
self :: assertResponseRedirects ( '/login' );
}
}
```
**Important ** : Always extend `App\Tests\WebTestCase` , not `Symfony\Bundle\FrameworkBundle\Test\WebTestCase` .
---
## Directory Structure
```
tests/
├── Controller/ # HTTP endpoint tests
├── Dto/ # Data Transfer Object tests
├── Entity/ # Entity logic tests
├── Service/ # Service layer tests
├── Integration/ # Integration tests
├── Factory/ # Foundry factories
├── WebTestCase.php # Base test class
└── bootstrap.php # PHPUnit bootstrap
```
---
## MineSeeker-Specific Patterns
### Testing Game Flow
``` php
public function testRedPlayerWinsGame () : void
{
$game = PlayedGameFactory :: new ()
-> withRegisteredPlayers ()
-> create ();
// Create steps to simulate gameplay
for ( $i = 0 ; $i < 26 ; $i ++ ) {
StepFactory :: new ()
-> forPlayer ( 'red' )
-> mine ()
-> create ([ 'playedGame' => $game ]);
}
self :: assertEquals ( 26 , $game -> redPoints );
}
```
### Testing Battle Sharing
``` php
public function testBattleSharePageReturnsValidGame () : void
{
$game = PlayedGameFactory :: new ()
-> withRegisteredPlayers ()
-> redWins ()
-> create ();
$client = static :: createClient ();
$client -> request ( 'GET' , '/battle/' . $game -> uuid );
self :: assertResponseIsSuccessful ();
self :: assertSelectorTextContains ( 'h1' , 'Battle Report' );
}
```
### Testing Authentication
``` php
public function testProfileRequiresAuthentication () : void
{
$client = static :: createClient ();
$client -> request ( 'GET' , '/profile' );
self :: assertResponseRedirects ( '/login' );
}
public function testAuthenticatedUserCanAccessProfile () : void
{
$user = UserFactory :: createOne ();
$client = static :: createClient ();
$client -> loginUser ( $user -> _real ());
$client -> request ( 'GET' , '/profile' );
self :: assertResponseIsSuccessful ();
}
```
---
## Troubleshooting
### Tests interfering with each other?
Ensure you extend `App\Tests\WebTestCase` , not the base Symfony class.
### Schema out of sync?
``` bash
make test-db-reset
```
### Memory limit errors?
``` bash
php -d memory_limit = 1024M vendor/bin/phpunit
```
Or increase in `phpunit.dist.xml` :
``` xml
<ini name= "memory_limit" value= "1024M" />
```
### Test database doesn't exist?
``` bash
make test-db-setup
```
---
## External Resources
- **[Symfony Testing ](https://symfony.com/doc/current/testing.html )** - Symfony testing guide
- **[Zenstruck Foundry ](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html )** - Factory documentation
- **[DAMA Doctrine Test Bundle ](https://github.com/dmaicher/doctrine-test-bundle )** - Transaction isolation
- **[PHPUnit ](https://docs.phpunit.de/ )** - PHPUnit documentation
---
## Modern PHPUnit Attributes
MineSeeker tests use modern PHP 8 attributes instead of method name prefixes:
``` php
use PHPUnit\Framework\Attributes\Test ;
use PHPUnit\Framework\Attributes\TestDox ;
#[TestDox('Security Controller')]
class SecurityControllerTest extends WebTestCase
{
#[Test]
#[TestDox('Login page loads successfully with form fields')]
public function loginPageLoadsSuccessfully () : void
{
// Test implementation
}
}
```
**Benefits: **
- ✅ More readable method names (no `test` prefix required)
- ✅ Self-documenting with `TestDox` descriptions
- ✅ Better IDE support and refactoring
- ✅ Cleaner `--testdox` output
**Run with documentation: **
``` bash
vendor/bin/phpunit --testdox
```
Output:
```
Security Controller
✔ Login page loads successfully with form fields
✔ Login page has links to register and forgot password
✔ Register page loads successfully with form
```