radziuk/php-tt

Docblock 单元测试库,在您的文档块中直接对类进行单元测试

0.3.0 2024-03-04 16:06 UTC

This package is not auto-updated.

Last update: 2024-09-30 18:46:47 UTC


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