tarantool / phpunit-extras
为 PHPUnit 提供一组辅助工具,以简化 Tarantool 库的测试。
Requires
- php: ^7.2.5|^8
- composer/package-versions-deprecated: 1.11.99.5
- composer/semver: ^3.3
- rybakit/phpunit-extras: ^0.2.4
- symfony/expression-language: ^3.3|^4|^5|^6
- tarantool/client: ^0.10
Requires (Dev)
- php: ^7.2.5|^8
- friendsofphp/php-cs-fixer: ^2.19
- vimeo/psalm: ^3.9|^4
README
为 PHPUnit 提供一组辅助工具,以简化 Tarantool 库的测试。它基于 rybakit/phpunit-extras,请参阅此包获取更多文档。
目录
安装
composer require --dev tarantool/phpunit-extras
注解
除了由包 rybakit/phpunit-extras
提供的注解外,该库还附带针对 Tarantool 特定的注解。最简单的方法是通过从 Tarantool\PhpUnit\TestCase
继承您的测试类来启用它们。
use Tarantool\Client\Client; use Tarantool\PhpUnit\TestCase; final class MyTest extends TestCase { protected function getClient() : Client { // TODO: Implement getClient() method. } // ... }
另一种选择是注册一个名为 AnnotationExtension
的扩展。
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" > <!-- ... --> <extensions> <extension class="Tarantool\PhpUnit\Annotation\AnnotationExtension" /> </extensions> </phpunit>
默认情况下,该扩展假定您将要连接的 Tarantool 服务器位于 127.0.0.1:3301
。您可以通过指定 DSN 字符串 或一个 选项数组 作为扩展配置值来自定义默认设置。
<extension class="Tarantool\PhpUnit\Annotation\AnnotationExtension"> <arguments> <string>tcp://127.0.0.1:3301/?socket_timeout=10</string> </arguments> </extension>
或者
<extension class="Tarantool\PhpUnit\Annotation\AnnotationExtension"> <arguments> <array> <element key="uri"> <string>tcp://127.0.0.1:3301</string> </element> <element key="socket_timeout"> <integer>10</integer> </element> </array> </arguments> </extension>
此外,配置值可以解析环境变量,这在您需要与 Tarantool 实例文件或任何其他脚本共享相同设置时可能很有用。
<extension class="Tarantool\PhpUnit\Annotation\AnnotationExtension"> <arguments> <string>tcp://%env(TARANTOOL_HOST)%:%env(TARANTOOL_PORT)%</string> </arguments> </extension>
一旦配置了注解,您就可以开始使用它们了。
处理器
Lua
允许在运行测试之前执行 Lua 代码。
示例
/** * @lua tube:put('kick_me') * @lua tube:bury(0) */ public function testKickReleasesBuriedTask() : void { // ... }
Sql
允许在运行测试之前执行 SQL 语句(需要 Tarantool 2.0+)。
示例
/** * @sql DROP TABLE IF EXISTS foobar * @sql CREATE TABLE foobar (id INTEGER PRIMARY KEY, name VARCHAR(50)) * @sql INSERT INTO foobar VALUES (1, 'A'), (2, 'B') */ public function testExecuteQueryFetchesAllRows() : void { // ... }
要求
要求允许根据先决条件跳过测试。
LuaCondition
格式
@requires luaCondition <condition>
其中 <condition>
是一个任意 Lua 表达式,应该评估为布尔值。
示例
/** * @requires luaCondition box.session.user() ~= 'guest' */ public function testChangeUserPassword() : void { // ... }
TarantoolVersion
格式
@requires Tarantool <version-constraint>
其中 <version-constraint>
是类似 Composer 的版本约束。有关支持的格式详细信息,请参阅 Composer 的 文档。
示例
/** * @requires Tarantool ^2.3.2 */ public function testPrepareCreatesPreparedStatement() : void { // ... }
如果您对如何创建和注册自己的注解和要求感兴趣,请参阅
rybakit/phpunit-extras
的 README。
期望
请求
要测试您的代码是否发送(或未发送)某些请求,以下方法可用
TestCase::expect<REQUEST_NAME>RequestToBeCalled(int $count) : void
TestCase::expect<REQUEST_NAME>RequestToBeCalledAtLeast(int $count) : void
TestCase::expect<REQUEST_NAME>RequestToBeCalledAtMost(int $count) : void
TestCase::expect<REQUEST_NAME>RequestToBeCalledOnce() : void
TestCase::expect<REQUEST_NAME>RequestToBeCalledAtLeastOnce() : void
TestCase::expect<REQUEST_NAME>RequestToBeCalledAtMostOnce() : void
TestCase::expect<REQUEST_NAME>RequestToBeNeverCalled() : void
TestCase::expectNoRequestToBeCalled() : void
其中 <REQUEST_NAME>
是请求的名称,例如 Call
、Insert
等。这些方法是 Tarantool\PhpUnit\TestCase
类的一部分,但也可以通过特质启用。
use PHPUnit\Framework\TestCase; use PHPUnitExtras\Expectation\Expectations as BaseExpectations; use Tarantool\Client\Client; use Tarantool\PhpUnit\Expectation\RequestExpectations; final class MyTest extends TestCase { use BaseExpectations; use RequestExpectations; protected function getClient() : Client { // TODO: Implement getClient() method. } /** * @after */ protected function verifyTestCaseExpectations() : void { $this->verifyExpectations(); } // ... }
示例
public function testGetSpaceIsCached() : void { $this->client->flushSpaces(); $this->expectSelectRequestToBeCalledOnce(); $this->client->getSpace('test_space'); $this->client->getSpace('test_space'); }
预编译语句
为了断言预编译语句的分配,请使用 Tarantool\PhpUnit\Expectation\PreparedStatementExpectations
特性,它包含以下方法
expectPreparedStatementToBe<TYPE>(int $count) : void
expectPreparedStatementToBe<TYPE>AtLeast(int $count) : void
expectPreparedStatementToBe<TYPE>AtMost(int $count) : void
expectPreparedStatementToBe<TYPE>Once() : void
expectPreparedStatementToBeNever<TYPE>() : void
expectPreparedStatementToBe<TYPE>AtLeastOnce() : void
expectPreparedStatementToBe<TYPE>AtMostOnce() : void
其中 <TYPE>
可以是 Allocated
或 Deallocated
。
示例
public function testCloseDeallocatesPreparedStatement() : void { $stmt = $this->client->prepare('SELECT ?'); $this->expectPreparedStatementToBeDeallocatedOnce(); $stmt->close(); }
要一次性启用所有上述期望方法,请使用 Tarantool\PhpUnit\Expectation\Expectations
特性,或者扩展 Tarantool\PhpUnit\TestCase
类。
模拟
该库提供了一些辅助类,用于为 Tarantool 客户端 创建测试替身,以避免向 Tarantool 服务器发送真实请求。为了方便创建此类对象,请在测试类中添加特性 TestDoubleClient
use PHPUnit\Framework\TestCase; use Tarantool\PhpUnit\Client\TestDoubleClient; final class MyTest extends TestCase { use TestDoubleClient; // ... }
如果您的测试用例扩展了
Tarantool\PhpUnit\TestCase
类,则此步骤不是必需的,因为特性已包含在该类中。
可以通过以下方式创建一个模拟客户端对象
public function testFoo() : void { $dummyClient = $this->createDummyClient(); // ... }
要模拟特定场景,例如建立与服务器的连接或从服务器按特定顺序返回特定响应,请使用 TestDoubleClientBuilder
类的功能。例如,要模拟 PING
请求
use Tarantool\Client\Request\PingRequest; use Tarantool\PhpUnit\TestCase; final class MyTest extends TestCase { public function testFoo() : void { $mockClient = $this->getTestDoubleClientBuilder() ->shouldSend(new PingRequest()) ->build(); // ... } // ... }
另一个示例,发送两个 EVALUATE
请求并返回每个请求的不同响应
use Tarantool\Client\RequestTypes; use Tarantool\PhpUnit\Client\TestDoubleFactory; use Tarantool\PhpUnit\TestCase; final class MyTest extends TestCase { public function testFoo() : void { $mockClient = $this->getTestDoubleClientBuilder() ->shouldSend( RequestTypes::EVALUATE, RequestTypes::EVALUATE )->willReceive( TestDoubleFactory::createResponseFromData([2]), TestDoubleFactory::createResponseFromData([3]) )->build(); // ... } // ... }
上述示例可以简化为
$mockClient = $this->getTestDoubleClientBuilder() ->shouldHandle( RequestTypes::EVALUATE, TestDoubleFactory::createResponseFromData([2]), TestDoubleFactory::createResponseFromData([3]) )->build();
此外,构建器允许设置自定义的 Connection
和 Packer
实例
$stubClient = $this->getMockClientBuilder() ->willUseConnection($myConnection) ->willUsePacker($myPacker) ->build();
测试
在运行测试之前,必须安装开发依赖项
composer install
然后,运行所有测试
vendor/bin/phpunit vendor/bin/phpunit -c phpunit-extension.xml
许可证
该库采用 MIT 许可证发布。有关详细信息,请参阅捆绑的 LICENSE 文件。