Skip to content

Testing & Code Quality

Running Tests

# Full test suite
bin/phpunit

# Single test file
bin/phpunit tests/Service/ChangeDetectionServiceTest.php

# Single test method
bin/phpunit --filter testDetectsNestedChanges

Test Structure

Tests mirror the src/ namespace structure:

tests/
├── Command/           # Console command tests
├── Controller/        # HTTP controller integration tests
└── Unit/              # Unit tests
    ├── DTO/
    ├── Entity/
    ├── Enum/
    ├── EventSubscriber/
    ├── MessageHandler/
    ├── Repository/
    ├── Security/
    └── Service/

Configuration

PHPUnit is configured with strict mode:

  • failOnDeprecation: true
  • failOnNotice: true
  • failOnWarning: true
  • Clock and DNS mocking enabled for the App namespace
  • Test environment uses in-memory message transports (no Doctrine queues)
  • Separate test database (suffix: _test)

Methodology

The project follows red/green testing: write a failing test first, then implement code to make it pass. Over 100 test files cover services, repositories, DTOs, entities, validators, message handlers, and event listeners.

Static Analysis (PHPStan)

vendor/bin/phpstan analyse

Configured at level 6 with extensions for Doctrine, Symfony, and PHPUnit.

Code Style (PHP-CS-Fixer)

# Fix code style
vendor/bin/php-cs-fixer fix

# Preview fixes without applying
vendor/bin/php-cs-fixer fix --dry-run --diff

Uses the @Symfony ruleset with 4-space indentation.

Mutation Testing (Infection)

# Run with coverage
composer infection:run

Pre-commit Hooks (GrumPHP)

GrumPHP runs automated checks before every commit to enforce code quality.

Naming Conventions

  • Classes: StudlyCaps (e.g., ProductSyncService)
  • Methods/properties: camelCase (e.g., syncBatch)
  • Database columns: snake_case (auto-converted by Doctrine's underscore naming strategy)
  • Entities: PHP attributes for mapping (not YAML/XML)