ksamborski/php-integration

0.9.4 2017-09-29 07:46 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:47:33 UTC


README

PHP库,用于编写自动化测试。它可以帮助你开始,尤其是在你进行TDD并且重视随机测试时。

Build Status

安装

composer install ksamborski/php-integration

基本用法

你编写测试。这很酷。当你编写使用随机数据的测试时,那就更酷了。但如果你的测试发现了一个错误呢?你修复它并再次尝试,但测试是随机的,你不能简单地重新运行它。你需要更改测试代码,运行它,当一切正常时,希望不要忘记在测试代码中删除你的更改。你也可以使用这个库。

首先,让我们定义一些测试

use PHPIntegration\TestParameter;
use PHPIntegration\Test;
use PHPIntegration\TestGroup;
use PHPIntegration\Console;

$groups = [
    new TestGroup(
        "Basic tests",
        [
            new Test(
                "Test1",
                "Simple test 1",
                function ($p) {
                    usleep(rand(10000, 100000));
                    return true;
                }
            ),
            new Test(
                "Test2",
                "Failing test",
                function ($p) {
                    return "this is a test that always fails";
                }
            )
        ]
    )
];

测试是一个简单的对象,它有一个名称、一个描述和一个接收参数的函数。现在不用担心它,我们稍后会讨论。这个函数是你的测试,它应该在一切正常时返回true,否则返回一些解释错误的消息。

现在为了避免在测试失败时更改测试代码,让我们引入动态参数

$params = function() {
    return [
        TestParameter::manyFromParameter("departments", ["Warsaw", "Berlin"], ["Warsaw", "Berlin", "Cracow"]),
        TestParameter::stringParameter("currency", "PLN"),
        TestParameter::regexParameter("date", "2015-01-01", "/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/"),
        TestParameter::arrayOfParameter("hours", [12], '\PHPIntegration\TestParameter::intParameter')
    ];
};

这些参数当然是对象。根据你的需求,你可以定义一个字符串参数、正则表达式参数、预定义值的参数等,或者自定义参数。参数通常需要一个名称和默认值。这个默认值可以在运行时被覆盖。我稍后会展示。

有一件事是缺少的,那就是控制台。我们需要初始化控制台接口(CLI)来获得使用它的某种方式。

Console::main($groups, $params);

它接受两个参数:测试数组和一个生成动态参数的函数。在后一种情况下,因为它需要在每次迭代后重新随机化它们,所以在运行某些测试n次时需要这个函数。

现在让我们运行它

php basic_example.php

Basic tests [pre] [ OK ] 
>> Test1 [ OK ] 48.12 ms
>> Test2 [ FAILED ] 0.00 ms
Test description: 
Failing test
Parameters: 
- departments:[Warsaw,Berlin]
- currency:PLN
- date:2015-01-01
- hours:[12]
Message: 
this is a test that always fails
Basic tests [post] [ OK ] 

现在让我们覆盖一些参数

php basic_example.php -p "currency:EUR"
Basic tests [pre] [ OK ] 
>> Test1 [ OK ] 24.58 ms
>> Test2 [ FAILED ] 0.00 ms
Test description: 
Failing test
Parameters: 
- departments:[Warsaw,Berlin]
- currency:EUR
- date:2015-01-01
- hours:[12]
Message: 
this is a test that always fails
Basic tests [post] [ OK ] 

OK,但如何在测试中使用它们?还记得我们之前定义的测试中的$p参数吗?那就是参数映射。例如,要读取货币,你可以写

new Test(
        "Test1",
        "Simple test 1",
        function($p) {
            return $p['currency'];
        }
    )

如果我们忘记了可以传递哪些参数怎么办?CLI就是救星!

php basic_example.php -h
Usage: php basic_example.php [OPTIONS]

  -g, --group GROUP_NAME 				 Run only tests from given groups (you can pass multiple -g option) 
  -t, --test TEST_NAME 					 Run only given tests (you can pass multiple -t option) 
  -p, --parameter PARAMETER_NAME:PARAMETER_VALUE 	 Set test parameter (you can pass multiple -p option) 
  -n 							 Number of repeats 

  -h, --help 						 Show this help

Available tests:
- Basic tests: 
  - Test1: Simple test 1
  - Test2: Failing test

Available parameters:
- departments 
  Default: [Warsaw,Berlin]
- currency 
  Default: PLN
- date 
  Default: 2015-01-01
- hours 
  Default: [12]

正如你所见,我们可以做很多事情。这不是很棒吗?

随机

接下来,我们应该看看examples目录中的random_example.php。让我们看看参数

use PHPIntegration\Utils\RandomHelper;

$params = function() {
    return [
        TestParameter::manyFromParameter(
            "departments",
            RandomHelper::randomArray(["Warsaw", "Berlin", "Cracow"], false),
            ["Warsaw", "Berlin", "Cracow"]
        ),
        TestParameter::stringParameter("currency", RandomHelper::randomString(3)),
        TestParameter::arrayOfParameter(
            "hours",
            RandomHelper::randomMany(function() { return rand(1,24); },1),
            '\PHPIntegration\TestParameter::intParameter'
        )
    ];
};

你可以看到相同的TestParameter类,但还有一个RandomHelper。它包含许多用于生成随机数据的有用函数。例如,randomArray函数只是从提供的列表中生成包含随机元素的数组。最后一个参数决定它是否可以包含重复值。当然,你可以使用randomString函数生成随机字符串,使用randomMany生成随机数组。

但真正美丽的是CLI

Random tests [pre] [ OK ] 
>> Test1 4/100 [ FAILED ] 0.00 ms
Test description: 
Warsaw test
Parameters: 
- departments:[]
- currency:b X
- hours:[14,12]
Message: 
this test succeeds only if Warsaw is passed
>> Test2 1/100 [ FAILED ] 20.10 ms > 10 ms limit
Test description: 
Failing test
Parameters: 
- departments:[Cracow,Warsaw,Berlin]
- currency:Mwy
- hours:[6,18,13,2]
Message: 
this is a test that always fails
Random tests [post] [ OK ] 

脚本中的n参数告诉它重复执行每个测试n次。每次失败时,它停止重复并转到下一个测试。你可以在第二个测试用例中看到“> 10 ms限制”。这是因为它设置了测试时间限制。你可以通过向Test类提供第三个参数来完成此操作

    new Test(
        "Test2",
        "Failing test",
        function($p) {
            usleep(20000);
            return "this is a test that always fails";
        },
        10
    )

10表示测试应该在10毫秒内完成。你可以在测试中测量其他东西。测试函数的参数是一个参数数组和一个特殊的功能调用measure。请参阅examples/measurement_example.php

作为参数的对象

到目前为止,我们只定义了字符串、整型和数组参数。但我们可以做得更好。我们可以定义对象!不幸的是,为了做到这一点,我们需要实现一个接口。请查看示例目录中的object_example.php。

use PHPIntegration\Testable;
use PHPIntegration\Utils\RandomHelper;
use PHPIntegration\Randomizable;

class TestObject implements Randomizable, Testable
{
    public $name;

    public function __construct(string $name)
    {
        $this->name = $name;
    }

    public static function build(string $value) : Testable
    {
        return new TestObject($value);
    }

    public static function validate(string $value, bool $valid = true)
    {
        $fstLetter = substr($value, 0, 1);
        if ($valid === true) {
            if (strtolower($fstLetter) == $fstLetter) {
                return "Value must start from upper case.\n";
            } else {
                return true;
            }
        } else {
            if (strtolower($fstLetter) == $fstLetter) {
                return true;
            } else {
                return "Value must not start from upper case.\n";
            }
        }
    }

    public function asStringParameter() : string
    {
        return $this->name;
    }

    public static function randomValid()
    {
        return new TestObject(strtoupper(RandomHelper::randomString()));
    }

    public static function randomInvalid()
    {
        return new TestObject(strtolower(RandomHelper::randomString()));
    }
}

要使用对象作为参数,我们只需要实现Testable接口。要使其随机化,我们还需要实现Randomizable接口。Testable接口中有3个方法:build、validate和asStringParameter。build方法很简单,它只接受用户在-p选项中写入的任何内容,并必须从中创建一个对象。validate方法在它之前执行,以确保这个字符串有意义。如果没有,CLI将显示错误。而asStringParameter在测试失败时用于显示用户可以再次传递的参数值(当对象未提供但随机化时很有用)。

php object_example.php -p "first name:john"    
Bad param `first name` value `john`
Value must start from upper case.

Randomizable接口要简单得多。只有2个方法。一个用于生成具有有效数据的对象。例如,当它是一个数据库连接字符串时,它会指向现有的数据库。另一个用于无效数据(例如,指向不存在的数据库的连接字符串)。

您可以使用RandomHelper类中的randomObject方法随机化对象。要将对象用作参数,您需要使用TestParameter类中的objectParameter方法。

其他事项

您绝对应该检查示例文件夹。