mindplay / testies
是的,testies:一个轻量级的库,用于快速、简单的单元测试
Requires
- php: ^8.0
Requires (Dev)
- mindplay/readable: ^1.2
- nyholm/psr7: ^1.8
- phpunit/php-code-coverage: ^9 || ^10 || ^11
- zaphyr-org/http-client: ^1.0
Suggests
- phpunit/php-code-coverage: ^9 || ^10 || ^11
This package is auto-updated.
Last update: 2024-09-21 17:48:13 UTC
README
是的,testies:一个轻量级函数库,用于快速、简单的单元测试。
试图尊重Go语言测试哲学 - 概括
测试框架往往会发展成自己的迷你语言,拥有条件语句、控制机制和打印机制,但PHP已经拥有所有这些功能;为什么还要重新创建它们?我们更愿意用PHP编写测试;这样就可以少学习一门语言,并且这种方法使测试更加简单易懂。
主要的测试API是一组位于mindplay\testies
命名空间中的函数。
内部,API由一对简单的“驱动”和配置类支持 - 这些类尽可能开放,你应该感到舒适地扩展这些类,并针对你正在测试的内容的测试需求进行定制。
使用方法
通过Composer安装
composer require-dev mindplay/testies
然后创建一个测试脚本 - 格式非常简单
<?php // import the functions you need: use function mindplay\testies\{test, ok}; // bootstrap Composer: require dirname(__DIR__) . '/vendor/autoload.php'; // define your tests: test( 'Describe your test here', function () { ok(true, 'it works!'); } ); // run your tests: exit(run()); // exits with errorlevel (for CI tools etc.)
你可以根据需要多次调用test()
- 测试将在调用run()
时排队执行。
API
以下函数可在mindplay\testies
命名空间中使用
# Assertions: ok($result, $why, $value); # check the result on an expression eq($value, $expected, $why); # check value for strict equality with an expected value expect($exception_type, $why, $function); # check for an expected exception that should be thrown # Helper functions: invoke($object, $method_name, $arguments); # invokes a protected or private method; returns the result inspect($object, $property_name); # returns a protected or private property value format($value, $detailed = false); # format a value for use in diagnostic messages
而不是提供数百个断言函数,您可以使用PHP表达式执行断言,通常与您自己的辅助函数或PHP内置标准函数一起使用 - 一些示例
test( 'Various things of great importance', function () { ok($foo instanceof Foo); # type-checking an object ok(is_int(inspect($foo, '_count'))); # type-checking a private property ok(123 == '123'); # loose comparison ok(in_array('b', ['a','b','c'])); # check for presence of a value ok(isset($map['key'])); # check for presence of a key ok(is_string(@$map['key'])); # type-check a key/value with error-suppression } );
我们发现,惯用的PHP代码是您已经知道的东西 - 我们相信编写更接近普通日常代码的测试,而不是为测试创建自己的领域特定语言。
自定义断言函数
您的自定义断言函数,就像内置断言函数一样,只是函数 - 通常这些函数会回调到ok()
函数以报告结果。例如
/** * Assert that a numeric value is very close to a given expected value * * @param float|int $value actual value * @param float|int $expected expected near value * @param int $decimals number of decimals of error tolerance */ function nearly($value, $expected, $decimals = 8) { ok(abs($value - $expected) * pow(10, $decimals) <= 1, "{$value} should be nearly {$expected}", $value); } test( 'Values should be approximately right', function () { nearly(9.999999999, 10); nearly(10.000000001, 10); nearly(10.00002, 10); } );
您可以使用相同的方法对多个断言进行分组以供重用
function checkValue($value) { ok(is_int($value), "value should be numeric", $value); ok($value > 0, "value should be positive", $value); } test( 'Checking out some numbers', function () { checkValue(123); checkValue(-1); } );
请注意,诊断输出将始终引用生成断言结果的测试闭包中的行号。
测试服务器
⚠️ 此功能尚处于草稿阶段。
PHP提供了一个内置的开发Web服务器。
对于基本的集成测试,提供了一个简单的包装类来启动和关闭服务器 - 下面的示例使用了nyholm/psr7
和zaphyr-org/http-client
客户端库
use Nyholm\Psr7\Factory\Psr17Factory; use Zaphyr\HttpClient\Client; use function mindplay\testies\{test, ok, eq}; $server = new TestServer(__DIR__, 8088); test( 'Can get home page', function () { $server = new TestServer(__DIR__, 8088); $http = new Psr17Factory(); $client = new Client($http, $http); $response = $client->sendRequest($http->createRequest("GET", "http://127.0.0.1:8088/index.php")); eq($response->getStatusCode(), 200); ok(strpos($response->getBody(), '<title>Welcome</title>') !== false, "it should capture the response body"); } );
请注意,当$server
对象超出作用域时,服务器将自动关闭 - 如果您需要显式关闭服务器,只需使用例如unset($server)
销毁服务器对象即可。
请记住,启动和停止多个服务器实例可能会极大地减慢您的测试速度 - 通常,打开一个服务器实例并在测试函数之间共享它是很好的主意。另一方面,创建和销毁客户端是推荐的,因为共享客户端状态可能会导致不可靠的测试。
选项
通过configure()
函数提供了一些简单的配置选项,该函数提供了对当前TestConfiguration
实例的访问。
代码覆盖率
要启用代码覆盖率并在控制台显示摘要结果
configure()->enableCodeCoverage();
要输出clover.xml
文件以便与外部分析工具集成,请指定输出路径
configure()->enableCodeCoverage(__DIR__ . '/build/clover.xml');
为了仅对特定文件夹中的文件启用代码覆盖率分析,请传入一个路径(或路径数组)如下
configure()->enableCodeCoverage(__DIR__ . '/build/clover.xml', dirname(__DIR__) . '/src');
详细程度
默认情况下,测试输出不会产生关于成功断言的消息,只有失败才会显示 - 如果您想查看更多内容,请启用详细输出
configure()->enableVerboseOutput();
您也可以通过命令行使用 -v
或 --verbose
开关来启用此功能。
严格错误处理
默认情况下,所有PHP错误/警告/通知都会通过内置的错误处理器自动映射到异常。如果您正在测试具有自定义错误处理的内容,您可以使用以下方法来禁用它
configure()->disableErrorHandler();
可扩展性
过程式API实际上是在两个提供实际库实现的类之上的一个薄层。
使用自定义驱动器的一个常见原因是覆盖 TestDriver::format()
方法,以自定义在控制台上输出特殊对象的格式。
要使用自定义的派生 TestConfiguration
类
// Derive your custom configuration class: class MyTestConfiguration extends TestConfiguration { // ... } // Head off your test by selecting your custom configuration object: configure(new MyTestConfiguration);
然后按照常规业务流程进行。
要使用自定义的派生 TestDriver
类
// Derive your custom driver class: class MyTestDriver extends TestDriver { // ... } // Boostrap your test by selecting your custom driver: configure(new TestConfiguration(new TestDriver));
或者,创建一个配置类,该类提供了一个自定义默认驱动器类
class MyTestDriver extends TestDriver { // ... } class MyTestConfiguration extends TestConfiguration { protected function createDefaultDriver() { return new MyTestDriver(); } // ... } configure(new MyTestConfiguration);
参考实际实现以查看其他可能的内容 - 这些类中的几乎所有内容都是 public
或 protected
,留待您根据需要调用或覆盖。