radziuk / php-tt
Docblock 单元测试库,在您的文档块中直接对类进行单元测试
Requires
- nikic/php-parser: ^5.0
- php-di/php-di: ^7.0
README
安装包
composer require --dev radziuk/php-tt
运行测试
php vendor/radziuk/php-tt/bin/run.php
使用 Laravel 集成运行器
php vendor/radziuk/php-tt/bin/lararun.php
指定文件夹
默认情况下,运行器使用 "app" 文件夹查找测试。您可以指定一个自定义文件夹
php vendor/radziuk/php-tt/bin/run.php src/lib
自测包
包安装后,您可以运行包中包含的自测脚本
php vendor/radziuk/php-tt/bin/selftest.php
应输入类似以下内容
Info: Assertions done: 89
Info: Assertions true: 89
测试示例
简单测试,将 "hello" 传递给函数,应返回 "hello"
/** * @php-tt-assert "hello" >>> "hello" */ public function replaceMarkers(string $string): string
文本示例 #2
/** * @php-tt-assert "'hello', 'world'" >>> "#1, #2" */ public function replaceMarkers(string $string): string
文本示例 #3
/** * @php-tt-assert "'hello', 'world'", 1 >>> "#1, 'world'" */ public function replaceMarkers(string $string, int $count): string
文本示例 #4,传递一个数组
/** * @php-tt-assert "'hello', 'world'", ['hello' => 'world'] >>> "#1, 'world'" */ public function replaceMarkers(string $string, array $data): string
文本示例 #5,在测试之前调用对象的方法
/** * @php-tt-before $object->setPattern('#%s') * @php-tt-assert "'hello', 'world'", ['hello' => 'world'] >>> "#1, 'world'" */ public function replaceMarkers(string $string, array $data): string
文本示例 #6,模拟 $this->... 方法
/** * @php-tt-mock $this->getFilenameFromDatasource >>> 'test.php' * @php-tt-assert 'Any.key', 'default' >>> ['default/test.php'] */ private function getFileForDataSource(string $dataSource, string $methodName): array { $dataDir = $this->getDataDirForMethod($methodName); $fileName = $this->getFilenameFromDatasource($dataSource); $file = $dataDir . '/' . $fileName; return [$file]; }
文本示例 #7,模拟依赖项的方法
/** * @php-tt-mock $this->service->getFilenameFromDatasource >>> 'test.php' * @php-tt-assert 'Any.key', 'default' >>> ['default/test.php'] */ private function getFileForDataSource(string $dataSource, string $methodName): array { $dataDir = $this->getDataDirForMethod($methodName); $fileName = $this->service->getFilenameFromDatasource($dataSource); $file = $dataDir . '/' . $fileName; return [$file]; }
文本示例 #8,模拟全局函数和方法
/** * @php-tt-mock $service->getFilenameFromDatasource >>> 'test.php' * @php-tt-mock getDataDirForMethod >>> 'default' * @php-tt-assert 'Any.key', 'default' >>> ['default/test.php'] */ private function getFileForDataSource(string $dataSource, string $methodName): array { $dataDir = getDataDirForMethod($methodName); $fileName = $service->getFilenameFromDatasource($dataSource); $file = $dataDir . '/' . $fileName; return [$file]; }
文本示例 #9,模拟属性
/** * @php-tt-mock @$service->getFilenameFromDatasource >>> 'test.php' * @php-tt-mock $this->data_dir >>> '/var/www' * @php-tt-assert 'Any.key', 'default' >>> ['/var/www/test.php'] */ private function getFileForDataSource(string $dataSource, string $methodName): array { $dataDir = $this->data_dir; $fileName = $service->getFilenameFromDatasource($dataSource); $file = $dataDir . '/' . $fileName; return [$file]; }
文本示例 #10,模拟任何内容
/** * @php-tt-mock self::getFilenameFromDatasource >>> 'test.php' * @php-tt-exact-mock require $methodName >>> '/var/www' * @php-tt-assert 'Any.key', 'default' >>> ['/var/www/test.php'] */ private function getFileForDataSource(string $dataSource, string $methodName): array { $dataDir = require $methodName; $fileName = self::getFilenameFromDatasource($dataSource); $file = $dataDir . '/' . $fileName; return [$file]; }
在单独的文件中定义您的测试数据
默认情况下,运行器正在查找 tests/php-tt-data 文件夹,因此您可以在那里创建您的数据文件
创建数据文件
touch tests/php-tt-data/TestData.php
在您的数据文件中
<?php return [ 'getFileForDataSource' => [ 0 => [ ['DoTest.test', 'methodName'],//parameters as array 'test',//expected result ], 1 => [ ['DoTest', 'methodName'], 'methodName' ] ], ];
在您的类中
/** * @php-tt-mock @self::getFilenameFromDatasource >>> 'test.php' * @php-tt-exact-mock require $methodName >>> '/var/www' * @php-tt-data TestData */ private function getFileForDataSource(string $dataSource, string $methodName): array
在您的数据文件中使用自定义键。默认键是方法名称。
在您的数据文件中
<?php return [ '__my_custom_key__' => [ 0 => [ ['DoTest.test', 'methodName'],//parameters as array 'test',//expected result ], 1 => [ ['DoTest', 'methodName'], 'methodName' ] ], ];
在您的类中
/** * @php-tt-mock self::getFilenameFromDatasource >>> 'test.php' * @php-tt-exact-mock require $methodName >>> '/var/www' * @php-tt-data TestData.__my_custom_key__ */ private function getFileForDataSource(string $dataSource, string $methodName): array
使用数据文件创建模拟
在您的类中
/** * @php-tt-mock self::getFilenameFromDatasource >>> 'test.php' * @php-tt-exact-mock require $methodName >>> #TestData.my_mock * @php-tt-data TestData */ private function getFileForDataSource(string $dataSource, string $methodName): array
在您的数据文件中
<?php return [ 'my_mock' => (function(){ return 'hello'; })(), ];
其他断言
断言异常。
此断言表示方法将抛出任何异常
/** * @php-tt-assert-exception "'hello', 'world'" */ public function replaceMarkers(string $string): string
此断言表示方法将抛出特定类的异常
/** * @php-tt-assert-exception "'hello', 'world'" >>> \App\My\Exception::class */ public function replaceMarkers(string $string): string
断言异常包含
此断言表示方法将抛出异常,并且消息将包含文本
/** * @php-tt-assert-exception-contains "'hello', 'world'" >>> "My error text" */ public function replaceMarkers(string $string): string
断言包含 & preg
此断言表示结果将包含指定的子字符串
/** * @php-tt-assert-contains "'hello', 'world'" >>> "My error text" */ public function replaceMarkers(string $string): string
此断言表示结果将匹配指定的正则表达式
/** * @php-tt-assert-preg "'hello', 'world'" >>> "/^.*$/" */ public function replaceMarkers(string $string): string
断言可调用
此断言允许您定义一个可调用的函数来处理方法执行的输出并与预期结果进行比较
/** * @php-tt-assert-callable "hello, world" >>> [#TestData.my_callable, 'expected result'] */ public function replaceMarkers(string $string): string
在您的 tests/php-tt-data/TestData.php 文件中
return [ 'my_callable' => function(stdClass $result, $expected):bool { return $result->property === $expected; }, ];
传递更多参数
/** * @php-tt-assert-callable "hello, world" >>> [#TestData.my_callable, 'expected result', false] */ public function replaceMarkers(string $string): string
在您的 tests/php-tt-data/TestData.php 文件中
return [ 'my_callable' => function(stdClass $result, $expected, $true = true):bool { return $true ? $result->property === $expected : $result->property !== $expected; }, ];
创建别名
/** * @php-tt-alias "property-equals" >>> #TestData.property_equals * @php-tt-alias "property-not-equals" >>> #TestData.property_not_equals * use your aliases * @php-tt-assert-property-equals 'parameter' >>> 'expected' * @php-tt-assert-property-not-equals 'parameter' >>> 'expected' */ public function replaceMarkers(string $string): string
在您的 tests/php-tt-data/TestData.php 文件中
return [ 'property_equals' => function(stdClass $result, $expected):bool { return $result->property === $expected; }, 'property_not_equals' => function(stdClass $result, $expected):bool { return $result->property !== $expected; }, ];
使用自定义数据文件夹
php vendor/radziuk/php-tt/bin/run.php app tests/my-folder
增加输出详细程度
php vendor/radziuk/php-tt/bin/run.php 3
任何一位数都被解释为详细程度。您可以像以下那样指定自定义文件夹和详细程度
php vendor/radziuk/php-tt/bin/run.php custom/app 3
php vendor/radziuk/php-tt/bin/run.php custom/app custom/data 3
创建您自己的自定义运行器
touch testrunner.php
<?php require __DIR__.'/vendor/autoload.php'; $tt = new \Aradziuk\PhpTT\Tt(); $tt->run( __DIR__ . '/app', //dir with your classes __DIR__ . '/test/php-tt' // dir with your data );
特性支持
从版本 0.3 开始,添加了对特性的支持。在测试期间,初始化一个实现特性的匿名类。要覆盖此默认行为,您可以使用 @php-tt-use-class
trait MyTrait { /** * @php-tt-use-class My\Namespace\CustomClass * the above command will tell php-tt to use the object of My\Namespace\CustomClass for testing this method. The class should use the trait * @php-tt-assert "#1, #2" >>> 'hello, world' */ public function replaceMarkers(string $string): string
Laravel 集成
lararun.php
lararun.php 在没有数据库、日志和其他提供者的情况下启动 Laravel,因此您的测试可以访问大量的 Laravel 功能,例如门面、各种提供者等。请注意,目前 lararun.php 处于 alpha 版本,强烈建议模拟所有可能对您的数据造成永久更改的代码
php vendor/radziuk/php-tt/bin/lararun.php
创建您的自定义 Laravel 命令
php artisan make:command PhpTT
在 app/Console/Commands/PhpTT.php 中
$tt = new \Radziuk\PhpTT\Tt(); $tt->setOutputCallback('info', function (string $string) { $this->info($string); })->setOutputCallback('error', function (string $string){ $this->error($string); })->setOutputCallback('alert', function (string $string){ $this->alert($string); }); // use artisan generic out put $tt->run( app_path(), base_path('tests/php-tt-data') );
在 app/Console/Kernel.php 中
protected $commands = [ PhpTT::class, ];
php artisan app:php-tt
创建您的自定义断言(与别名相同)
\Radziuk\PhpTT\Tt::enhance('greater-than', function(\ReflectionMethod $method, $object, array $params, $expected): array { $result = $method->invoke($object, ...$params); return [$result > $expected, $result]; });
在您的测试中
/** * @php-tt-assert-greater-than 2, 2 >>> 3 */ public function multiply(int $x, int $y): int