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 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 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.
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ão
ignoradas.
Este apêndice mostra todas as variedades de anotações suportadas pelo PHPUnit.
A anotação @author
é um apelido para a anotação
@group
(veja “@group”) e permite filtrar os testes baseado
em seus autores.
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.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @after */ public function tearDownSomeFixtures() { // ... } /** * @after */ public function tearDownSomeOtherFixtures() { // ... } }
A anotação @afterClass
pode ser usada para especificar
métodos estáticos que devem ser chamados depois que todos os métodos de teste em uma classe
de teste foram executados para limpar ambientes compartilhados.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @afterClass */ public static function tearDownSomeSharedFixtures() { // ... } /** * @afterClass */ public static function tearDownSomeOtherSharedFixtures() { // ... } }
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
use PHPUnit\Framework\TestCase; /** * @backupGlobals disabled */ class MyTest extends 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:
use PHPUnit\Framework\TestCase; /** * @backupGlobals disabled */ class MyTest extends TestCase { /** * @backupGlobals enabled */ public function testThatInteractsWithGlobalVariables() { // ... } }
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:
use PHPUnit\Framework\TestCase; /** * @backupStaticAttributes enabled */ class MyTest extends TestCase { /** * @backupStaticAttributes disabled */ public function testThatInteractsWithStaticAttributes() { // ... } }
@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.
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.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @before */ public function setupSomeFixtures() { // ... } /** * @before */ public function setupSomeOtherFixtures() { // ... } }
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.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @beforeClass */ public static function setUpSomeSharedFixtures() { // ... } /** * @beforeClass */ public static function setUpSomeOtherSharedFixtures() { // ... } }
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”.
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ção | Descrição |
---|---|
@covers ClassName::methodName | Especifica que o método de teste anotado cobre o método especificado. |
@covers ClassName | Especifica 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 ::functionName | Especifica que método de teste anotado cobre a função global especificada. |
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 use PHPUnit\Framework\TestCase; /** * @coversDefaultClass \Foo\CoveredClass */ class CoversDefaultClassTest extends TestCase { /** * @covers ::publicMethod */ public function testSomething() { $o = new Foo\CoveredClass; $o->publicMethod(); } } ?>
A anotação @coversNothing
pode ser usada no
código de teste para especificar que nenhuma informação de cobertura de código será
registrada 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
.
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.
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.
O Exemplo 2.10
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.
A anotação @expectedExceptionCode
em conjunto
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.
use PHPUnit\Framework\TestCase; class MyTest extends 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
".
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @expectedException MyException * @expectedExceptionCode MyClass::ERRORCODE */ public function testExceptionHasErrorcode20() { throw new MyException('Some Message', 20); } } class MyClass { const ERRORCODE = 20; }
A anotação @expectedExceptionMessage
funciona de modo similar
a @expectedExceptionCode
já que lhe permite fazer uma
asserção na mensagem de erro de uma exceção.
use PHPUnit\Framework\TestCase; class MyTest extends 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 mensagem de exceção no teste.
use PHPUnit\Framework\TestCase; class MyTest extends 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”.
A mensagem experada também pode ser especificada como uma expressão regular usando
a anotação @expectedExceptionMessageRegExp
. Isso
é útil em situações onde uma substring não é adequada para combinar
uma determinada mensagem.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @expectedException MyException * @expectedExceptionMessageRegExp /Argument \d+ can not be an? \w+/ */ public function testExceptionHasRightMessage() { throw new MyException('Argument 2 can not be an integer'); } }
Um teste pode ser marcado como pertencente a um ou mais grupos usando a
anotação @group
desta forma
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @group specification */ public function testSomething() { } /** * @group regresssion * @group bug2204 */ public function testSomethingElse() { } }
Testes podem ser selecionados para execução baseados 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.
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.
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.
Quando um teste é executado em um processo separado, o PHPUnit
tentará preservar o estado global do 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
.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testInSeparateProcess() { // ... } }
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
Indica que todos testes em uma classe de teste devem ser executados em um processo PHP separado.
use PHPUnit\Framework\TestCase; /** * @runTestsInSeparateProcesses */ class MyTest extends TestCase { // ... }
Nota: Por padrão, o PHPUnit tentará preservar o estado global do 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.
Indica que um teste deve ser executado em um processo PHP separado.
use PHPUnit\Framework\TestCase; class MyTest extends TestCase { /** * @runInSeparateProcess */ public function testInSeparateProcess() { // ... } }
Nota: Por padrão, o PHPUnit tentará preservar o estado global do 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.
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.
Testes precisam ser explicitamente anotados com @small
,
@medium
ou @large
para ativar limites de tempo de execução.
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()); }
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 uma unidade de código.
/** * @covers BankAccount::deposit * @uses Money */ public function testMoneyCanBeDepositedInAccount() { // ... }
Essa anotação é especialmente útil em modo de cobertura estrita onde código coberto involuntariamente fará um teste falhar. Veja “Cobertura de Código Involuntária” para mais informação sobre modo de cobertura estrita.