dotink/lab

Lab是一个简洁直接的测试框架

这个包的官方仓库似乎已经消失,因此该包已被冻结。

1.2.1 2016-12-04 10:43 UTC

This package is auto-updated.

Last update: 2024-02-29 02:37:35 UTC


README

Join the chat at https://gitter.im/dotink/lab Build Status

Lab是一个简洁直接的测试框架,它隔离测试环境、类交互等。它使用简单且直观。它与Parody配合良好,提供了与更复杂的框架相似的测试能力,同时API更简洁,方法更简单。

安装

composer global require dotink/lab

基本用法

一旦安装了lab,开始使用就很容易了!

cd <path to project>
cp ~/.composer/vendor/dotink/lab.config ./lab.config
mkdir -p test/routines

现在您可以首次运行lab

Lab running for the first time

添加测试集和测试

要向Lab添加一组测试,您可以在tests文件夹中创建一个名为测试集名称的文件。与其它测试框架不同,此文件是一个简单的PHP文件,它仅返回一个数组。让我们将以下模板添加到名为Example Tests.php的文件中:

<?php namespace Dotink\Lab
{
	return [
		'tests' => [

			// Our first test

			'First Test' => function($data){

			},
		]
	];
}

现在我们可以重新运行Lab并看到我们的第一个测试结果

Lab running our first test

进行断言

每个测试将进行一个或多个断言。Lab提供了一个Assertion类,可用于进行断言,然而,如果您愿意,也可以使用第三方库或基本的PHP代码。无论如何进行断言,当抛出一个未捕获的异常时,测试将在Lab中失败。让我们使用Lab的assert函数进行基本的断言来检验这一点,这将创建一个新的内置Assertion类的实例。

<?php namespace Dotink\Lab
{
	return [
		'tests' => [

			// Our first test

			'First Test' => function($data){
				accept(2 + 2)->equals(5);
			},
		]
	];
}

这次,当我们重新运行Lab时,我们立即看到失败以及一些有关失败的信息

Lab with a failing assertion

“智能”断言

Assertion类旨在为90%的测试案例提供功能,具有简洁灵活的语法。其便利性的一部分在于它如何解析字符串输入,并尝试确定该字符串是否表示其他代码,例如,一个类方法、一个属性或一个函数。以下两行代码在大多数情况下是等效的

accept(ltrim('test', 't'))->equals('est', TRUE);

accept('ltrim')->with('test', 't')->equals('est');
多个断言

尽管上述每个都会进行完全相同的比较以断言相等的值,但第二个在两个方面有所益处。首先,通过直接向accept()提供函数、方法或属性名称,可以在不重复实际方法名称的情况下对单个方法执行多个断言

accept('ltrim')
	-> with   ('test', 't')
	-> equals ('est')

	-> with   ('another', 'an')
	-> equals ('other')

	-> with   ('  default  ')
	-> equals ('default  ')
;
测试私有/受保护的

除了可以轻松地进行多个断言外,使用“智能”断言还可以访问privateprotected方法和属性。让我们使用以下毫无用处的类来说明这一点

class Adder
{
	protected $seed = 0;

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

	private function add($num)
	{
		return $this->seed + $num;
	}
}

使用上述类,我们可以轻松地进行以下断言,尽管add方法不是公开可见的

accept('Adder::add')
	-> using  (new Adder(3))
	-> with   (2)
	-> equals (5)

	-> using  (new Adder(5))
	-> with   (3)
	-> equals (8)
;

同样,我们可以使用稍有不同的调用来检查seed属性的值

accept('Adder::$seed')
	-> using  (new Adder(3))
	-> equals (3)

	-> using  (new Adder(5))
	-> equals (5)
;

上述代码还显示了如何使用using方法来指定我们想要访问属性或方法的对象。这允许我们轻松地测试可能以不同方式实例化的多个对象,以确保在不同的情况下行为的一致性。

测试用例

理解这一点非常重要:Lab 中添加的每个测试集/文件都会在完全独立的 PHP 执行中运行。尽管我们建议按装置组织测试集,但在需要的情况下,您可以创建单独的装置包含文件并将它们添加到多个测试集中。在所有情况下,您需要为准备测试环境或创建测试数据所做的任何操作都应添加到测试集数组中的 setup 键。

<?php namespace Dotink\Lab
{
	return [
		'setup' => function($data) {
			// setup code here
		},

		'tests' => [
			// tests here
		]
	];
}

如果您需要在所有测试集/文件中进行设置,则可以将该逻辑添加到与相同键名引用的闭包中 lab.config 文件。同样,您还会在那里找到一个 cleanup 键,可以用于全局清理代码以及添加到每个单独的测试集中的特定清理代码。

//
// The global 'cleanup' key can contain a closure to run fixture cleanup logic at the end
// of every test file
//

'cleanup' => function($data) {

},

自定义配置数据

现在您可能已经意识到,每个闭包要么在 lab.config 文件中,要么在测试集中,都接受一个 $data 参数。您可能也注意到了 lab.config 中的 data 键,它指向一个数组。默认情况下,此数组仅包含一个 root 键,该键指向 lab.config 文件所在的目录。

您可以将任何需要的信息添加到该数组中,以便在每次测试/设置/或清理的基础上使用。或者使用提供的根,例如,使用 needs 函数加载您的类。

'setup' => function($data) {
	needs($data['root'] . '/src/Adder.php');
}

依赖关系

如上代码所示,needs 函数提供了一个干净的方式来要求您的源文件,并使用 Lab 的格式化输出。

Lab with a failing needs

然而,您可能被诱惑在 setup 函数(s) 中抛出一个自动加载器或类似的东西。虽然这是100%可能的,但您需要在 lab.config 文件中将 disable_autoloading 设置为 FALSE。如果设置为 TRUE(默认值),Lab 将几乎立即注册一个自动加载器,这将通过抛出异常来阻止以这种方式加载类。这是为了减少未知或未看到依赖关系导致单元测试变成更像是集成测试的机会。

结论

Lab 是一个易于使用、快速设置且通常很有趣的测试框架。结合 Parody,它代表了 PHP 测试的一个强大工具,涵盖了大量的最佳实践,包括但不限于:

  • 简单、清晰且表达性强的 API(限制测试本身的错误)
  • 高度代码隔离(默认禁用自动加载,显式 needs 或模拟)
  • 限制无关的上下文(每个测试集都由 PHP 独立执行)
  • 不可协商的硬失败(直到解决,否则完全死亡)