Apêndice B. Anotações

Uma anotação é uma forma especial de metadados sintáticos que podem ser adicionados ao código-fonte de algumas linguagens de programação. Enquanto o PHP não tem um recurso de linguagem dedicado a anotação de código-fonte, o uso de tags como @annotation arguments em bloco de documentação tem sido estabelecido na comunidade do PHP para anotar o código-fonte. Os blocos de documentação PHP são reflexivos: eles podem ser acessados através do método getDocComment() da API Reflection a nível de função, classe, método e atributo. Aplicações como o PHPUnit usam essa informação em tempo de execução para configurar seu comportamento.

Nota

Um comentário de documentação em PHP deve começar com /** e terminar com */. Anotações em algum outro estilo de comentário será ignorada.

Este apêndice mostra todas as variedades de anotações suportadas pelo PHPUnit.

@author

A anotação @author é um apelido para a anotação @group (veja “@group”) e permite filtrar os testes baseado em seus autores.

@after

A anotação @after pode ser usada para especificar métodos que devem ser chamados depois de cada método em uma classe de caso de teste.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @after
     */
    public function tearDownSomeFixtures()
    {
        // ...
    }

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

@afterClass

A anotação @afterClass pode ser usada para especificar métodos estáticos que devem ser chamados depois de todos os métodos de teste em uma classe de teste foram executados para limpar ambientes compartilhados.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @afterClass
     */
    public static function tearDownSomeSharedFixtures()
    {
        // ...
    }

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

@backupGlobals

As operações de cópia de segurança e restauração para variáveis globais podem ser completamente desabilitadas para todos os testes de uma classe de caso de teste como esta

/**
 * @backupGlobals disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    // ...
}

A anotação @backupGlobals também pode ser usada a nível de método de teste. Isso permite uma configuração refinada das operações de cópia de segurança e restauração:

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

@backupStaticAttributes

A anotação @backupStaticAttributes pode ser usada para copiar todos valores de propriedades estáticas em todas classes declaradas antes de cada teste e restaurá-los depois. Pode ser usado em nível de classe de caso de teste ou método de teste:

/**
 * @backupStaticAttributes enabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @backupStaticAttributes disabled
     */
    public function testThatInteractsWithStaticAttributes()
    {
        // ...
    }
}

Nota

@backupStaticAttributes é limitada pela parte interna do PHP e pode causar valores estáticos não intencionais ao persistir e vazar para testes subsequentes em algumas circunstâncias.

Veja “Estado Global” para detalhes.

@before

A anotação @before pode ser usada para especificar métodos que devem ser chamados antes de cada método de teste em uma classe de caso de teste.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @before
     */
    public function setupSomeFixtures()
    {
        // ...
    }

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

@beforeClass

A anotação @beforeClass pode ser usada para especificar métodos estáticos que devem ser chamados antes de quaisquer métodos de teste em uma classe de teste serem executados para criar ambientes compartilahdos.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @beforeClass
     */
    public static function setUpSomeSharedFixtures()
    {
        // ...
    }

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

@codeCoverageIgnore*

As anotações @codeCoverageIgnore, @codeCoverageIgnoreStart e @codeCoverageIgnoreEnd podem ser usadas para excluir linhas de código da análise de cobertura.

Para uso, veja “Ignorando Blocos de Código”.

@covers

A anotação @covers pode ser usada no código de teste para especificar quais métodos um método de teste quer testar:

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

Se fornecida, apenas a informação de cobertura de código para o(s) método(s) especificado(s) será considerada.

Tabela B.1 mostra a sintaxe da anotação @covers.

Tabela B.1. Anotações para especificar quais métodos são cobertos por um teste

AnotaçãoDescrição
@covers ClassName::methodNameEspecifica que o método de teste anotado cobre o método especificado.
@covers ClassNameEspecifica que o método de teste anotado cobre todos os métodos de uma dada classe.
@covers ClassName<extended>Especifica que o método de teste anotado cobre todos os métodos de uma dada classe e sua(s) classe(s) pai(s) e interface(s).
@covers ClassName::<public>Especifica que o método de teste anotado cobre todos os métodos públicos de uma dada classe.
@covers ClassName::<protected>Especifica que o método de teste anotado cobre todos os métodos protegidos de uma dada classe.
@covers ClassName::<private>Especifica que o método de teste anotado cobre todos os métodos privados de uma dada classe.
@covers ClassName::<!public>Especifica que o método de teste anotado cobre todos os métodos que não sejam públicos de uma dada classe.
@covers ClassName::<!protected>Especifica que o método de teste anotado cobre todos os métodos que não sejam protegidos de uma dada classe.
@covers ClassName::<!private>Especifica que o método de teste anotado cobre todos os métodos que não sejam privados de uma dada classe.
@covers ::functionNameEspecifica que o método de teste anotado cobre todos os métodos que não sejam privados de uma dada classe.


@coversDefaultClass

A anotação @coversDefaultClass pode ser usada para especificar um namespace padrão ou nome de classe. Dessa forma nomes longos não precisam ser repetidos para toda anotação @covers. Veja o Exemplo B.1.

Exemplo B.1: Usando @coversDefaultClass para encurtar anotações

<?php
/**
 * @coversDefaultClass \Foo\CoveredClass
 */
class CoversDefaultClassTest extends PHPUnit_Framework_TestCase
{
    /**
     * @covers ::publicMethod
     */
    public function testSomething()
    {
        $o = new Foo\CoveredClass;
        $o->publicMethod();
    }
}
?>


@coversNothing

A anotação @coversNothing pode ser usada no código de teste para especificar que nenhuma informação de cobertura de código será gravada para o caso de teste anotado.

Isso pode ser usado para testes de integração. Veja Exemplo 11.3 para um exemplo.

A anotação pode ser usada nos níveis de classe e de método e vão sobrescrever quaisquer tags @covers.

@dataProvider

Um método de teste pode aceitar argumentos arbitrários. Esses argumentos devem ser fornecidos por um método provedor (provider() em Exemplo 2.5). O método provedor de dados a ser usado é especificado usando a anotação @dataProvider.

Veja “Provedores de Dados” para mais detalhes.

@depends

O PHPUnit suporta a declaração de dependências explícitas entre métodos de teste. Tais dependências não definem a ordem em que os métodos de teste devem ser executados, mas permitem o retorno de uma instância do ambiente de teste por um produtor e passá-la aos consumidores dependentes. O Exemplo 2.2 mostra como usar a anotação @depends para expressar dependências entre métodos de teste.

Veja “Dependências de Testes” para mais detalhes.

@expectedException

O Exemplo 2.9 mostra como usar a anotação @expectedException para testar se uma exceção é lançada dentro do código testado.

Veja “Testando Exceções” para mais detalhes.

@expectedExceptionCode

A anotação @expectedExceptionCode em conjunção com a @expectedException permite fazer asserções no código de erro de uma exceção lançada, permitindo diminuir uma exceção específica.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException     MyException
     * @expectedExceptionCode 20
     */
    public function testExceptionHasErrorcode20()
    {
        throw new MyException('Some Message', 20);
    }
}

Para facilitar o teste e reduzir a duplicação, um atalho pode ser usado para especificar uma constante de classe como um @expectedExceptionCode usando a sintaxe "@expectedExceptionCode ClassName::CONST".

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
      * @expectedException     MyException
      * @expectedExceptionCode MyClass::ERRORCODE
      */
    public function testExceptionHasErrorcode20()
    {
      throw new MyException('Some Message', 20);
    }
}
class MyClass
{
    const ERRORCODE = 20;
}

@expectedExceptionMessage

A anotação @expectedExceptionMessage trabalha de modo similar a @expectedExceptionCode já que lhe permite fazer uma asserção na mensagem de erro de uma exceção.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException        MyException
     * @expectedExceptionMessage Some Message
     */
    public function testExceptionHasRightMessage()
    {
        throw new MyException('Some Message', 20);
    }
}

A mensagem esperada pode ser uma substring de uma Mensagem de exceção. Isso pode ser útil para asseverar apenas que um certo nome ou parâmetro que foi passado é mostrado na exceção e não fixar toda a mensagem de exceção no teste.

class MyTest extends PHPUnit_Framework_TestCase
{
     /**
      * @expectedException        MyException
      * @expectedExceptionMessage broken
      */
     public function testExceptionHasRightMessage()
     {
         $param = "broken";
         throw new MyException('Invalid parameter "'.$param.'".', 20);
     }
}

Para facilitar o teste e reduzir duplicação um atalho pode ser usado para especificar uma constante de classe como uma @expectedExceptionMessage usando a sintaxe "@expectedExceptionMessage ClassName::CONST". Um exemplo pode ser encontrado na seção chamada “@expectedExceptionCode”.

@expectedExceptionMessageRegExp

A mensagem experada também pode ser especificada como uma expressão regular usando a anotação @expectedExceptionMessageRegExp. Isso é útil em situações aonde uma substring não é adequada para combinar uma determinada mensagem.

class MyTest extends PHPUnit_Framework_TestCase
{
     /**
      * @expectedException              MyException
      * @expectedExceptionMessageRegExp /Argument \d+ can not be an? \w+/
      */
     public function testExceptionHasRightMessage()
     {
         throw new MyException('Argument 2 can not be an integer');
     }
}

@group

Um teste pode ser marcado como pertencente a um ou mais grupos usando a anotação @group desta forma

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @group specification
     */
    public function testSomething()
    {
    }

    /**
     * @group regresssion
     * @group bug2204
     */
    public function testSomethingElse()
    {
    }
}

Testes podem ser selecionados para execução baseada em grupos usando as opções --group e --exclude-group do executor de teste em linha-de-comando ou usando as respectivas diretivas do arquivo de configuração XML.

@large

A anotação @large é um apelido para @group large.

Se o pacote PHP_Invoker estiver instalado e o modo estrito estiver habilitado, um teste grande irá falhar se ele demorar mais de 60 segundos para executar. Esse tempo de espera é configurável através do atributo timeoutForLargeTests no arquivo de configuração XML.

@medium

A anotação @medium é um apelido para @group medium. Um teste médio não deve depender de um teste marcado como @large.

Se o pacote PHP_Invoker estiver instalado e o modo estrito estiver habilitado, um teste médio irá falhar se ele demorar mais de 10 segundos para executar. Esse tempo de espera é configurável através do atributo timeoutForMediumTests no arquivo de configuração XML.

@preserveGlobalState

Quando um teste é executado em um processo separado, o PHPUnit tentará preservar o estado global de processo pai serializando todos globais no processo pai e deserializando-os no processo filho. Isso pode causar problemas se o processo pai contém globais que não são serializáveis. Para corrigir isto, você pode prevenir o PHPUnit de preservar o estado global com a anotação @preserveGlobalState.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function testInSeparateProcess()
    {
        // ...
    }
}

@requires

A anotação @requires pode ser usada para pular testes quando pré-condições comuns, como a Versão do PHP ou extensões instaladas, não batem.

Uma lista completa de possibilidades e exemplos pode ser encontrada em Tabela 7.3

@runTestsInSeparateProcesses

Indica que todos testes em uma classe de teste devem ser executados em um processo PHP separado.

/**
 * @runTestsInSeparateProcesses
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    // ...
}

Nota: Por padrão, o PHPUnit tentará preservar o estado global de processo pai serializando todos globais no processo pai e deserializando-os no processo filho. Isso pode causar problemas se o processo pai contém globais que não são serializáveis. Veja “@preserveGlobalState” para informações de como corrigir isso.

@runInSeparateProcess

Indica que um teste deve ser executado em um processo PHP separado.

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @runInSeparateProcess
     */
    public function testInSeparateProcess()
    {
        // ...
    }
}

Nota: Por padrão, o PHPUnit tentará preservar o estado global de processo pai serializando todos globais no processo pai e deserializando-os no processo filho. Isso pode causar problemas se o processo pai contém globais que não são serializáveis. Veja “@preserveGlobalState” para informações de como corrigir isso.

@small

A anotação @small é um apelido para @group small. Um teste pequeno não deve depender de um teste marcado como @medium ou @large.

Se o pacote PHP_Invoker estiver instalado e o modo estrito estiver habilitado, um teste pequeno irá falhar se ele demorar mais de 1 segundo para executar. Esse tempo de espera é configurável através do atributo timeoutForLargeTests no arquivo de configuração XML.

Nota

Pr padrão, todos testes são considerados pequenos se eles não são como @medium ou @large. Note, por favor, no entanto, que --group e as opções relacionadas irão apenas considerarão um teste ser do grupo small se ele é marcado explicitamente com a anotação apropriada.

@test

Como uma alternativa para prefixar seus nomes de métodos de teste com test, você pode usar a anotação @test no Bloco de Documentação do método para marcá-lo como um método de teste.

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

@testdox

@ticket

@uses

A anotação @uses especifica o código que irá ser executado por um teste, mas não se destina a ser coberto pelo teste. Um bom exemplo é um objeto valor que é necessário para testar um unidade de código.

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

Essa anotação é especialmente útil em modo de cobertura estrita aonde código coberto involuntariamente fará um teste falhar. Veja “Cobertura de Código Involuntária” para mais informação sobre modo de cobertura estrito.

Por favor, abra um chamado no GitHub para sugerir melhorias para esta página. Obrigado!