Spec-Zone.ru › PHPUnit 9

Аннотации

Аннотация — это специальная форма синтаксической метаданных, которая может быть добавлена к исходному коду некоторых языков программирования. Хотя PHP не имеет специальной языковой возможности для аннотирования исходного кода, в сообществе PHP используется использование тегов, таких как @annotation arguments, в блоке документации для аннотирования исходного кода. В блоках документации PHP отражаются: они могут быть доступны через метод API рефлексии getDocComment() на уровне функций, классов, методов и атрибутов. Такие приложения, как PHPUnit, используют эту информацию во время выполнения для настройки своего поведения.

Примечание

Комментирование документации в PHP должно начинаться с /** и заканчиваться */. Аннотации в любом другом стиле комментариев будут проигнорированы.

В этом приложении показаны все разновидности аннотаций, поддерживаемые PHPUnit.

@author

Аннотация @author является псевдонимом для аннотации @group (см. @group) и позволяет фильтровать тесты на основе их авторов.

@after

Аннотация @after может быть использована для указания методов, которые должны вызываться после каждого метода теста в классе тестового случая.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    /**
     * @after
     */
    public function tearDownSomeFixtures(): void
    {
        // ...
    }

    /**
     * @after
     */
    public function tearDownSomeOtherFixtures(): void
    {
        // ...
    }
}

@afterClass

Аннотация @afterClass может быть использована для указания статических методов, которые должны вызываться после выполнения всех методов теста в классе теста для очистки общих фикстур.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    /**
     * @afterClass
     */
    public static function tearDownSomeSharedFixtures(): void
    {
        // ...
    }

    /**
     * @afterClass
     */
    public static function tearDownSomeOtherSharedFixtures(): void
    {
        // ...
    }
}

@backupGlobals

PHPUnit может по желанию сохранять все глобальные и сверхглобальные переменные перед каждым тестом и восстанавливать это сохранение после каждого теста.

Аннотация @backupGlobals enabled может использоваться на уровне класса для включения этой операции для всех тестов класса тестового случая:

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

/**
 * @backupGlobals enabled
 */
final class MyTest extends TestCase
{
    // ...
}

Аннотация @backupGlobals также может быть использована на уровне метода теста. Это позволяет для тонкой настройки операций резервного копирования и восстановления:

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

/**
 * @backupGlobals enabled
 */
final class MyTest extends TestCase
{
    public function testThatInteractsWithGlobalVariables()
    {
        // ...
    }

    /**
     * @backupGlobals disabled
     */
    public function testThatDoesNotInteractWithGlobalVariables(): void
    {
        // ...
    }
}

@backupStaticAttributes

PHPUnit может по желанию сохранять все статические атрибуты во всех объявленных классах перед каждым тестом и восстанавливать это сохранение после каждого теста.

Аннотация @backupStaticAttributes enabled может использоваться на уровне класса для включения этой операции для всех тестов класса тестового случая:

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

/**
 * @backupStaticAttributes enabled
 */
final class MyTest extends TestCase
{
    // ...
}

Аннотация @backupStaticAttributes также может быть использована на уровне метода теста. Это позволяет для тонкой настройки операций резервного копирования и восстановления:

use PHPUnit\Framework\TestCase;

/**
 * @backupStaticAttributes enabled
 */
class MyTest extends TestCase
{
    public function testThatInteractsWithStaticAttributes(): void
    {
        // ...
    }

    /**
     * @backupStaticAttributes disabled
     */
    public function testThatDoesNotInteractWithStaticAttributes(): void
    {
        // ...
    }
}

Примечание

@backupStaticAttributes ограничено внутренними механизмами PHP и может в некоторых случаях привести к непредвиденному сохранению статических значений и утечке в последующие тесты.

Подробности см. в Глобальное состояние.

@before

Аннотация @before может быть использована для указания методов, которые должны вызываться перед каждым методом теста в классе тестового случая.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    /**
     * @before
     */
    public function setupSomeFixtures(): void
    {
        // ...
    }

    /**
     * @before
     */
    public function setupSomeOtherFixtures(): void
    {
        // ...
    }
}

@beforeClass

Аннотация @beforeClass может быть использована для указания статических методов, которые должны вызываться перед запуском любых методов теста в классе теста для настройки общих фикстур.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    /**
     * @beforeClass
     */
    public static function setUpSomeSharedFixtures(): void
    {
        // ...
    }

    /**
     * @beforeClass
     */
    public static function setUpSomeOtherSharedFixtures(): void
    {
        // ...
    }
}

@codeCoverageIgnore*

Аннотации @codeCoverageIgnore, @codeCoverageIgnoreStart и @codeCoverageIgnoreEnd могут быть использованы для исключения строк кода из анализа покрытия.

Для использования см. Игнорирование блоков кода.

@covers

Аннотация @covers может быть использована в коде теста для указания, какие части кода он должен тестировать:

/**
 * @covers \BankAccount
 */
public function testBalanceIsInitiallyZero(): void
{
    $this->assertSame(0, $this->ba->getBalance());
}

Если она указана, она эффективно фильтрует отчет о покрытии кода, чтобы включать исполненный код только из указанных частей. Это гарантирует, что код будет помечен как покрытый только в том случае, если для него есть отдельные тесты, но не если он используется косвенно тестами для другого класса, тем самым избегая ложных срабатываний для покрытия кода.

Эту аннотацию можно добавить в блок документации класса теста или отдельных методов теста. Рекомендуется добавить аннотацию в блок документации класса теста, а не в блок документации методов теста.

Когда опция конфигурации forceCoversAnnotation в файле конфигурации установлена в true, каждый метод теста должен иметь связанную аннотацию @covers (либо в классе теста, либо в отдельном методе теста).

Таблица 2.2 показывает синтаксис аннотации @covers. Раздел Указание покрытых частей кода содержит более подробные примеры использования аннотации.

Обратите внимание, что для этой аннотации требуется полное имя класса (FQCN). Для большей ясности для читателя рекомендуется использовать ведущую обратную косую черту (даже если это не требуется для корректной работы аннотации).

Таблица 2.2 Аннотации для указания методов, которые покрываются тестом
Аннотация Описание
@covers ClassName::methodName (не рекомендуется) Указывает, что анотированный метод теста покрывает указанный метод.
@covers ClassName (рекомендуется) Указывает, что анотированный метод теста покрывает все методы данного класса.
@covers ClassName<extended> (не рекомендуется) Указывает, что анотированный метод теста покрывает все методы данного класса и его родительских классов.
@covers ClassName::<public> (не рекомендуется) Указывает, что анотированный метод теста покрывает все публичные методы данного класса.
@covers ClassName::<protected> (не рекомендуется) Указывает, что анотированный метод теста покрывает все защищенные методы данного класса.
@covers ClassName::<private> (не рекомендуется) Указывает, что анотированный метод теста покрывает все приватные методы данного класса.
@covers ClassName::<!public> (не рекомендуется) Указывает, что анотированный метод теста покрывает все методы данного класса, которые не являются публичными.
@covers ClassName::<!protected> (не рекомендуется) Указывает, что анотированный метод теста покрывает все методы данного класса, которые не являются защищенными.
@covers ClassName::<!private> (не рекомендуется) Указывает, что анотированный метод теста покрывает все методы данного класса, которые не являются приватными.
@covers ::functionName (рекомендуется) Указывает, что анотированный метод теста покрывает указанную глобальную функцию.

@coversDefaultClass

Аннотация @coversDefaultClass может быть использована для указания имени по умолчанию пространства имен или класса. Таким образом, длинные имена не нужно повторять для каждой аннотации @covers. См. Пример 2.18.

Обратите внимание, что для этой аннотации требуется полное имя класса (FQCN). Для большей ясности для читателя рекомендуется использовать ведущую обратную косую черту (даже если это не требуется для корректной работы аннотации).

Пример 2.18 Использование @coversDefaultClass для сокращения аннотаций
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

/**
 * @coversDefaultClass \Foo\CoveredClass
 */
final class CoversDefaultClassTest extends TestCase
{
    /**
     * @covers ::publicMethod
     */
    public function testSomething(): void
    {
        $o = new Foo\CoveredClass;
        $o->publicMethod();
    }
}

@coversNothing

Аннотация @coversNothing может использоваться в коде теста для указания, что для анотированного тестового случая информация о покрытии кода не будет регистрироваться.

Это может использоваться для интеграционных тестов. См. Тест, который указывает, что ни один метод не должен быть покрыт для примера.

Аннотация может быть использована на уровне класса и на уровне метода и переопределит любые теги @covers.

@dataProvider

Метод теста может принимать произвольные аргументы. Эти аргументы должны быть предоставлены одним или несколькими методами-поставщиками данных (provider() в Использование поставщика данных, возвращающего массив массивов). Используемый метод-поставщик данных указывается с помощью аннотации @dataProvider.

См. Поставщики данных для получения более подробной информации.

END_OF_DOCUMENT_MARKER

@depends

PHPUnit поддерживает объявление явных зависимостей между методами тестов. Такие зависимости не определяют порядок выполнения методов тестов, но позволяют производителю возвращать экземпляр фикстуры теста и передавать его зависимым потребителям. Использование аннотации @depends для выражения зависимостей демонстрирует, как использовать аннотацию @depends для выражения зависимостей между методами тестов.

Дополнительные сведения см. в разделе Зависимости тестов.

@doesNotPerformAssertions

Предотвращает отметку теста, не выполняющего утверждения, как рискованный.

@group

Тест может быть помечен как принадлежащий одной или нескольким группам, используя аннотацию @group следующим образом:

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    /**
     * @group specification
     */
    public function testSomething(): void
    {
    }

    /**
     * @group regression
     * @group bug2204
     */
    public function testSomethingElse(): void
    {
    }
}

Аннотация @group также может быть предоставлена для класса теста. Она затем «унаследуется» всеми методами теста этого класса.

Тесты могут быть выбраны для выполнения на основе групп с помощью опций --group и --exclude-group командной строки или с помощью соответствующих директив файла конфигурации XML.

@large

Аннотация @large является псевдонимом для @group large.

Если пакет PHP_Invoker установлен и включен строгий режим, большой тест завершится ошибкой, если его выполнение займёт более 60 секунд. Это время ожидания можно настроить с помощью атрибута timeoutForLargeTests в файле конфигурации XML.

@medium

Аннотация @medium является псевдонимом для @group medium. Тест среднего размера не должен зависеть от теста, помеченного как @large.

Если пакет PHP_Invoker установлен и включен строгий режим, тест среднего размера завершится ошибкой, если его выполнение займёт более 10 секунд. Это время ожидания можно настроить с помощью атрибута timeoutForMediumTests в файле конфигурации XML.

@preserveGlobalState

Когда тест выполняется в отдельном процессе, PHPUnit попытается сохранить глобальное состояние из родительского процесса, сериализуя все глобальные переменные в родительском процессе и десериализуя их в дочернем процессе. Это может вызвать проблемы, если родительский процесс содержит глобальные переменные, которые не подлежат сериализации. Для исправления этой проблемы можно предотвратить сохранение глобального состояния PHPUnit с помощью аннотации @preserveGlobalState.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function testInSeparateProcess(): void
    {
        // ...
    }
}

@requires

Аннотация @requires может использоваться для пропуска тестов, когда не выполнены общие предварительные условия, такие как версия PHP или установленные расширения.

Полный список возможностей и примеров можно найти в Возможные использования @requires.

@runTestsInSeparateProcesses

Указывает, что все тесты в классе теста должны выполняться в отдельном процессе PHP.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

/**
 * @runTestsInSeparateProcesses
 */
final class MyTest extends TestCase
{
    // ...
}

Примечание: По умолчанию PHPUnit попытается сохранить глобальное состояние из родительского процесса, сериализуя все глобальные переменные в родительском процессе и десериализуя их в дочернем процессе. Это может вызвать проблемы, если родительский процесс содержит глобальные переменные, которые не подлежат сериализации. См. @preserveGlobalState для получения информации о том, как это исправить.

@runInSeparateProcess

Указывает, что тест должен выполняться в отдельном процессе PHP.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class MyTest extends TestCase
{
    /**
     * @runInSeparateProcess
     */
    public function testInSeparateProcess(): void
    {
        // ...
    }
}

Примечание: По умолчанию PHPUnit попытается сохранить глобальное состояние из родительского процесса, сериализуя все глобальные переменные в родительском процессе и десериализуя их в дочернем процессе. Это может вызвать проблемы, если родительский процесс содержит глобальные переменные, которые не подлежат сериализации. См. @preserveGlobalState для получения информации о том, как это исправить.

@small

Аннотация @small является псевдонимом для @group small. Тест малого размера не должен зависеть от теста, помеченного как @medium или @large.

Если пакет PHP_Invoker установлен и включен строгий режим, тест малого размера завершится ошибкой, если его выполнение займёт более 1 секунды. Это время ожидания можно настроить с помощью атрибута timeoutForSmallTests в файле конфигурации XML.

Примечание

Для включения ограничений по времени выполнения тесты должны быть явно помечены аннотациями @small, @medium, или @large.

@test

В качестве альтернативы префиксу вашей имени метода теста с test, вы можете использовать аннотацию @test в DocBlock метода, чтобы пометить его как метод теста.

/**
 * @test
 */
public function initialBalanceShouldBe0(): void
{
    $this->assertSame(0, $this->ba->getBalance());
}

@testdox

Указывает альтернативное описание, используемое при генерации предложений документации к agile.

Аннотация @testdox может быть применена как к классам тестов, так и к методам тестов.

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

/**
 * @testdox A bank account
 */
final class BankAccountTest extends TestCase
{
    /**
     * @testdox has an initial balance of zero
     */
    public function balanceIsInitiallyZero(): void
    {
        $this->assertSame(0, $this->ba->getBalance());
    }
}

Примечание

До PHPUnit 7.0 (из-за ошибки в парсинге аннотаций), использование аннотации @testdox также активировало поведение аннотации @test.

При использовании аннотации @testdox на уровне метода с @dataProvider, вы можете использовать параметры метода в качестве заполнителей в вашем альтернативном описании.

/**
 * @dataProvider additionProvider
 * @testdox Adding $a to $b results in $expected
 */
public function testAdd($a, $b, $expected)
{
    $this->assertSame($expected, $a + $b);
}

public function additionProvider()
{
    return [
        [0, 0, 0],
        [0, 1, 1],
        [1, 0, 1],
        [1, 1, 3]
    ];
}

@testWith

Вместо реализации метода для использования с @dataProvider, вы можете определить набор данных с помощью аннотации @testWith.

Набор данных состоит из одного или нескольких элементов. Для определения набора данных с несколькими элементами, определите каждый элемент в отдельной строке. Каждый элемент набора данных должен быть массивом, определённым в JSON.

См. Поставщики данных, чтобы узнать больше о передаче набора данных тесту.

/**
 * @testWith ["test", 4]
 *           ["longer-string", 13]
 */
public function testStringLength(string $input, int $expectedLength): void
{
    $this->assertSame($expectedLength, strlen($input));
}

Представление объекта в JSON будет преобразовано в ассоциативный массив.

/**
 * @testWith [{"day": "monday", "conditions": "sunny"}, ["day", "conditions"]]
 */
public function testArrayKeys(array $array, array $keys): void
{
    $this->assertSame($keys, array_keys($array));
}

@ticket

Аннотация @ticket является псевдонимом для аннотации @group (см. @group) и позволяет фильтровать тесты на основе их идентификатора билета.

@uses

Аннотация @uses указывает код, который будет выполняться тестом, но не предполагается, что он будет охвачен тестом. Хорошим примером является объект значения, который необходим для тестирования блока кода.

/**
 * @covers \BankAccount
 * @uses   \Money
 */
public function testMoneyCanBeDepositedInAccount(): void
{
    // ...
}

Пример 9.2 показывает ещё один пример.

Помимо полезности для чтения кода, эта аннотация полезна в режиме строгого контроля покрытия, где непреднамеренно покрытый код заставит тест завершиться ошибкой. См. Непреднамеренно покрытый код для получения дополнительной информации о режиме строгого контроля покрытия.

Обратите внимание, что для этой аннотации требуется полное имя класса (FQCN). Для большей наглядности для читателя рекомендуется использовать ведущий обратный слэш (даже если это не требуется для корректной работы аннотации).

© 2005–2020 Sebastian Bergmann
Licensed under the Creative Commons Attribution 3.0 Unported License.
https://phpunit.readthedocs.io/en/9.5/annotations.html

Spec-Zone.ru

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