lark / resttest
Lark RestTest
0.26.0
2023-05-19 14:56 UTC
Requires
- lark/framework: ^0.26.0
README
RestTest 是一个用于测试 REST API 端点的测试库。
安装
composer require lark/resttest
设置测试目录
创建一个测试目录,例如 ./tests/Rest,并添加一个运行测试文件,例如 ./tests/Rest/run.php
<?php use LarkRestTest\RestTest; require_once '../../app/bootstrap.php'; // setup autoloading for tests/Rest dir // this can also be done in composer.json using require-dev $loader = new Composer\Autoload\ClassLoader; $loader->addPsr4('Tests\\', dirname(__DIR__, 1)); $loader->register(); // handle options, like debugging $argv = $_SERVER['argv'] ?? []; $isDebug = false; if (in_array('--debug', $argv) || in_array('-d', $argv)) { $isDebug = true; } // run tests using base namespace and directory RestTest::run('Tests\Rest', __DIR__, $isDebug);
创建测试类
可以在 ./tests/Rest 目录中创建测试类,并且必须以 Test.php 结尾。创建一个第一个测试类,例如 ./tests/Rest/UserTest.php
namespace Tests\Rest; use LarkRestTest\RestTest; class UserTest extends RestTest { public function __construct() { // HTTP client must be initialized with a base URL before // any client methods can be called $this->client('https://'); } /** * Create users * @test */ public function create(): void { // send request: // POST /users // [{"name":"test"},{"name":"test2"}] $this->clientPost('/users', [ ['name' => 'test'], ['name' => 'test2'] ]); // must be response status code 200 $this->expectCodeOk(); // body must be the same as this // because "id" will be unknown use "$$VAR" to allow any value $this->expectBodySame([ ['id' => '$$VAR', 'name' => 'test'], ['id' => '$$VAR', 'name' => 'test2'] ]); // save IDs for later tests $this->ids('user'); } /** * Delete user * @test * @depends create */ public function deleteOne(): void { // get ID from earlier save in create method $id = $this->id('user'); // also can use $this->id('user', 1); to get ID at exact index $this->clientDelete('/users/' . $id); $this->expectCodeOk(); $this->expectBodySame(['affected' => 1]); } }
每个测试类方法必须是测试,必须在 docblock 中有 @test,否则在运行测试时将被忽略。
如果方法依赖于另一个方法或多个方法,应该在方法的 docblock 中使用 @depends [METHODNAME] 注释,例如 @depends create。
如果类依赖于另一个类,应在类的 docblock 中使用 @depends [CLASSNAME] 注释,例如 @depends \Tests\Rest\UserTest。
所有以
Test.php结尾的类都将被视为测试。要排除以Test.php结尾的类文件从测试中,请在类的 docblock 中使用@ignore。
清理函数
测试方法可以返回一个 callable,用作清理函数,将在测试方法调用后被调用,例如
/** * Delete user * @test * @depends create */ public function deleteOne(): callable { // ... return function() { // do cleanup here }; }
比较响应体
有时响应体对象数组可能是随机排序的,这可能导致使用 RestTest::expectBodySame 时测试失败。例如
/** * Update users * @test * @depends create */ public function update(): void { $this->clientPatch('/users', [ [ 'id' => $this->id('user', 1), 'name' => 'test5' ], [ 'id' => $this->id('user', 2), 'name' => 'test6' ] ]); // this will possibly fail depending on the order of objects // returned in the response body $this->expectBodySame([ [ 'id' => $this->id('user', 1), 'name' => 'test5' ], [ 'id' => $this->id('user', 2), 'name' => 'test6' ] ]) }
为了解决这个问题,可以使用 RestTest::expectBodySameSorted 方法来自动按特定字段(默认为 id)对预期数组对象和响应体对象数组进行排序。
运行测试
要运行测试,请转到包含运行测试文件的测试目录,例如 ./tests/Rest,并执行运行文件
$ php run.php
Running tests...
------------------------------------------------------------------------------------------
Base namespace: Tests\Rest
Base directory: /myproject/tests/Rest
Test classes: 1
------------------------------------------------------------------------------------------
001) 200 Tests\Rest\UserTest::create # Create users [0.0475s]
002) 200 Tests\Rest\UserTest::deleteOne # Delete user [0.0312s]
------------------------------------------------------------------------------------------
OK (Tests: 2, Assertions: 4) in 0.0874s