geckoboom / whirlwind-application-testing
whirlwind微框架的功能测试
Requires
- php: ^8.0.0
- ext-json: *
- ext-mbstring: *
- justinrainbow/json-schema: ^5.2
- mockery/mockery: ^1.4
- phpunit/phpunit: ^9.0
- softcreatr/jsonpath: ^0.8.2
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-30 01:35:46 UTC
README
应用程序测试检查应用程序所有层(从路由到响应)的集成。它们基于PHPUnit框架,并具有特殊的流程。
- 发起请求
- 测试响应
需求
PHP 7.4或更高版本。
安装
安装此扩展的首选方式是通过composer。
运行
composer require "geckoboom/whirlwind-application-testing" --dev
或添加
"geckoboom/whirlwind-application-testing": "*"
到您的composer.json文件的require-dev部分。
定义TestCase
要定义您的REST测试基础设施,您必须创建一个继承自RestTestCase的TestCase类,并实现createApplication()方法的具体实现。
以下代码定义了一个whirlwind应用程序TestCase
<?php namespace Test; use League\Container\Container; use Whirlwind\App\Application\Application; use WhirlwindApplicationTesting\RestTestCase; use App\Models\User; abstract class TestCase extends RestTestCase { protected function createApplication(): Application { $container = new Container(); // register service providers here return new Application($container); } }
在上面的例子中,我们为进行应用程序测试提供了最小配置
现在您可以进行REST测试。只需创建新的测试并扩展之前创建的TestCase
<?php namespace Test; class UsersTest extends TestCase { public function testGetById() { $this->addAuthorizationToken('secret') ->get('/users/1', ['X-Test-Header' => 'Test']) ->assertResponseIsSuccessful() ->assertResponseCodeIsOk() ->assertHeader('Content-Type', 'application/json') ->assertResponseContainsJsonFragment(['id' => 1]); } }
在上面的例子中,测试添加了Bearer授权令牌,并验证HTTP请求是否成功,状态码为200,且响应中包含适当的头和正文片段。
发起请求
TestCase模拟浏览器等HTTP客户端,并向Whirlwind应用程序发起请求。默认情况下,您可以访问以下HTTP方法
get($uri, $headers = [])getJson($uri, $headers = [])post($uri, $data = [], $headers = [])postJson($uri, $data = [], $headers = [])put($uri, $data = [], $headers = [])putJson($uri, $data = [], $headers = [])patch($uri, $data = [], $headers = [])patchJson($uri, $data = [], $headers = [])delete($uri, $data = [], $headers = [])deleteJson($uri, $data = [], $headers = [])options($uri, $data = [], $headers = [])optionsJson($uri, $data = [], $headers = [])
如果所需的HTTP方法不在上述列表中,您可以通过call()或json()方法发起HTTP请求。
call()和json()方法的全签名
call( string $method, string $uri, array $parameters = [], array $files = [], array $server = [], ?string $content = null ) json( string $method, string $uri, array $parameters = [], array $headers = [] )
可用的响应断言
assertResponseIsSuccessful()检查状态码是否在[200, 300)范围内assertResponseCodeIs(int $status)检查状态码是否等于$statusassertResponseCodeIsOk()检查状态码是否为200assertResponseCodeIsCreated()检查状态码是否为201assertResponseCodeIsAccepted()检查状态码是否为202assertResponseCodeIsNoContent()检查状态码是否为204assertResponseCodeIsBadRequest()检查状态码是否为400assertResponseCodeIsUnauthorized()检查状态码是否为401assertResponseCodeIsForbidden()检查状态码是否为403assertResponseCodeIsNotFound()检查状态码是否为404assertResponseCodeIsNotAllowed()检查状态码是否为405assertResponseCodeIsUnprocessable()检查状态码是否为422assertHeader(string $name, $value = null)检查响应中是否存在名为$name的标头,值是$value(如果非null)assertResponseIsJson()检查响应是否包含有效的JSONassertResponseContains(string $needle, bool $escape = true)检查响应JSON是否包含字符串assertResponseNotContains(string $needle, bool $escape = true)检查响应JSON不包含字符串assertHeaderMissing(string $name)检查响应中是否存在名为$name的标头assertContainsInResponsePath(string $path, $expected)assertResponseContainsExactJson(array $data)assertResponseContainsJsonFragment(array $data)检查响应是否包含$data片段assertResponseNotContainsExactJson(array $data)assertResponseMatchesJsonType(array $jsonSchema, ?string $jsonPath = null)请参阅 justinrainbow/json-schemaassertResponseCount(int $count, ?string $jsonPath = null)
测试用例
测试用例用于将“假”数据集加载到数据库中以进行测试。测试用例可以依赖于其他测试用例(WhirlwindApplicationTesting\Fixture\Fixture::$depends 属性)。
定义测试用例
要定义测试用例,只需创建一个新的类,该类实现 WhirlwindApplicationTesting\Fixture\FixtureInterface。
<?php namespace Test\Fixture; use Domain\User\User; use Whirlwind\Infrastructure\Hydrator\UserHydrator; use Whirlwind\Infrastructure\Repository\TableGateway\UserTableGateway; use WhirlwindApplicationTesting\Fixture\EntityFixture; class UserFixture extends EntityFixture { protected string $dataFile = 'users.php'; protected string $entityClass = User::class; public function __construct(UserHydrator $hydrator, UserTableGateway $tableGateway) { parent::__construct($hydrator, $tableGateway); } }
提示:每个EntityFixture都是为了准备数据库表以进行测试目的。您可以在构造函数中以及Hydrator实现属性中指定适当的TableGatewayInterface实现。表名封装在表网关中,而Hydrator用于将原始结果映射到WhirlwindApplicationTesting\Fixture\EntityFixture::$entityClass对象
EntityFixture的测试用例数据通常位于声明测试用例类的data目录中的文件中。数据文件应返回要插入表中的数据行数组。例如
<?php // tests/Fixture/data/users.php return [ [ 'name' => 'user1', 'email' => 'user1@example.org', 'password' => bcrypt('secret'), ], [ 'name' => 'user2', 'email' => 'user2@example.org', 'password' => bcrypt('secret'), ], ];
可以通过指定WhirlwindApplicationTesting\Fixture\Fixture::$depends属性来创建可依赖的测试用例,如下所示
<?php namespace Test\Fixture; use Domain\User\UserProfile; use Whirlwind\Infrastructure\Hydrator\UserHydrator; use Whirlwind\Infrastructure\Repository\TableGateway\UserTableGateway; use WhirlwindApplicationTesting\Fixture\EntityFixture; class UserProfileFixture extends EntityFixture { protected string $dataFile = 'user_profiles.php'; protected string $entityClass = UserProfile::class; protected array $depends = [ UserFixture::class, ]; public function __construct(UserProfileHydrator $hydrator, UserProfileTableGateway $tableGateway) { parent::__construct($hydrator, $tableGateway); } }
依赖关系允许您以良好定义的顺序加载和卸载测试用例。在上面的示例中,UserFixture将始终在UserProfileFixture之前加载。
使用测试用例
如果您在测试代码中使用测试用例,则需要添加 WhirlwindApplicationTesting\Traits\InteractWithFixtures 特性并实现 fixtures() 方法
<?php namespace Test; use Domain\Profile\Profile; use Test\Fixture\UserFixture; use Test\Fixture\UserProfileFixture; use WhirlwindApplicationTesting\Traits\InteractWithFixtures; class UsersTest extends TestCase { use InteractWithFixtures; public function testGetById() { $this->addAuthorizationToken('secret') ->get('/users/1', ['X-Test-Header' => 'Test']) ->assertResponseIsSuccessful() ->assertResponseCodeIsOk() ->assertHeader('Content-Type', 'application/json') ->assertResponseContainsJsonFragment(['id' => 1]); } public function fixtures(): array { return [ 'users' => UserFixtureClass::class, 'profiles' => [ 'class' => UserProfileFixture::class, 'depends' => [ UserFixture::class, ], 'dataFile' => 'profile.php', 'entityClass' => Profile::class, ], ]; } }
在fixtures()方法中列出的测试用例将在执行测试之前自动加载。