jlippitt/tusk

该软件包已被废弃且不再维护。未建议替代软件包。

适用于大象的PHP测试框架

0.2 2014-04-27 07:32 UTC

This package is not auto-updated.

Last update: 2020-04-03 16:21:42 UTC


README

适用于大象的PHP测试框架

基础

tusk 是一个类似于 Jasmine (JavaScript) 或 RSpec (Ruby) 的行为驱动开发 (BDD) 框架风格的 PHP 测试框架。

每个 spec 都由测试文件中的 it 块表示。使用 describe 块将多个 spec 组合成一个 suite。可以根据需要将 describe 块嵌套到任意深度。

在每个 spec 内部,使用 expect 创建必须满足以通过测试的 expectations

典型示例

describe('Bowling', function() {
    describe('getScore()', function() {
        it('returns 0 for an all gutter game', function() {
            $bowling = new Bowling();
            
            for ($i = 0; $i < 10; ++$i) {
                $bowling->hit(0);
            }
            
            expect($bowling->getScore())->toBe(0);
        });
    });
});

设置和清理

通常你会在每个 spec 之前或之后运行一些代码。这可以通过使用 beforeEachafterEach 块来实现。

describe('My Test Suite', function() {
    beforeEach(function() {
        echo "This will run before each spec\n";
    });
    
    afterEach(function() {
        echo "This will run after each spec\n"
    });
    
    // ...
});

在外部 describe 块上定义的钩子也将运行在嵌套的任何 describe 块内部的每个 spec 之前/之后。

变量作用域

PHP 的闭包(匿名函数)有一个奇怪的特性,即如果你想在闭包中捕获外部作用域中的任何变量,你必须使用 use 关键字显式地告诉 PHP。

鉴于我们对匿名函数的广泛使用,这可能会变得相当繁琐。

describe('Bowling', function() {
    $bowling = null;
    
    beforeEach(function() use (&$bowling) {
        $bowling = new Bowling();
    });
    
    describe('getScore()', function() use (&$bowling) {
        it('returns 0 for an all gutter game', function() use (&$bowling) {
            for ($i = 0; $i < 10; ++$i) {
                $bowling->hit(0);
            }
            
            expect($bowling->getScore())->toBe(0);
        });
    });
});

然而,从 PHP 5.4 开始,可以在闭包中将 '$this' 变量绑定到任意值。tusk 充分利用了这一点,并且一切如你所愿。

describe('Bowling', function() {
    beforeEach(function() {
        $this->bowling = new Bowling();
    });
    
    describe('getScore()', function() {
        it('returns 0 for an all gutter game', function() {
            for ($i = 0; $i < 10; ++$i) {
                $this->bowling->hit(0);
            }
            
            expect($this->bowling->getScore())->toBe(0);
        });
    });
});

Expectations 和 Matchers

Expectations 提供了许多内置的 matchers

  • toBe(expectedValue) 使用 === 运算符比较值

  • toEqual(expectedValue) 使用 == 运算符比较值

  • toBeGreaterThan(expectedValue) 使用 > 运算符比较值

  • toBeGreaterThanOrEqualTo(expectedValue) 使用 >= 运算符比较值

  • toBeLessThan(expectedValue) 使用 < 运算符比较值

  • toBeLessThanOrEqualTo(expectedValue) 使用 <= 运算符比较值

  • toBeTruthy() 测试值根据 布尔转换规则 是“真”的

  • toBeFalsy() 测试值根据 布尔转换规则 是“假”的

  • toContain(expectedValue) 测试数组是否包含给定值。这使用了内部的 in_array 函数。

  • toMatch(regex) 测试字符串值是否与给定的正则表达式匹配。请参阅 preg_match

  • toBeType(type) 测试值是否匹配给定的内部类型。请参阅 gettype

  • toBeInstanceOf(className) 测试值是否为给定类或接口的实例

  • toThrow([className[, message]) 测试在运行时闭包(匿名函数)是否会抛出异常。如果提供异常类和错误信息,则这些也必须匹配,以便期望成功。

所有期望都可以通过将 to 改为 notTo 来否定,例如 toBe 变为 notToBe,而 toEqual 变为 notToEqual

定义自定义匹配器

可以通过将它们添加到内部的 ExpectationFactory 类中来定义自定义匹配器,这将使它们在您的规格中的所有期望中可用。为此,您需要首先从 Pimple 依赖注入容器中检索 ExpectationFactory,然后为要添加的每个匹配器调用 addMatch 方法。

<?php

use Tusk\Container;
use Tusk\Matcher;

$expectationFactory = Container::getInstance()['ExpectationFactory'];

$expectationFactory->addMatcher(
    'toBeDivisibleBy',
    new Matcher(
        function($value, $divisor) {
            return $value % $divisor === 0;
        },
        'to be divisible by {0}'
    )
);

匹配器函数可以接受任意数量的参数,尽管第一个参数始终是在创建期望时传递给 expect 函数的值。其余参数将作为匹配器方法本身提供的参数。

匹配器对象的第二个参数确定当匹配器不成功时将显示给用户的消息。可以使用 {0}、{1}、{2} 等(其中数字是它们在参数列表中的零索引位置)将传递给匹配器方法的任何参数插入到此字符串中。

许可证

tusk 采用 MIT 许可证发布。有关更多详细信息,请参阅 LICENSE 文件。