TestDox
TestDox — это функция, которая позволяет тестам служить не только исполняемой проверкой, но и исполняемой спецификацией и исполняемой документацией.
При разработке через тестирование (TDD) тесты пишутся до производственного кода. В этом контексте тесты служат исполняемой спецификацией: они описывают ожидаемое поведение кода, который еще предстоит написать. После написания производственного кода тесты продолжают служить исполняемой документацией: они описывают фактическое поведение кода.
TestDox преобразует имена тестовых методов в понятные человеку предложения. При использовании вместе с параметром CLI --testdox он предоставляет представление набора тестов, основанное на поведении и похожее на документацию.
Поведение по умолчанию
По умолчанию PHPUnit использует соглашения об именовании тестовых классов и тестовых методов для создания понятной человеку документации.
Имена классов
Имя тестового класса приводится к удобному виду: сначала удаляется суффикс Test, затем имя в camelCase разбивается на слова. Например, GreeterTest превращается в Greeter.
Если тестовый класс находится в пространстве имен, в качестве заголовка используется короткое имя класса, а его полное имя (без суффикса Test) указывается в скобках. Например, App\Tests\GreeterTest превращается в Greeter (App\Tests\Greeter).
Имена методов
Имя тестового метода приводится к удобному виду: сначала удаляется префикс test (или test_ для имен методов в snake_case), а затем оставшаяся часть преобразуется в предложение:
camelCase:
testGreetsWithNameпревращается вGreets with namesnake_case:
test_greets_with_nameпревращается вGreets with nameЧисла:
testValueIsGreaterThan0превращается вValue is greater than 0
Рассмотрим следующий тестовый класс:
<?php declare(strict_types=1);
final class Greeter
{
public function greet(string $name): string
{
return 'Hello, ' . $name . '!';
}
public function greetWithTimeOfDay(string $name, int $hour): string
{
if ($hour < 12) {
return 'Good morning, ' . $name . '!';
}
if ($hour < 18) {
return 'Good afternoon, ' . $name . '!';
}
return 'Good evening, ' . $name . '!';
}
}
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class GreeterTest extends TestCase
{
public function testGreetsWithName(): void
{
$greeter = new Greeter;
$this->assertSame('Hello, World!', $greeter->greet('World'));
}
public function testGreetsWithGoodMorningBeforeNoon(): void
{
$greeter = new Greeter;
$this->assertSame(
'Good morning, Alice!',
$greeter->greetWithTimeOfDay('Alice', 9),
);
}
public function testGreetsWithGoodAfternoonAfterNoon(): void
{
$greeter = new Greeter;
$this->assertSame(
'Good afternoon, Alice!',
$greeter->greetWithTimeOfDay('Alice', 14),
);
}
public function testGreetsWithGoodEveningAfter6Pm(): void
{
$greeter = new Greeter;
$this->assertSame(
'Good evening, Alice!',
$greeter->greetWithTimeOfDay('Alice', 20),
);
}
}
Запуск этого теста с параметром --testdox дает результат, показанный ниже:
$ ./tools/phpunit --no-progress --testdox tests/GreeterTest.php PHPUnit 13.2.0 by Sebastian Bergmann and contributors. Runtime: PHP 8.5.3 Time: 00:00.077, Memory: 10.00 MB Greeter ✔ Greets with name ✔ Greets with good morning before noon ✔ Greets with good afternoon after noon ✔ Greets with good evening after 6 pm OK (4 tests, 4 assertions)
Поставщики данных
Если тестовый метод использует поставщик данных, TestDox добавляет сведения о наборе данных к имени метода, приведенному к удобному виду:
Для индексированных наборов данных:
with data set #0Для именованных наборов данных:
with "name"
Настройка документации тестов
Преобразования по умолчанию часто достаточно, но иногда требуется больше контроля над текстом документации. Для этого PHPUnit предоставляет три атрибута.
Атрибут TestDox
Атрибут TestDox(string $text) можно использовать на уровне класса и/или метода, чтобы задать собственный текст документации.
На уровне класса он заменяет имя класса, приведенное к удобному виду:
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
#[TestDox('Greeting Service')]
final class GreeterTest extends TestCase
{
#[TestDox('Greets a person by their name')]
public function testGreetsWithName(): void
{
// ...
}
}
Запуск этого теста с включенным выводом TestDox дает следующий результат:
Greeting Service
✔ Greets a person by their name
Описание атрибута см. в разделе TestDox.
Использование заполнителей с поставщиками данных
Если атрибут TestDox используется для тестового метода, который применяет поставщик данных, можно добавить заполнители, ссылающиеся на параметры метода. Каждый заполнитель представляет собой имя параметра с префиксом $.
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\TestDox;
use PHPUnit\Framework\TestCase;
final class CalculatorTest extends TestCase
{
#[DataProvider('additionProvider')]
#[TestDox('Adding $a to $b results in $expected')]
public function testAdd(int $expected, int $a, int $b): void
{
$this->assertSame($expected, $a + $b);
}
public static function additionProvider(): array
{
return [
'zero plus zero' => [0, 0, 0],
'zero plus one' => [1, 0, 1],
'one plus zero' => [1, 1, 0],
'one plus one' => [2, 1, 1],
];
}
}
Запуск этого теста с включенным выводом TestDox дает следующий результат:
Calculator
✔ Adding 0 to 0 results in 0
✔ Adding 0 to 1 results in 1
✔ Adding 1 to 0 results in 1
✔ Adding 1 to 1 results in 2
При использовании заполнителей сведения о поставщике данных не добавляются к тексту, поскольку значения параметров уже включены в текст документации.
Доступен специальный заполнитель $_dataName, который заменяется именем текущего набора данных (например, zero plus zero или one plus one в примере выше).
Атрибут TestDoxFormatter
Атрибут TestDoxFormatter(string $methodName) можно использовать для тестового метода, чтобы указать статический метод того же класса, форматирующий текст документации. Это полезно, когда текст документации требует логики, которую нельзя выразить с помощью простых заполнителей, например, если объекты необходимо отформатировать определенным образом.
Метод форматирования должен быть public и static. Он получает те же параметры, что и тестовый метод (от поставщика данных), и должен возвращать string.
<?php declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\TestDoxFormatter;
use PHPUnit\Framework\TestCase;
final class ExampleTest extends TestCase
{
public static function provider(): array
{
return [
[
new DateTimeImmutable('2025-08-01'),
new DateTimeImmutable('2025-08-01'),
],
];
}
public static function formatter(DateTimeImmutable $expected, DateTimeImmutable $actual): string
{
return sprintf(
'%s is expected to be %s',
$actual->format('Y-m-d'),
$expected->format('Y-m-d'),
);
}
#[DataProvider('provider')]
#[TestDoxFormatter('formatter')]
public function testOne(DateTimeImmutable $expected, DateTimeImmutable $actual): void
{
$this->assertEquals($expected, $actual);
}
}
Запуск этого теста с включенным выводом TestDox дает следующий результат:
Example
✔ 2025-08-01 is expected to be 2025-08-01
Описание атрибута см. в разделе TestDoxFormatter.
Атрибут TestDoxFormatterExternal
Атрибут TestDoxFormatterExternal(string $className, string $methodName) работает так же, как TestDoxFormatter, но ссылается на метод public static, объявленный в другом классе. Это полезно, когда несколько тестовых классов используют одну и ту же логику форматирования.
Описание атрибута см. в разделе TestDoxFormatterExternal.
Вывод TestDox
Вывод в консоль
Параметр CLI --testdox заменяет вывод результатов по умолчанию на формат TestDox. Для обозначения состояния каждого теста используются следующие символы:
✔ Тест пройден
✘ Тест завершился с ошибкой или сбоем
↩ Тест пропущен
⚠ Тест вызвал предупреждение
∅ Тест не завершен
Параметр CLI --testdox-summary повторно выводит результаты TestDox в конце запуска тестов для тестов, в которых были ошибки, сбои или проблемы. Это позволяет получить краткую сводку проблемных тестов в формате TestDox.
Вывод в виде обычного текста
Параметр CLI --testdox-text <file> записывает результаты тестов в формате TestDox в обычный текстовый файл. Успешные тесты отмечаются символом [x], а тесты с дефектами — символом [ ]:
Greeter
[x] Greets with name
[x] Greets with good morning before noon
[x] Greets with good afternoon after noon
[x] Greets with good evening after 6 pm
Это также можно настроить в XML-файле конфигурации с помощью элемента <testdoxText> внутри элемента <logging> (см. раздел Элемент <testdoxText>).
Вывод в формате HTML
Параметр CLI --testdox-html <file> записывает результаты тестов в формате TestDox в HTML-файл. В результате создается документ с оформленными результатами, который можно просматривать в браузере: успешные тесты отмечены зеленой галочкой ✓, а тесты с дефектами — красным крестиком ✗.
Это также можно настроить в XML-файле конфигурации с помощью элемента <testdoxHtml> внутри элемента <logging> (см. раздел Элемент <testdoxHtml>).
Конфигурация XML
Вывод TestDox можно включить через XML-файл конфигурации вместо использования параметров CLI.
Атрибут testdox элемента <phpunit> включает вывод TestDox в консоль (см. раздел Атрибут testdox).
Атрибут testdoxSummary элемента <phpunit> включает сводку TestDox (см. раздел Атрибут testdoxSummary).
Вывод TestDox в файл настраивается с помощью дочерних элементов элемента <logging>:
<phpunittestdox="true"testdoxSummary="true">
<logging>
<testdoxHtmloutputFile="testdox.html"/>
<testdoxTextoutputFile="testdox.txt"/>
</logging>
</phpunit>
© 2005–2026 Sebastian Bergmann
Licensed under the Creative Commons Attribution 3.0 Unported License.
https://docs.phpunit.de/en/13.2/testdox.html