Почему Testo?
Testo — расширяемый фреймворк тестирования для PHP. Создан для сценариев, требующих кастомизации процесса тестирования: SDK, инструменты фреймворков, сложные интеграции.
В отличие от других фреймворков тестирования, Testo предоставляет всё сразу: привычный и удобный PHP-синтаксис, беспрецедентную расширяемость и кастомизируемость, а также простую, но мощную архитектуру на основе минимального ядра и системы middleware.
Вы можете слепить из него любую инфраструктуру тестирования, которая вам нужна.
История создания
Testo родился из потребности в расширяемом фреймворке тестирования, который мог бы адаптироваться к сложным требованиям современных PHP-проектов. Подробнее о мотивации создания Testo читайте здесь, но вкратце:
- Раньше, чтобы обернуть запуск теста своей логикой, мы опирались на переопределение метода
TestCase::runTest(), который хоть и был помечен аннотацией@internal, но многие годы существовал и семантически не менялся. Это была прекрасная точка для расширения. - Однако, в версиях 10.5.46, 11 и 12 этот метод стал
private. - Обращения к автору PHPUnit не работают. Даже такие.
- В PEST тоже столкнулись с этой проблемой. Что они сделали? Просто переопределил некоторые классы PHPUnit в своём неймспейсе. Но это хрупкое решение, поэтому в PEST дополнительно выставлены конфликты в composer.json, чтобы не допустить ломающего обновления PHPUnit.
Философия Testo
Полный контроль разработчика
С позиции Testo, тесты — это владение разработчика, а не фреймворка. Вся метаинформация и оперативные данные, нужные фреймворку, хранятся и обрабатываются в стороне.
Поэтому:
- Тестовым классам не нужно наследоваться от
TestCase - Тест-кейс не запускает сам себя и даже не знает своё имя в тестовой среде
- Вы можете использовать конструктор как угодно
- Тестами могут быть даже обычные функции!
#[Test]
function simpleTest(): void
{
Assert::true(true);
}Расширяемость
Testo построен на простой идее: небольшое ядро с набором DTO и контрактов, а весь функционал выстраивается на базе middleware и системы событий.
Ядро просто выстраивает несколько pipelines из middleware, а дальше делай что хочешь. Любая фича фреймворка это middleware или бработчики событий:
- Атрибуты в целом
- Дата-провайдеры
- Inline-тестирование
- Система утверждений (
Assert,Expect) - CLI рендеринг и TeamCity
Продуманное API
Вместо раздутого фасада Assert на ~2300 строк (как в PHPUnit), Testo предоставляет:
Assert— для утверждений (проверяются здесь и сейчас)Expect— для ожиданий (проверяются после завершения теста)- Пайповые ассерты — группировка по типам для чистоты кода:
// Строки
Assert::string($string)->contains("str");
// Файлы
Assert::file("foo.txt")->notExists();
// Исключения
Expect::exception(Failure::class)
->fromMethod(Service::class, 'process')
->withMessage("foo bar");Testo поставляется с плагином для PhpStorm/IntelliJ IDEA, в котором есть весь привычный функционал с запуском тестов, навигацией и отладкой.
Для кого Testo?
Testo создан для тех, кто:
- Разрабатывает фреймворки и нуждается в глубокой интеграции тестов.
- Создаёт SDK со специфичными требованиями к тестированию.
- Строит сложные системы, где PHPUnit не даёт нужной гибкости.
- Хочет полного контроля над тестовой инфраструктурой.
- Предпочитает синтаксис PHP, а не JS.
Что дальше?
Testo находится в активной разработке и движется к версии 1.0.0. Мы открыты для идей и предложений от сообщества.
Присоединяйтесь к обсуждению в Telegram или участвуйте в разработке на GitHub.
Мы верим, что разработчики должны иметь полный контроль над своей тестовой средой, и Testo предоставляет именно это.