fillincode/tests

一个用于在 Laravel 中简化测试工作的包

4.0.3 2024-08-02 10:46 UTC

This package is auto-updated.

Last update: 2024-10-02 11:11:52 UTC


README

快速生成测试,无需手动编写整个测试逻辑。

包功能

  1. 包执行路由中间件测试
  2. 对配置中定义的每个用户的请求进行测试
  3. 对带有数据的请求进行测试
  4. 对带有 URL 参数的请求进行测试
  5. 检查每个测试的响应代码
  6. 在执行请求之前用数据填充数据库
  7. 创建嘲讽

安装

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();
}

包的测试功能

更改当前路由的默认响应代码

  1. 需要实现接口 Fillincode/Tests/Interfaces/CodeInterface
  2. 实现 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 参数的无效参数的默认响应代码

  1. 需要实现接口 Fillincode/Tests/Interfaces/ParametersCodeInterface
  2. 实现 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,
        ];       
    }
}

在测试期间传递参数

  1. 需要实现接口 Fillincode/Tests/Interfaces/ParametersInterface
  2. 实现 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']) 
        ];       
    }
}

数据验证

  1. 需要实现接口 Fillincode/Tests/Interfaces/ValidateInterface
  2. 实现 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,
        ];       
    }
}

在执行每个请求之前用数据填充数据库

  1. 需要实现接口 Fillincode/Tests/Interfaces/FakeInterface
  2. 实现 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]);
    }
}

创建模拟数据存储

  1. 需要实现接口 Fillincode/Tests/Interfaces/FakeStorageInterface

对于实现此接口的测试,将自动创建模拟的 public 存储库

use Fillincode\Tests\Interfaces\FakeStorageInterface;
use Tests\Feature\BaseFeatureTest;

class ExampleTest extends BaseFeatureTest implements FakeStorageInterface
{
    
}

在测试中添加嘲讽

  1. 需要实现接口 Fillincode/Tests/Interfaces/MockInterface
  2. 实现 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 包一起使用,并且有不需要记录的路线

  1. 需要实现接口 Fillincode/Tests/Interfaces/DocIgnoreInterface

    use Fillincode\Tests\Interfaces\DocIgnoreInterface;
    use Tests\Feature\BaseFeatureTest;
    
    class ExampleTest extends BaseFeatureTest implements DocIgnoreInterface
    {
        
    }
  2. 在 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'];
    }
}

实现所有包功能的类示例。

类功能

  1. 执行配置包中定义的所有用户的请求
  2. 执行带有 URL 参数的测试
  3. 传递数据进行验证
  4. 创建模拟文件存储库
  5. 模拟 Http 门面
  6. 忽略文档化测试结果
  7. 将填充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();
    }
}