Uma biblioteca Composer com atributos adicionais para aprimorar os testes com PHPUnit.
compositor requer --dev eliashaeussler/phpunit-attributes
A biblioteca vem com uma extensão PHPUnit pronta para uso. Deve estar cadastrado em seu arquivo de configuração do PHPUnit:
<?xml versão="1.0" codificação="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap = "vendor/autoload.php" >+ <extensões>+ <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension" />+ </extensions> <testsuites> <nome do conjunto de testes = "unidade"> <diretório>testes</diretório> </testsuite> </testsuites> <fonte> <incluir> <diretório>src</diretório> </incluir> </fonte> </phpunit>
Alguns atributos podem ser configurados com parâmetros de extensão customizados. Eles devem ser adicionados à seção de registro de extensão da seguinte forma:
<extensões>- <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension" />+ <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension">+ <parameter name="fancyParameterName" value="fancyParameterValue" />+ </bootstrap> </extensions>
Os seguintes atributos são fornecidos com esta biblioteca:
#[RequiresClass]
#[RequiresPackage]
#[RequiresClass]
Escopo: nível de classe e método
Com este atributo, testes ou casos de teste podem ser marcados para serem executados somente se existir uma determinada classe. A classe fornecida deve ser carregável pelo carregador de classes atual (que normalmente é o carregador de classes padrão do Composer).
Por padrão, os casos de teste que exigem classes inexistentes são ignorados. Entretanto, esse comportamento pode ser configurado usando o parâmetro de extensão handleMissingClasses
. Se definido como fail
, os casos de teste com classes ausentes falharão (o padrão é skip
):
<extensões> <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension"> <parâmetro name="handleMissingClasses" value="fail" /> </bootstrap> </extensões>
classe final DummyTest estende TestCase { #[RequiresClass(AnImportantClass::class)]função pública testDummyAction(): void{// ...} }
Nível de classe:
#[RequiresClass(AnImportantClass::class)]classe final DummyTest estende TestCase {função pública testDummyAction(): void{// ignorada se AnImportantClass estiver faltando.}função pública testOtherDummyAction(): void{// ignorada se AnImportantClass estiver faltando.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresClass(AnImportantClass::class)]public function testDummyAction(): void{// Ignorado se AnImportantClass estiver faltando.}public function testOtherDummyAction(): void{// Não ignorado.} }
Nível de classe:
#[RequiresClass(AnImportantClass::class, 'Este teste requer a classe `AnImportantClass`.')]classe final DummyTest estende TestCase {public function testDummyAction(): void{// Skipped se AnImportantClass estiver faltando, junto com a mensagem personalizada.}public function testOtherDummyAction(): void{// Skipped se AnImportantClass estiver faltando, junto com a mensagem personalizada.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresClass(AnImportantClass::class, 'Este teste requer a classe `AnImportantClass`.')]public function testDummyAction(): void{// Ignorado se AnImportantClass estiver faltando, junto com a mensagem personalizada.}public function testOtherDummyAction(): void{// Não ignorado.} }
Nível de classe:
#[RequiresClass(AnImportantClass::class, resultBehavior: OutcomeBehavior::Fail)]classe final DummyTest estende TestCase {public function testDummyAction(): void{// falha se AnImportantClass estiver faltando.}public function testOtherDummyAction(): void{// falha se AnImportantClass estiver faltando.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresClass(AnImportantClass::class, resultBehavior: OutcomeBehavior::Fail)]public function testDummyAction(): void{// Falha se AnImportantClass estiver faltando.}public function testOtherDummyAction(): void{// Não falha.} }
Nível de classe:
#[RequiresClass(AnImportantClass::class)] #[RequiresClass(AnotherVeryImportantClass::class)]classe final DummyTest estende TestCase {public function testDummyAction(): void{// Ignorado se AnImportantClass e/ou AnotherVeryImportantClass estiverem faltando.}public function testOtherDummyAction(): void{// Ignorado se AnImportantClass e/ou AnotherVeryImportantClass estiverem faltando.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresClass(AnImportantClass::class)] #[RequiresClass(AnotherVeryImportantClass::class)]public function testDummyAction(): void{// Ignorado se AnImportantClass e/ou AnotherVeryImportantClass estiverem faltando.}public function testOtherDummyAction(): void{// Não ignorado.} }
#[RequiresPackage]
Escopo: nível de classe e método
Este atributo pode ser usado para definir requisitos de pacote específicos para testes únicos, bem como para classes de teste completas. Espera-se que um pacote necessário seja instalado via Composer. Opcionalmente, você pode definir uma restrição de versão e uma mensagem personalizada.
Importante
O atributo determina os pacotes do Composer instalados a partir da classe InstalledVersions
gerada em tempo de construção e construída pelo Composer. Para ler corretamente esta classe, é essencial incluir o autoloader gerado pelo Composer em seu script de bootstrap do PHPUnit:
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php"><! -- ... --></phpunit>
Você também pode passar o script como opção de comando: phpunit --bootstrap vendor/autoload.php
Por padrão, os casos de teste com requisitos não satisfeitos são ignorados. No entanto, esse comportamento pode ser configurado usando o parâmetro de extensão handleUnsatisfiedPackageRequirements
. Se definido como fail
, os casos de teste com requisitos não satisfeitos falharão (o padrão é skip
):
<extensões> <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension"> <parameter name="handleUnsatisfiedPackageRequirements" value="fail" /> </bootstrap> </extensões>
classe final DummyTest estende TestCase { #[RequiresPackage('symfony/console')]função pública testDummyAction(): void{// ...} }
Nível de classe:
#[RequiresPackage('symfony/console')]classe final DummyTest estende TestCase {public function testDummyAction(): void{// Ignorado se o symfony/console não estiver instalado.}public function testOtherDummyAction(): void{// Ignorado se o symfony/console não estiver instalado.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresPackage('symfony/console')]public function testDummyAction(): void{// Ignorado se symfony/console não estiver instalado.}public function testOtherDummyAction(): void{// Não ignorado.} }
Nível de classe:
#[RequiresPackage('symfony/*')]classe final DummyTest estende TestCase {public function testDummyAction(): void{// Ignorado se nenhum pacote symfony/* estiver instalado.}public function testOtherDummyAction(): void{// Ignorado se nenhum pacote symfony/* estiver instalado.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresPackage('symfony/*')]public function testDummyAction(): void{// Ignorado se nenhum pacote symfony/* estiver instalado.}public function testOtherDummyAction(): void{// Não ignorado.} }
Nível de classe:
#[RequiresPackage('symfony/console', '>= 7')]classe final DummyTest estende TestCase {public function testDummyAction(): void{// Ignorado se a versão instalada do symfony/console for < 7.}public function testOtherDummyAction(): void{// Ignorado se a versão instalada do symfony/console for < 7.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresPackage('symfony/console', '>= 7')]public function testDummyAction(): void{// Ignorado se a versão instalada do symfony/console for < 7.}public function testOtherDummyAction(): void{// Não ignorado.} }
Nível de classe:
#[RequiresPackage('symfony/console', mensagem: 'Este teste requer o Console Symfony.')]classe final DummyTest estende TestCase {public function testDummyAction(): void{// Ignorado se o symfony/console não estiver instalado, junto com a mensagem personalizada.}public function testOtherDummyAction(): void{// Ignorado se o symfony/console não estiver instalado, junto com a mensagem personalizada. } }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresPackage('symfony/console', message: 'Este teste requer o console Symfony.')]public function testDummyAction(): void{// Ignorado se o symfony/console não estiver instalado, junto com a mensagem personalizada.}public function testOtherDummyAction(): void{// Não ignorado.} }
Nível de classe:
#[RequiresPackage('symfony/console', resultBehavior: OutcomeBehavior::Fail)]classe final DummyTest estende TestCase {public function testDummyAction(): void{// falha se o symfony/console não estiver instalado.}public function testOtherDummyAction(): void{// falha se o symfony/console não estiver instalado.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresPackage('symfony/console', resultBehavior: OutcomeBehavior::Fail)]public function testDummyAction(): void{// Falha se symfony/console não estiver instalado.}public function testOtherDummyAction(): void{// Não falhar.} }
Nível de classe:
#[RequiresPackage('symfony/console')] #[RequiresPackage('guzzlehttp/guzzle')]classe final DummyTest estende TestCase {public function testDummyAction(): void{// Ignorado se symfony/console e/ou guzzlehttp/guzzle não estiverem instalados.}public function testOtherDummyAction(): void{// Ignorado se symfony/console e/ou guzzlehttp/guzzle não estiverem instalado.} }
Nível do método:
classe final DummyTest estende TestCase { #[RequiresPackage('symfony/console')] #[RequiresPackage('guzzlehttp/guzzle')]public function testDummyAction(): void{// Ignorado se symfony/console e/ou guzzlehttp/guzzle não estiverem instalados.}public function testOtherDummyAction(): void{// Não ignorado. } }
Por favor, dê uma olhada em CONTRIBUTING.md
.
Este projeto está licenciado sob GNU General Public License 3.0 (ou posterior).