Une bibliothèque Composer avec des attributs supplémentaires pour améliorer les tests avec PHPUnit.
composer require --dev eliashaeussler/phpunit-attributes
La bibliothèque est livrée avec une extension PHPUnit prête à l'emploi. Il doit être enregistré dans votre fichier de configuration PHPUnit :
<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="fournisseur/phpunit/phpunit/phpunit.xsd" bootstrap="vendeur/autoload.php" >+ <extensions>+ <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension" />+ </extensions> <testsuites> <nom de la suite de tests="unité"> <répertoire>tests</répertoire> </suite de tests> </suites de tests> <source> <inclure> <répertoire>src</répertoire> </include> </source> </phpunité>
Certains attributs peuvent être configurés avec des paramètres d'extension personnalisés. Ceux-ci doivent être ajoutés à la section d’enregistrement de l’extension comme suit :
<extensions>- <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension" />+ <bootstrap class="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension">+ <parameter name="fancyParameterName" value="fancyParameterValue" />+ </bootstrap> </extensions>
Les attributs suivants sont fournis avec cette bibliothèque :
#[RequiresClass]
#[RequiresPackage]
#[RequiresClass]
Portée : niveau classe et méthode
Avec cet attribut, les tests ou scénarios de test peuvent être marqués comme étant exécutés uniquement si une certaine classe existe. La classe donnée doit pouvoir être chargée par le chargeur de classe actuel (qui est normalement le chargeur de classe par défaut de Composer).
Par défaut, les cas de tests nécessitant des classes inexistantes sont ignorés. Toutefois, ce comportement peut être configuré à l'aide du paramètre d'extension handleMissingClasses
. S'il est défini sur fail
, les cas de test avec des classes manquantes échoueront (par défaut sur skip
) :
<extensions> <classe bootstrap="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension"> <parameter name="handleMissingClasses" value="fail" /> </bootstrap> </extensions>
la classe finale DummyTest étend TestCase { #[RequiresClass(AnImportantClass::class)]fonction publique testDummyAction() : void{// ...} }
Niveau de classe :
#[RequiresClass(AnImportantClass::class)]la classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si AnImportantClass est manquant.}public function testOtherDummyAction() : void{// Ignoré si AnImportantClass est manquant.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresClass(AnImportantClass::class)]public function testDummyAction(): void{// Ignoré si AnImportantClass est manquant.}public function testOtherDummyAction(): void{// Non ignoré.} }
Niveau de classe :
#[RequiresClass(AnImportantClass::class, 'Ce test nécessite la classe `AnImportantClass`.')]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si AnImportantClass est manquant, ainsi qu'un message personnalisé.}public function testOtherDummyAction() : void{// Ignoré si AnImportantClass est manquant, ainsi qu'un message personnalisé.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresClass(AnImportantClass::class, 'Ce test nécessite la classe `AnImportantClass`.')]fonction publique testDummyAction() : void{// Ignorée si AnImportantClass est manquant, ainsi qu'un message personnalisé.}fonction publique testOtherDummyAction() : void{// Non ignoré.} }
Niveau de classe :
#[RequiresClass(AnImportantClass::class, resultBehavior: OutcomeBehavior::Fail)]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// échoue si AnImportantClass est manquant.}public function testOtherDummyAction() : void{// échoue si AnImportantClass est manquant.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresClass(AnImportantClass::class, resultBehavior: OutcomeBehavior::Fail)]public function testDummyAction(): void{// Échoue si AnImportantClass est manquant.}public function testOtherDummyAction(): void{// N'échoue pas.} }
Niveau de classe :
#[RequiresClass(AnImportantClass::class)] #[RequiresClass(AnotherVeryImportantClass::class)]la classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si AnImportantClass et/ou AnotherVeryImportantClass sont manquants.}public function testOtherDummyAction() : void{// Ignoré si AnImportantClass et/ou AnotherVeryImportantClass sont manquants.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresClass(AnImportantClass::class)] #[RequiresClass(AnotherVeryImportantClass::class)]public function testDummyAction(): void{// Ignoré si AnImportantClass et/ou AnotherVeryImportantClass sont manquants.}public function testOtherDummyAction(): void{// Non ignoré.} }
#[RequiresPackage]
Portée : niveau classe et méthode
Cet attribut peut être utilisé pour définir des exigences de package spécifiques pour des tests uniques ainsi que pour des classes de tests complètes. Un package requis devrait être installé via Composer. Vous pouvez éventuellement définir une contrainte de version et un message personnalisé.
Important
L'attribut détermine les packages Composer installés à partir de la classe InstalledVersions
générée au moment de la génération et créée par Composer. Afin de lire correctement cette classe, il est essentiel d'inclure le chargeur automatique généré par Composer dans votre script d'amorçage PHPUnit :
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php"><! -- ... --></phpunit>
Vous pouvez également passer le script comme option de commande : phpunit --bootstrap vendor/autoload.php
Par défaut, les cas de test dont les exigences ne sont pas satisfaites sont ignorés. Toutefois, ce comportement peut être configuré à l'aide du paramètre d'extension handleUnsatisfiedPackageRequirements
. S'il est défini sur fail
, les cas de test dont les exigences ne sont pas satisfaites échoueront (par défaut, skip
) :
<extensions> <classe bootstrap="EliasHaeusslerPHPUnitAttributesPHPUnitAttributesExtension"> <parameter name="handleUnsatisfiedPackageRequirements" value="fail" /> </bootstrap> </extensions>
la classe finale DummyTest étend TestCase { #[RequiresPackage('symfony/console')]fonction publique testDummyAction() : void{// ...} }
Niveau de classe :
#[RequiresPackage('symfony/console')]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si symfony/console n'est pas installé.}public function testOtherDummyAction() : void{// Ignoré si symfony/console n'est pas installé.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresPackage('symfony/console')]public function testDummyAction(): void{// Ignoré si symfony/console n'est pas installé.}public function testOtherDummyAction(): void{// Non ignoré.} }
Niveau de classe :
#[RequiresPackage('symfony/*')]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si aucun package symfony/* n'est installé.}public function testOtherDummyAction() : void{// Ignoré si aucun package symfony/* n'est installé.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresPackage('symfony/*')]public function testDummyAction(): void{// Ignoré si aucun package symfony/* n'est installé.}public function testOtherDummyAction(): void{// Non ignoré.} }
Niveau de classe :
#[RequiresPackage('symfony/console', '>= 7')]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si la version installée de symfony/console est < 7.}public function testOtherDummyAction() : void{// Ignoré si la version installée de symfony/console est < 7.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresPackage('symfony/console', '>= 7')]public function testDummyAction(): void{// Ignoré si la version installée de symfony/console est < 7.}public function testOtherDummyAction(): void{// Pas ignoré.} }
Niveau de classe :
#[RequiresPackage('symfony/console', message : 'Ce test nécessite la console Symfony.')]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si symfony/console n'est pas installé, avec un message personnalisé.}public function testOtherDummyAction() : void{// Ignoré si symfony/console n'est pas installé, avec un message personnalisé. } }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresPackage('symfony/console', message : 'Ce test nécessite la console Symfony.')]fonction publique testDummyAction(): void{// Ignoré si symfony/console n'est pas installé, avec message personnalisé.}fonction publique testOtherDummyAction() : void{// Non ignoré.} }
Niveau de classe :
#[RequiresPackage('symfony/console', resultBehavior: OutcomeBehavior::Fail)]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// échoue si symfony/console n'est pas installé.}public function testOtherDummyAction() : void{// échoue si symfony/console n'est pas installé.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresPackage('symfony/console', resultBehavior: OutcomeBehavior::Fail)]public function testDummyAction(): void{// Échoue si symfony/console n'est pas installé.}public function testOtherDummyAction(): void{// Ne fonctionne pas échouer.} }
Niveau de classe :
#[RequiresPackage('symfony/console')] #[RequiresPackage('guzzlehttp/guzzle')]classe finale DummyTest étend TestCase {public function testDummyAction() : void{// Ignoré si symfony/console et/ou guzzlehttp/guzzle ne sont pas installés.}public function testOtherDummyAction(): void{// Ignoré si symfony/console et/ou guzzlehttp/guzzle ne le sont pas installé.} }
Niveau méthode :
la classe finale DummyTest étend TestCase { #[RequiresPackage('symfony/console')] #[RequiresPackage('guzzlehttp/guzzle')]public function testDummyAction(): void{// Ignoré si symfony/console et/ou guzzlehttp/guzzle ne sont pas installés.}public function testOtherDummyAction(): void{// Non ignoré. } }
Veuillez jeter un oeil à CONTRIBUTING.md
.
Ce projet est sous licence GNU General Public License 3.0 (ou version ultérieure).