PHPUnit:完全忽略基于 dataProvider 参数的测试

PHPUnit: Ignore tests completely based on dataProvider parameters

提问人:Nono 提问时间:10/19/2023 更新时间:11/7/2023 访问量:41

问:

我想用 PHPUnit 9.6 测试我的 Symfony 控制器(功能),为了不必在每个测试类中都有相同的测试用例,我有一个想法,即创建一个包含测试函数的抽象类,然后有一个抽象的 dataProvider 函数。这是我的抽象类:

abstract public function getEndpointConfiguration(): array;

/**
 * @dataProvider getEndpointConfiguration
 * @testdox It grants access without authentication on endpoint $endpoint and method $method
 */
public function testItGrantsAccessWithoutAuthentication(string $method, string $endpoint, ?string $expectedUserClass): void
{
    if ($expectedUserClass !== null) {
        static::markTestSkipped();
    }

    $client = static::createClient();
    $client->request($method, $endpoint);

    static::assertResponseIsSuccessful();
}

/**
 * @dataProvider getEndpointConfiguration
 * @testdox It grants access with JWT token to $expectedUserClass on endpoint $endpoint and method $method
 */
public function testItGrantsAccessWithJwtToken(string $method, string $endpoint, ?string $expectedUserClass): void
{
    if ($expectedUserClass === null) {
        static::markTestSkipped();
    }

    $client = static::createJwtAuthenticatedClient(
        AppFixtures::getUsernameByUserClass($expectedUserClass),
        AppFixtures::getPasswordByUserClass($expectedUserClass)
    );

    $client->request($method, $endpoint);

    static::assertResponseIsSuccessful();
}

然后,为了对控制器运行这两个测试,我为控制器创建了一个测试类,该测试类扩展了我的抽象类,并在其中定义了抽象函数:

public function getEndpointConfiguration(): array
{
    return [
        // No authentication required
        ['GET', '/api/info', null],
        // Authentication with User class required
        ['GET', '/api/me', User::class],
    ];
}

所以我的想法是提供一个用户类或 null 作为第三个参数。如果为 null,则应为该终结点执行测试,如果是用户类,则应执行测试。正如你所看到的,我在两个测试函数中都使用了,这取决于提供的第三个参数。testItGrantsAccessWithoutAuthenticationtestItGrantsAccessWithJwtTokenstatic::markTestSkipped();

问题是我不喜欢在这种情况下将测试标记为跳过。如果这些被完全忽略,甚至不影响测试运行的最终结果,那就太完美了。

一个想法是创建两个单独的 dataProviders,然后传入一个不带身份验证的端点,另一个传入带身份验证的端点。但是,例如,控制器没有没有身份验证的端点,然后您必须在 dataProvider 中为此传递一个空数组,然后在最终结果中再次跳过测试。

有没有人对我如何做到这一点有任何想法?

php symfony phpunit

评论


答:

0赞 vodevel 11/7/2023 #1

我不确定您是否需要对成功响应进行如此普遍的测试(这通常会提供错误的支持)。但是,如果您坚持这种方法,那么同样的一般测试呢:


    /**
     * @dataProvider getEndpointConfiguration
     * @testdox It grants success response on endpoint $endpoint and method $method
     */
    public function testEndpoint(string $method, string $endpoint, ?string $expectedUserClass): void
    {
        $client = $this->getClient($expectedUserClass);
        $client->request($method, $endpoint);
    
        static::assertResponseIsSuccessful();
    }
    
    private function getClient(?string $expectedUserClass): void
    {
        if ($expectedUserClass === null) {
            return static::createClient();
        }
    
        return static::createJwtAuthenticatedClient(
            AppFixtures::getUsernameByUserClass($expectedUserClass),
            AppFixtures::getPasswordByUserClass($expectedUserClass)
        );
    }