fillincode/tests
一个用于在 Laravel 中简化测试工作的包
4.0.3
2024-08-02 10:46 UTC
Requires
- php: ^8.1
- laravel/framework: ^10.0
README
快速生成测试,无需手动编写整个测试逻辑。
包功能
- 包执行路由中间件测试
- 对配置中定义的每个用户的请求进行测试
- 对带有数据的请求进行测试
- 对带有 URL 参数的请求进行测试
- 检查每个测试的响应代码
- 在执行请求之前用数据填充数据库
- 创建嘲讽
安装
composer require fillincode/tests
发布配置
php artisan vendor:publish --provider="Fillincode\Tests\TestServiceProvider"
配置
配置位于 config/fillincode_tests.php 文件中
需要指定用户的默认响应代码,以及无效数据和 URL 参数的默认响应代码
[
'user' => 200,
'admin' => 200,
'guest' => 401,
'invalid_data' => 422,
'invalid_parameters' => 404,
];
需要指定系统中存在的用户和哪些 guards 检查它们的认证。对于 guest,不需要指定 guard
'users' => [ 'guest', 'user' => 'Passport', 'admin' => 'web', ],
命令
生成用于功能测试的基本类,其中包含基本的测试逻辑
php artisan f-tests:init
生成测试类。使用此命令还可以选择实现类所需的接口。方法将自动添加到类中
php artisan make:f-test
包的初始配置示例
需要在配置中指定系统中存在的用户以及这些用户的默认响应代码。
return [ 'web_user' => 200, 'api_user' => 200, 'admin' => 200, 'guest' => 401, 'invalid_data' => 422, 'invalid_parameters' => 404, 'has_fillincode_swagger_parser' => true, 'users' => [ 'guest', 'web_user' => 'web', 'api_user' => 'Passport' 'admin' => 'Moonshine', ], ];
然后执行生成类的命令。在这个类中,将实现来自每个用户的测试方法。
php artisan f-tests:init
然后实现这些方法,或者在 BaseFeatureTest 或 TestCase 中实现,以获取这些用户。
use App\Models\User; ```` /** * Получения пользователя web_user * * @return User */ public function getWebUser(): User { return User::whereEmail('web_user@gmail.com')->first(); } /** * Получения пользователя api_user * * @return User */ public function getApiUser(): User { return User::whereEmail('api_user@gmail.com')->first(); } /** * Получения пользователя admin * * @return User */ public function getAdmin(): User { return User::whereEmail('admin@gmail.com')->first(); }
包的测试功能
更改当前路由的默认响应代码
- 需要实现接口 Fillincode/Tests/Interfaces/CodeInterface
- 实现 getCodes 方法
use Fillincode\Tests\Interfaces\CodeInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements CodeInterface { /** * {@inheritDoc} */ public function getCodes(): array { return [ 'guest' => 401, 'web_user' => 200, 'api_user' => 401, 'admin' => 401, ]; } }
更改传递给 URL 参数的无效参数的默认响应代码
- 需要实现接口 Fillincode/Tests/Interfaces/ParametersCodeInterface
- 实现 getCodesForInvalidParameters 方法
use Fillincode\Tests\Interfaces\ParametersCodeInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements ParametersCodeInterface { /** * {@inheritDoc} */ public function getCodesForInvalidParameters(): array { return [ 'guest' => 404, 'web_user' => 404, 'api_user' => 404, 'admin' => 404, ]; } }
在测试期间传递参数
- 需要实现接口 Fillincode/Tests/Interfaces/ParametersInterface
- 实现 getParameters 和 getInvalidParameters 方法
第一个方法应该返回正确的 URL 参数,第二个方法应该返回错误的 URL 参数
use Fillincode\Tests\Interfaces\ParametersInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements ParametersInterface { /** * {@inheritDoc} */ public function getParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'active']) ]; } /** * {@inheritDoc} */ public function getInvalidParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'draft']) ]; } }
数据验证
- 需要实现接口 Fillincode/Tests/Interfaces/ValidateInterface
- 实现 getValidData 和 getNotValidData 方法
第一个方法应该返回有效数据,第二个方法应该返回无效数据
use Fillincode\Tests\Interfaces\ValidateInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements ValidateInterface { /** * {@inheritDoc} */ public function getValidData(): array { return [ 'name' => 'test_name', 'age' => 12, ]; } /** * {@inheritDoc} */ public function getNotValidData(): array { return [ 'name' => 'q', 'age' => null, ]; } }
在执行每个请求之前用数据填充数据库
- 需要实现接口 Fillincode/Tests/Interfaces/FakeInterface
- 实现 faker 方法。在这个方法中,你需要执行填充数据库的逻辑
use Fillincode\Tests\Interfaces\FakeInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements FakeInterface { /** * {@inheritDoc} */ public function faker(): void { Project::factory(10)->create(['web_user_id' => $this->getWebUser()->id]); } }
创建模拟数据存储
- 需要实现接口 Fillincode/Tests/Interfaces/FakeStorageInterface
对于实现此接口的测试,将自动创建模拟的 public 存储库
use Fillincode\Tests\Interfaces\FakeStorageInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements FakeStorageInterface { }
在测试中添加嘲讽
- 需要实现接口 Fillincode/Tests/Interfaces/MockInterface
- 实现 getMockAction 方法
use Fillincode\Tests\Interfaces\MockInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements MockInterface { /** * {@inheritDoc} */ public function getMockAction(): void { Http::fake(); } }
如果包与 Fillincode/Swagger 包一起使用,并且有不需要记录的路线
-
需要实现接口 Fillincode/Tests/Interfaces/DocIgnoreInterface
use Fillincode\Tests\Interfaces\DocIgnoreInterface; use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest implements DocIgnoreInterface { }
-
在 BaseFeatureTest 类的 callRouteAction 方法中添加
if (! $this->checkDocIgnoreInterface()) { (new TestParser())->makeAutoDoc($testResponse); }
包使用示例
对于最小测试,只需要创建一个继承自 BaseFeatureTest 类并实现 getRouteName 和 getMiddleware 方法的类。
use Tests\Feature\BaseFeatureTest; class ExampleTest extends BaseFeatureTest { /** * {@inheritDoc} */ public function getRouteName(): string { return 'api.user.update'; } /** * {@inheritDoc} */ public function getMiddleware(): array { return ['api', 'auth']; } }
实现所有包功能的类示例。
类功能
- 执行配置包中定义的所有用户的请求
- 执行带有 URL 参数的测试
- 传递数据进行验证
- 创建模拟文件存储库
- 模拟 Http 门面
- 忽略文档化测试结果
- 将填充10个项目到数据库
use Tests\Feature\BaseFeatureTest; use Fillincode\Tests\Interfaces\CodeInterface; use Fillincode\Tests\Interfaces\ParametersCodeInterface; use Fillincode\Tests\Interfaces\ParametersInterface; use Fillincode\Tests\Interfaces\ValidateInterface; use Fillincode\Tests\Interfaces\FakeInterface; use Fillincode\Tests\Interfaces\FakeStorageInterface; use Fillincode\Tests\Interfaces\MockInterface; use Fillincode\Tests\Interfaces\DocIgnoreInterface; class ExampleTest extends BaseFeatureTest implements CodeInterface, ParametersCodeInterface, ParametersInterface, ValidateInterface, FakeInterface, FakeStorageInterface, MockInterface, DocIgnoreInterface { /** * {@inheritDoc} */ public function getRouteName(): string { return 'api.user.update'; } /** * {@inheritDoc} */ public function getMiddleware(): array { return ['api', 'auth']; } /** * {@inheritDoc} */ public function getCodes(): array { return [ 'guest' => 401, 'web_user' => 200, 'api_user' => 401, 'admin' => 401, ]; } /** * {@inheritDoc} */ public function getCodesForInvalidParameters(): array { return [ 'guest' => 404, 'web_user' => 404, 'api_user' => 404, 'admin' => 404, ]; } /** * {@inheritDoc} */ public function getParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'active']) ]; } /** * {@inheritDoc} */ public function getInvalidParameters(): array { return [ 'project' => Project::factory()->create(['status' => 'draft']) ]; } /** * {@inheritDoc} */ public function getValidData(): array { return [ 'name' => 'test_name', 'age' => 12, ]; } /** * {@inheritDoc} */ public function getNotValidData(): array { return [ 'name' => 'q', 'age' => null, ]; } /** * {@inheritDoc} */ public function faker(): void { Project::factory(10)->create(['web_user_id' => $this->getWebUser()->id]); } /** * {@inheritDoc} */ public function getMockAction(): void { Http::fake(); } }