szuhiko / spec-php
这是基于 Spec-PHP 的分支,支持 RSpec2 语法和 composer。
Requires
- php: >=5.3.2
- hamcrest/hamcrest-php: 1.1.*
- pear/console_commandline: dev-trunk@dev
- phpunit/phpunit: 3.7.*
This package is auto-updated.
Last update: 2024-09-26 16:35:19 UTC
README
Spec for PHP 是一个用于实现行为驱动开发规范文件的工具。它受到 Ruby 世界中 RSpec 的启发。
它建立在 PHPUnit 和 Hamcrest 项目之上,提供成熟和稳定的特性,并借鉴了这些项目的当前行业支持。
实现 Spec 的目的是将常规 PHP 代码和更自然的语言语法混合起来,以表达期望。用纯 PHP 编写测试代码很好,因为这就是你将在你的应用程序和 IDE 中使用它的方式,而 IDE 为它提供了自动完成功能。然而,使用 PHP 语法表达断言既困难又难以阅读,因此用不同的方式编写它们是有意义的。
为了能够解析 Spec 的语法,有一个即时转换,它生成有效的 PHP 代码。代码生成有其缺点,特别是当需要调试问题时,源文件和执行文件是不同的,这使得了解发生了什么变得像是一场噩梦。Spec 考虑了这一点,并会尽可能生成保持原始行号相同的代码。这非常有帮助,因为你可以转到异常中报告的行号,并实际上看到失败的语句。请参阅“它是如何工作的?”部分以获取更多详细信息。
请参阅 文档 以获取更多详细信息。
特性
Spec for PHP 正在积极开发中,虽然功能齐全,但尚未实现所有功能。因此,目前应将其视为 alpha 级软件。
工作特性
- Describe 和 It 块解析器
- 自然语言期望解析器
- 协调期望(和、或、但是)
- Before 和 After 块
- 运行期望针对集合/数组(全部、任何、没有)
- 参数化的 It 块
- 支持注解(@group、@skip、@todo、@throw 等)
- 自定义 CLI 运行工具
- PHPUnit 集成
- 使用注解从自定义 PHPUnit_TestCase 类继承(例如:Zend_Test)
- 匹配器工厂,用于使用回调函数创建匹配器
- 所有 RSpec2 特性(主题、its)
即将推出
- 审查可配置选项和扩展点
稍后
- 额外的匹配器
- 更好的期望失败描述
- 从 RSpec 2 导入功能
- Mock 框架(PHPUnit、Mockery 等)的一级集成
需求
- PHP 5.3
- Composer
安装
使用 composer
将库添加到项目的 composer.json
中 - 例如
{
"require": {
"sizuhiko/spec-php": "0.9.*"
}
}
或者,从 CLI 将以下内容添加到 composer.json
中
composer require sizuhiko/spec-php:0.9.*
要进行测试运行,只需检出存储库以获取测试目录,并运行以下命令
cd tests/
phpunit AllTests.php
也可以尝试自定义 CLI 运行器
spec4php tests
示例
<?php
// Implements the StackTest example from PHPUnit manual as a spec file
describe "Testing array operations with Spec"
it "should support Push and Pop"
$stack = array();
count($stack) should equal 0;
array_push($stack, 'foo');
$stack[count($stack)-1] SHOULD == 'foo';
count($stack) SHOULD BE 1;
array_pop($stack)
Should be "foo"
count($stack)
should be equal to 0
end
end
就是这样,真的,没有 ->assert
调用,没有类、方法或其他冗长语句来适应代码。
块的语法借鉴自RSpec,describe
用于分组测试,而it
则定义了一个用于执行特定功能测试的代码块。
但请注意,这个示例使用了Spec可能的最自然语言语法。它也可以使用闭包或用点而不是空格来分隔语句,使其成为完全有效的PHP语法。请查看以下示例
<?php
describe. "Block without closure".
it("should multiply", function(){
(2*2) . should.equal(4);
});
end;
如果您仍然更喜欢传统的PHPUnit测试用例的样子,您可能仍然会发现这个库很有用,请查看关于PHPUnit兼容性的部分。
它是如何工作的?
自定义语法的解析器使用PHP自身的标记器(token_get_all
)来确保它不会在奇怪的表达式上卡住。当它遇到像describe
这样的块级别关键字时,它会将内容包装在一个闭包函数中。
should
关键字使用不同的解析逻辑。它前面的语句被捕获为“值”或“主题”,而它后面的语句被捕获为“期望”或“谓词”。它甚至能够解析括号内的复杂表达式。
为了欺骗PHP解释器,使其接收转换后的代码而不是原始的Spec语法,使用了自定义流包装器来执行转换。每个使用spec://path/to/file.php
表示法的文件都会通过Spec的解析器进行转换(如果需要的话)。
为了使期望有意义,Expect类应用了一些简单的算法,例如删除常用词汇或管理句子组合符,如and。以下句子为例
5 should be an integer and less than 10
将被处理为以下内容
expect(5)->integer()->and_less(10);
与PHPUnit的兼容性
开发Spec时遵循的设计原则之一是使其与PHPUnit兼容,因为它是PHP世界中当前标准的测试工具。
Spec文件会即时转换以与PHPUnit兼容,允许使用其报告(代码覆盖率、xunit、tap日志)以及与IDE和持续集成服务的当前集成。
将\DrSlump\Spec\TestSuite
对象传递给PHPUnit,它将能够执行它引用的任何spec文件。例如,通过创建以下类,它将递归地运行在定义该类的目录下找到的所有spec文件。
require_once 'Spec.php';
class AllSpecs extends \DrSlump\Spec\DirectoryRunnerHelper {
static function suite() {
return parent::suite();
}
}
如果您已经有一个扩展了TestCase类的自定义断言和帮助方法,您可以使用class
注解通过Spec使用它。Spec将在生成测试时使用提供的类作为基础。这允许您使用当前的PHPUnit扩展,例如Zend Framework的Zend_Test。
# class My_TestCase
describe "My Test" {
it "should access a method of My_TestCase"
$this->myMethod();
end
}
甚至可以在PHPUnit的原生测试用例中使用expect
组件。
class ExpectTest extends PHPUnit_Framework_TestCase {
function testEqual(){
expect(1)->to_equal(1);
}
}
测试之外
Expect
组件实际上并不与PHPUnit或测试框架紧密相连。它的主要依赖是Hamcrest匹配器集,因此它也可以用于其他场景,例如验证应用程序控制器接收到的参数。
以下是一个示例Zend Framework控制器
class MyController extends Zend_Controller_Action {
public function myAction() {
expect($this->getParam('id'))
->to_be_numeric->and_more_than(0)
->do();
expect($this->getParam('action'))
->to_equal('create')->or('update')->or('delete')
->as('Invalid action')
->do();
// ... your logic goes here ...
}
}
当期望失败时,会抛出异常,因此它与大多数捕获异常以渲染错误页面的Web框架相匹配。当然,真正的力量来自于编写自定义的matchers
,例如一个检查用户ID是否有效的user exists匹配器。
许可协议
The MIT License
Copyright (c) 2011 Iván -DrSlump- Montes
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.