eliashaeussler / phpunit-attributes
为PHPUnit测试提供额外的属性
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0
- phpunit/phpunit: ^10.4 || ^11.0
Requires (Dev)
- armin/editorconfig-cli: ^1.8 || ^2.0
- eliashaeussler/php-cs-fixer-config: ^2.0
- eliashaeussler/phpstan-config: ^2.5.1
- eliashaeussler/rector-config: ^3.0
- ergebnis/composer-normalize: ^2.30
- phpstan/extension-installer: ^1.2
- phpstan/phpstan-phpunit: ^1.1
- phpunit/phpcov: ^9.0 || ^10.0
- symfony/console: ^6.4 || ^7.0
This package is auto-updated.
Last update: 2024-09-22 05:07:42 UTC
README
PHPUnit属性
一个Composer库,提供了额外的属性来增强PHPUnit的测试。
🔥 安装
composer require --dev eliashaeussler/phpunit-attributes
⚡ 使用
该库附带了一个可以直接使用的PHPUnit扩展。必须在您的PHPUnit配置文件中注册
<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" > + <extensions> + <bootstrap class="EliasHaeussler\PHPUnitAttributes\PHPUnitAttributesExtension" /> + </extensions> <testsuites> <testsuite name="unit"> <directory>tests</directory> </testsuite> </testsuites> <source> <include> <directory>src</directory> </include> </source> </phpunit>
一些属性可以通过自定义扩展参数进行配置。这些必须添加到扩展注册部分,如下所示
<extensions> - <bootstrap class="EliasHaeussler\PHPUnitAttributes\PHPUnitAttributesExtension" /> + <bootstrap class="EliasHaeussler\PHPUnitAttributes\PHPUnitAttributesExtension"> + <parameter name="fancyParameterName" value="fancyParameterValue" /> + </bootstrap> </extensions>
🎢 属性
以下属性包含在这个库中
#[RequiresClass]
范围:类与方法级别
使用此属性,可以将测试或测试用例标记为仅在存在特定类时执行。给定的类必须能够被当前类加载器(通常是Composer的默认类加载器)加载。
配置
默认情况下,需要不存在类的测试用例将被跳过。但是,可以通过使用handleMissingClasses
扩展参数来配置此行为。如果设置为fail
,则缺少类的测试用例将失败(默认为skip
)
<extensions> <bootstrap class="EliasHaeussler\PHPUnitAttributes\PHPUnitAttributesExtension"> <parameter name="handleMissingClasses" value="fail" /> </bootstrap> </extensions>
示例
final class DummyTest extends TestCase { #[RequiresClass(AnImportantClass::class)] public function testDummyAction(): void { // ... } }
更多示例
需要单个类
类级别
#[RequiresClass(AnImportantClass::class)] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if AnImportantClass is missing. } public function testOtherDummyAction(): void { // Skipped if AnImportantClass is missing. } }
方法级别
final class DummyTest extends TestCase { #[RequiresClass(AnImportantClass::class)] public function testDummyAction(): void { // Skipped if AnImportantClass is missing. } public function testOtherDummyAction(): void { // Not skipped. } }
需要单个类并提供自定义消息
类级别
#[RequiresClass(AnImportantClass::class, 'This test requires the `AnImportantClass` class.')] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if AnImportantClass is missing, along with custom message. } public function testOtherDummyAction(): void { // Skipped if AnImportantClass is missing, along with custom message. } }
方法级别
final class DummyTest extends TestCase { #[RequiresClass(AnImportantClass::class, 'This test requires the `AnImportantClass` class.')] public function testDummyAction(): void { // Skipped if AnImportantClass is missing, along with custom message. } public function testOtherDummyAction(): void { // Not skipped. } }
需要单个类并定义自定义结果行为
类级别
#[RequiresClass(AnImportantClass::class, outcomeBehavior: OutcomeBehavior::Fail)] final class DummyTest extends TestCase { public function testDummyAction(): void { // Fails if AnImportantClass is missing. } public function testOtherDummyAction(): void { // Fails if AnImportantClass is missing. } }
方法级别
final class DummyTest extends TestCase { #[RequiresClass(AnImportantClass::class, outcomeBehavior: OutcomeBehavior::Fail)] public function testDummyAction(): void { // Fails if AnImportantClass is missing. } public function testOtherDummyAction(): void { // Does not fail. } }
需要多个类
类级别
#[RequiresClass(AnImportantClass::class)] #[RequiresClass(AnotherVeryImportantClass::class)] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if AnImportantClass and/or AnotherVeryImportantClass are missing. } public function testOtherDummyAction(): void { // Skipped if AnImportantClass and/or AnotherVeryImportantClass are missing. } }
方法级别
final class DummyTest extends TestCase { #[RequiresClass(AnImportantClass::class)] #[RequiresClass(AnotherVeryImportantClass::class)] public function testDummyAction(): void { // Skipped if AnImportantClass and/or AnotherVeryImportantClass are missing. } public function testOtherDummyAction(): void { // Not skipped. } }
#[RequiresPackage]
范围:类与方法级别
此属性可用于为单个测试以及完整的测试类定义特定的包要求。所需的包应通过Composer安装。您可以可选地定义版本约束和自定义消息。
重要
此属性确定已安装的Composer包来自Composer构建时生成的InstalledVersions
类。为了正确读取此类,必须在您的PHPUnit引导脚本中包含Composer生成的自动加载器
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" > <!-- ... --> </phpunit>
您还可以将脚本作为命令选项传递:phpunit --bootstrap vendor/autoload.php
配置
默认情况下,不满足要求的测试用例将被跳过。但是,可以通过使用handleUnsatisfiedPackageRequirements
扩展参数来配置此行为。如果设置为fail
,则不满足要求的测试用例将失败(默认为skip
)
<extensions> <bootstrap class="EliasHaeussler\PHPUnitAttributes\PHPUnitAttributesExtension"> <parameter name="handleUnsatisfiedPackageRequirements" value="fail" /> </bootstrap> </extensions>
示例
final class DummyTest extends TestCase { #[RequiresPackage('symfony/console')] public function testDummyAction(): void { // ... } }
更多示例
需要显式的Composer包
类级别
#[RequiresPackage('symfony/console')] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if symfony/console is not installed. } public function testOtherDummyAction(): void { // Skipped if symfony/console is not installed. } }
方法级别
final class DummyTest extends TestCase { #[RequiresPackage('symfony/console')] public function testDummyAction(): void { // Skipped if symfony/console is not installed. } public function testOtherDummyAction(): void { // Not skipped. } }
需要匹配给定模式的任何Composer包
类级别
#[RequiresPackage('symfony/*')] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if no symfony/* packages are installed. } public function testOtherDummyAction(): void { // Skipped if no symfony/* packages are installed. } }
方法级别
final class DummyTest extends TestCase { #[RequiresPackage('symfony/*')] public function testDummyAction(): void { // Skipped if no symfony/* packages are installed. } public function testOtherDummyAction(): void { // Not skipped. } }
需要具有给定版本约束的Composer包
类级别
#[RequiresPackage('symfony/console', '>= 7')] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if installed version of symfony/console is < 7. } public function testOtherDummyAction(): void { // Skipped if installed version of symfony/console is < 7. } }
方法级别
final class DummyTest extends TestCase { #[RequiresPackage('symfony/console', '>= 7')] public function testDummyAction(): void { // Skipped if installed version of symfony/console is < 7. } public function testOtherDummyAction(): void { // Not skipped. } }
需要Composer包并提供自定义消息
类级别
#[RequiresPackage('symfony/console', message: 'This test requires the Symfony Console.')] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if symfony/console is not installed, along with custom message. } public function testOtherDummyAction(): void { // Skipped if symfony/console is not installed, along with custom message. } }
方法级别
final class DummyTest extends TestCase { #[RequiresPackage('symfony/console', message: 'This test requires the Symfony Console.')] public function testDummyAction(): void { // Skipped if symfony/console is not installed, along with custom message. } public function testOtherDummyAction(): void { // Not skipped. } }
需要Composer包并定义自定义结果行为
类级别
#[RequiresPackage('symfony/console', outcomeBehavior: OutcomeBehavior::Fail)] final class DummyTest extends TestCase { public function testDummyAction(): void { // Fails if symfony/console is not installed. } public function testOtherDummyAction(): void { // Fails if symfony/console is not installed. } }
方法级别
final class DummyTest extends TestCase { #[RequiresPackage('symfony/console', outcomeBehavior: OutcomeBehavior::Fail)] public function testDummyAction(): void { // Fails if symfony/console is not installed. } public function testOtherDummyAction(): void { // Does not fail. } }
多个要求
类级别
#[RequiresPackage('symfony/console')] #[RequiresPackage('guzzlehttp/guzzle')] final class DummyTest extends TestCase { public function testDummyAction(): void { // Skipped if symfony/console and/or guzzlehttp/guzzle are not installed. } public function testOtherDummyAction(): void { // Skipped if symfony/console and/or guzzlehttp/guzzle are not installed. } }
方法级别
final class DummyTest extends TestCase { #[RequiresPackage('symfony/console')] #[RequiresPackage('guzzlehttp/guzzle')] public function testDummyAction(): void { // Skipped if symfony/console and/or guzzlehttp/guzzle are not installed. } public function testOtherDummyAction(): void { // Not skipped. } }
🧑💻 贡献
请参阅CONTRIBUTING.md
。
⭐ 许可证
本项目采用GNU通用公共许可证3.0(或更新版)授权。