-
-
Notifications
You must be signed in to change notification settings - Fork 1
Testing
| Команда | Каталог | Тестов | Описание |
|---|---|---|---|
composer test:unit |
tests/Unit/ |
326 | Поведение API, autowiring, configuration, freeze |
composer test:integration |
tests/Integration/ |
5 | Графы зависимостей, PSR-11 |
composer test:security |
tests/Security/ |
17 | Безопасность resolve, id, autowiring, freeze |
composer test:load |
tests/Load/ |
15 | Массовые регистрации и resolve (1000–3000 ops) |
composer test:performance |
tests/Performance/ |
12 | Латентность hot path (до 10 000 итераций) |
composer test:coverage |
— | — | Покрытие строк ≥95% |
composer test:mutation |
— | — | Infection MSI (цель ≥95%) |
Всего: 375 PHPUnit-тестов (без coverage/mutation).
Фактические метрики (локальный прогон): покрытие строк ~96%; MSI Infection ≥95% по ядру (src/, без Configuration/ — отдельный набор mutation-тестов для конфигурации в backlog).
| Набор | Wiki |
|---|---|
| Security (17) | Тесты безопасности — кэш, autowire, freeze, id |
| Load (15) + Performance (12) | Нагрузка и производительность — методология, все 27 сценариев, пороги, бенчмарки |
composer test:security
composer test:load
composer test:performance
composer ci # полный пайплайн
composer benchmark-report # фактические времена бенчмарков (markdown)Создавайте новый Container в каждом тесте — экземпляры не разделяют состояние:
final class OrderServiceTest extends TestCase
{
public function testCreatesOrder(): void
{
$container = new Container();
$container->set('clock', new FixedClock('2026-01-01'));
$container->set(
'orders',
static fn (ContainerInterface $c): OrderService => new OrderService($c->get('clock')),
);
$service = $container->get('orders');
// assertions...
}
}$container = new Container();
$container->enableAutowiring();
$container->set(ClockInterface::class, new FixedClock('2026-01-01'));
$service = $container->get(OrderService::class);Property и method injection в тестах:
$container = new Container();
$container->enableAutowiring();
$container->enablePropertyAutowiring();
$container->enableMethodAutowiring();
$container->set(LoggerInterface::class, new NullLogger());
$service = $container->get(LegacyServiceWithSetters::class);Явный set() переопределяет autowiring для того же типа.
Зарегистрируйте тестовый double до первого get():
$container->set('mailer', $this->createMock(MailerInterface::class));После get() замена через set() сбросит кэш — при следующем get() будет новый singleton.
Если тесты используют глобальный реестр, сбрасывайте его:
protected function tearDown(): void
{
ContainerRegistry::reset();
parent::tearDown();
}
public function testWithRegistry(): void
{
$container = new Container();
$container->set('clock', new FixedClock());
ContainerRegistry::set($container);
// код, вызывающий ContainerRegistry::get()
}Предпочтительнее передавать Container явно — без глобального состояния.
Вынесите регистрацию сервисов в функцию или класс:
function createApplicationContainer(): Container
{
$container = new Container();
$container->enableAutowiring();
$container->scan(__DIR__ . '/../src/Services', 'App\\Services\\');
// test doubles...
return $container;
}Кратко — в таблице выше. Подробно:
- Тесты безопасности — 17 сценариев, шаги, риски
-
Нагрузка и производительность — 15 load + 12 performance, пороги CI,
benchmark-report
composer test:coverage # порог ≥95% строк
composer test:mutation # Infection (цель MSI ≥95%)Требуется PCOV или Xdebug (XDEBUG_MODE=coverage).
CloudCastle DI · Репозиторий · Packagist · Releases · Discussions · Issues
Исходники Wiki — wiki/ в репозитории (синхронизация через Actions).
- Архитектура
- Быстрый старт
- Сравнение с PHP-DI, Symfony, Pimple — пошагово
- Примеры bootstrap
- Autowiring
- Конфигурация из файлов
- Сканирование классов
- Глобальный реестр
- Теги и декораторы
- call(), bind(), afterResolving
- Прототипы, alias и lazy
- Справочник API
- Фабрики и singleton
- Тестирование
- Тесты безопасности
- Нагрузка и производительность
- Анти-паттерны