PHPUnit:如何仅在以 Test 结尾的类中运行测试?

Posted

技术标签:

【中文标题】PHPUnit:如何仅在以 Test 结尾的类中运行测试?【英文标题】:PHPUnit: How to run only tests in classes that end with Test? 【发布时间】:2021-12-24 18:07:25 【问题描述】:

问题描述

我使用配置运行目录中的所有测试

phpunit-config.xml

<phpunit bootstrap="./bootstrap.php">
  <testsuites>
    <testsuite name="all">
      <directory>./tests</directory>
    </testsuite>
  </testsuites>
</phpunit>

在某些文件中有多个类(即它不遵循 PSR,请参阅底部的注释)可能扩展 *Test 类,但不应运行。他们的名字不以Test 结尾。例如ExampleHelper:

测试/AllTest.php

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

class ExampleTest extends TestCase

  public function testShouldRun(): void
  
    $this->assertSame(0, 0);
  


final class ExampleHelper extends ExampleTest

  public function testShouldNotBeExecuted(): void
  
    $this->assertSame(0, 1);
  

正如方法所暗示的,应该执行ExampleTest,但不应该执行ExampleHelper

复制

目录结构

├── Dockerfile
├── bootstrap.php
├── docker-compose.yml
├── phpunit-config.xml
└── tests
    └── AllTest.php

Dockerfile

FROM --platform=linux/amd64 php:7.4
RUN apt-get update \
 && apt-get install -y git zip libzip-dev
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
WORKDIR /app
RUN composer require --dev phpunit/phpunit:9.5.10

bootstrap.php

<?php
require_once __DIR__ . '/vendor/autoload.php';

docker-compose.yml

version: '3.7'
services:
  app:
    build: ./
    image: phpunit-test
    command: ./vendor/bin/phpunit -c phpunit-config.xml
    volumes:
      - ./bootstrap.php:/app/bootstrap.php
      - ./phpunit-config.xml:/app/phpunit-config.xml
      - ./tests:/app/tests

运行

docker-compose build && docker-compose up

实际输出

...
app_1  | There was 1 failure:
app_1  | 
app_1  | 1) ExampleHelper::testShouldNotBeExecuted
app_1  | Failed asserting that 1 is identical to 0.
app_1  | 
app_1  | /app/tests/AllTest.php:16
app_1  | 
app_1  | FAILURES!
app_1  | Tests: 3, Assertions: 3, Failures: 1.

预期输出

...
app_1  | OK (1 test, 1 assertion)

编辑: 实际项目是一个很大的旧代码库。由于某些文件中有多个类,因此它不遵循 PSR。从长远来看,这应该改变,但目前成本太高。我正在寻找一种需要对现有文件进行最少更改的解决方案,例如只有配置。

顺便说一句。 ExampleHelper 未在早期版本的 PHPUnit 中运行。我猜是 4.8。

【问题讨论】:

一般来说,同一个文件中不会有多个类。 @NigelRen 我知道,但有时你必须使用你得到的东西;) 你的ExampleHelper extends ExampleTest真的很奇怪。 ExampleHelper 类不包含任何测试的目的是什么? 至于如何只运行您想要的类,您可以编写一个自定义的TestSuiteLoader 并使用它,这要归功于testSuiteLoaderClass 配置。 @homer 谢谢,这看起来很有希望。用例很难解释,因为它有点像 hack。 ExampleHelper实例实际上是在ExampleTest的测试方法中创建的,它调用了ExampleHelper的测试方法。 ExampleHelper 覆盖了测试方法使用的ExampleTest 的一些方法。更复杂的是,测试方法继承自使用 TestTemplate 类的特征,该类定义了实际测试,并且可以使用遵循特定命名约定的方法从实际测试类中查询数据,并且可以覆盖模板的默认值. 【参考方案1】:

您的问题至少有 2 个解决方案。

1。重命名非测试函数

PHPUnit's doc 声明:

测试是名为test*的公共方法

因此,更改非测试函数的可见性,或将它们重命名为不以 test 开头应该可以解决您的问题:PHPUnit 不会自动运行这些函数。

2。写一个自定义TestSuiteLoader

如果解决方案 1 不能满足您的需求,您仍然可以编写自定义 TestSuiteLoader 并使用 testSuiteLoaderClass(或 testSuiteLoaderFile)配置属性在配置中声明它。

【讨论】:

关于解决方案1:问题是ExampleHelper extends ExampleTestExampleTest定义了应该为ExampleTest运行的测试方法,但不在子类ExampleHelper中,即不是可以重命名这些测试。

以上是关于PHPUnit:如何仅在以 Test 结尾的类中运行测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何在以特定单词开头并以另一个单词结尾的字符串中出现多次[重复]

Laravel 路由仅在 phpunit 测试期间返回 302 而不是 404 响应

如何仅在更新后触发以“Table_”开头的表的触发器

Javascript 仅在以管理员身份登录时工作

Wordpress 前端仅在以管理员身份登录时有效

如何让 PHPUnit 等待条件测试?