toast / unit
针对 PHP7 的超级简单的单元测试
Requires
- php: >=8.1
- monolyth/cliff: ^0.7.0
- monomelodies/kingconf: ^1.1.0
- simoneast/simple-ansi-colors: ^1.0
README
Toast 是一个受 JavaScript 测试框架(如 Karma、Jasmine 等)启发的 PHP 超简单测试框架。
Toast 是因为对现有测试框架(在我们看来)过于庞大、复杂且难以设置而诞生的。有些还非常慢(比如 PHPUnit)。
特性
- 非常 快速
- 使用原生 PHP
assert
进行断言 - 使用 DocComments 进行特性描述
- 相关测试的分组
安装
$ composer require --dev toast/unit
在项目的根目录中创建一个 Toast.json
配置文件。它应包含至少一个 "tests"
键,指向放置测试的目录。测试可以放在(子)目录中;Toast 会递归搜索。
可选地,配置可以包含一个 "bootstrap"
键,包含在运行之前要包含的文件数组。这些可以包含项目的设置(例如依赖注入逻辑)。
开启断言并配置它们在失败时抛出 AssertionError
。请参阅 手册中的此部分;两个值都应该设置为 1
。
配置
将配置文件放在项目的根目录中(或在运行 Toast 时可选地指定它)。该文件支持 Kingconf 支持的所有格式;这里我们将使用 JSON。
示例配置文件
{ "tests": "path/to/my/tests" }
是的,就是这样 :)
使用方法
$ vendor/bin/toast
就是这样 :) 您可以可选地指定一个 --filter=
参数,包含一个正则表达式。在这种情况下,只有与文件名匹配的测试将被运行。过滤器不区分大小写,使用 "@"
作为分隔符。
其他可选标志包括
-v
用于详细模式-o
用于输出模式(见下文)
编写测试
这再简单不过了!每个测试(组)都是一个 可调用 的。Toast 假设任何返回 Generator
的可调用项是一个组;其他可调用项是实际的测试。例如
<?php /** Description of this group */ return function () : Generator { /** Test if true == true */ yield function () { assert(true); }; };
您可以为每个测试添加尽可能多的断言,但通常最好将断言数量限制到尽可能少(最好是单个),并使用生成器对相关测试进行分组
<?php return function () : Generator { $obj = new My\Thing\Under\Test; /** Test method foo */ yield function () use ($obj) { assert($obj->foo()); }; /** Test method bar */ yield function () use ($obj) { assert($obj->bar()); }; };
嵌套可以深到适合您的项目。
设置
测试可调用项将与 $this
绑定的实际测试实例(Toast\Unit\Test
的一个实例)一起调用。这暴露了一个接受可调用项的 beforeEach
方法,在每组测试之前(嵌套组中的测试不继承它们)调用。可以多次调用 beforeEach
。
<?php return function () : Generator { $this->beforeEach(function () { echo "1\n"; }); yield function () : Generator { $this->beforeEach(function () { echo "2\n"; }); yield function () { assert(true); }; }; yield function () { assert(true); }; };
在上面的示例中,由于 beforeEach
对两个顶级 yield
都是有效的,因此 "1"
将被输出两次。"2"
将只输出一次,因为它只适用于嵌套的 yield
,而这个嵌套的 yield
对其父项一无所知。
您可以使用 beforeEach
来加载数据库固定值等。如何做取决于您。
清理
类似地,如果需要清理,有一个 afterEach
方法也以相同的方式工作。
这很显然,但是
beforeEach
和afterEach
只会应用于在相应调用之后被yield
的测试。这是因为PHP在生成器内部会暂停执行。对于复杂的测试,在组中间添加before/after可调用对象可能有意义,但通常你只需将它们放在开始处。如果你发现自己需要在组中间添加它们,通常这意味着你应该将测试组拆分成更小的单元。
测试不仅仅是简单的断言
Toast假设成功的测试是一个通过的断言。但是,如果你需要测试是否抛出异常呢?很简单
<?php //... yield function () { $foo = new Foo; $e = null; try { $foo->bar(); } catch (FooException $e) { } assert($e instanceof FooException); };
Toast还假设测试不会产生输出。所以,要测试一个函数是否实际上确实产生输出,请使用输出缓冲。
<?php //.... yield function () { ob_start(); thisFunctionPrintsSomething(); assert(ob_end_clean() == "Hello world!"); };
在调用Toast时,你可以选择指定-o
参数来关闭此功能。这有助于开发,因为你可以更轻松地var_dump
东西,直到你得到一个有效的测试。
检测Toast运行
Toast设置了一个环境变量TOAST
,你的代码可以检查它,例如,知道你想要使用哪个数据库(开发或测试)
<?php if (getenv("TOAST")) { $db = new PDO('mysql:test'); } else { $db = new PDO('mysql:dev'); }
还有一个(唯一的)TOAST_CLIENT
设置,你可以用来识别特定的Toast运行。如果你测试的功能将某些东西存储在某个位置,并且你需要能够识别它,这将很有用。