Spec-Zone.ru › PHPUnit

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 name

  • snake_case: test_greets_with_name превращается в Greets with name

  • Числа: testValueIsGreaterThan0 превращается в Value is greater than 0

Рассмотрим следующий тестовый класс:

Пример 8.1 Класс с именем Greeter (объявленный в src/Greeter.php)
<?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 . '!';
    }
}
Пример 8.2 Тестовый класс с именем GreeterTest (объявленный в tests/GreeterTest.php)
<?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) можно использовать на уровне класса и/или метода, чтобы задать собственный текст документации.

На уровне класса он заменяет имя класса, приведенное к удобному виду:

Пример 8.3 Использование атрибута TestDox на уровне класса
<?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 используется для тестового метода, который применяет поставщик данных, можно добавить заполнители, ссылающиеся на параметры метода. Каждый заполнитель представляет собой имя параметра с префиксом $.

Пример 8.4 Использование заполнителей в атрибуте 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.

Пример 8.5 Использование атрибута TestDoxFormatter
<?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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API