phpunit与项目框架衔接指南
目录
lumen 框架
BaseTestCase
范例:旧版 lumen 框架。
lumen 框架中 TestCase 类,继承了 PHPUnit_Framework_TestCase,基本用法与 phpunit 的用法一致。
为了隔离框架的 TestCase,我们创建了一个 BaseTestCase 类,继承框架的 TestCase,并实现其指定的 createApplication() 方法,创建 lumen 应用,准备应用的单元测试环境。
<?php
namespace tests;
class BaseTestCase extends \Laravel\Lumen\Testing\TestCase
{
public function createApplication()
{
$this->baseUrl = env('APP_URL');
return require __DIR__ . '/../bootstrap/app.php';
}
}
-
所有的单测文件都继承 BaseTestCase。
-
createApplication() 方法是 lumen 单测框架要求实现的抽象方法,用于模拟创建一个
\Laravel\Lumen\Application
。lumen 框架中的单测类,继承 BaseTestCase 类,将创建 lumen app,并自动加载 bootstrap/app.php,确保单元测试过程中能正常加载框架需要的文件。
phpunit.xml
phpunit.xml 文件,用于配置 phpunit 单元测试框架,phpunit 启动时会加载 phpunit.xml 文件中的配置信息,并执行测试用例。
详见【phpunit.xml 配置说明】
单测引导文件
在 BaseTestCase 中我们按 lumen 单测框架要求实现了 createApplication() 方法,所以我们未在 phpunit.xml 中指定引导文件,比如:
bootstrap="tests/bootstrap.php"
YII 框架
BaseTestCase
由于我们一些项目的 php 版本低,且使用了比较低的 phpunit 的版本。phpunit 5.4 之前的版本使用 PHPUnit\Framework\PHPUnit_Framework_TestCase
,之后的版本使用 PHPUnit\Framework\TestCase
,为了隔离这一层命名的变化,我们补充一个 BaseTestCase,方便后续快速调整使用新的 phpunit。
<?php
namespace tests;
use PHPUnit_Framework_TestCase;
class BaseTestCase extends PHPUnit_Framework_TestCase
{
}
phpunit.xml
phpunit.xml 文件,用于配置 phpunit 单元测试框架,phpunit 启动时会加载 phpunit.xml 文件中的配置信息,并执行测试用例。
详见【phpunit.xml 配置说明】
参考:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="tests/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Application Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="build/code-coverage" charset="UTF-8"/>
</logging>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
</php>
</phpunit>
单测引导文件
上面 phpunit.xml 文件中配置了引导文件,即:
bootstrap="tests/bootstrap.php"
我们创建 tests/bootstrap.php,来自于 api\web\index.php,用于加载框架的常量、配置文件、业务类文件等,并创建应用实例,但并不运行应用,使得单测过程中,正常使用到框架的常量、配置文件、业务类文件等。
<?php
// 该文件是 phpunit 的引导文件。
// 定义常量
defined('YII_API_PATH') or define('YII_API_PATH', realpath(__DIR__.'/../api'));
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
// 加载 Composer 自动加载
require __DIR__ . '/../vendor/autoload.php';
// 优先加在的配置出现重复名称后优先级高,hot.env 优先加在避免上线产生影响。
// Bootstrap for hot.env
try {
(new \Dotenv\Dotenv(__DIR__ . '/../', '.env_hot'))->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
// cant load hot.env
}
// 加载环境变量
try {
(new \Dotenv\Dotenv(__DIR__ . '/../', '.env.test'))->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
// 如果找不到测试环境文件,尝试加载普通环境文件
try {
(new \Dotenv\Dotenv(__DIR__ . '/../'))->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
// 如果都找不到,使用默认值
$_ENV['YII_DEBUG'] = true;
$_ENV['YII_ENV'] = 'test';
}
}
// 加载 Yii 框架
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
// 加载通用引导文件
require __DIR__ . '/../common/config/bootstrap.php';
require __DIR__ . '/../api/config/bootstrap.php';
// 合并配置文件
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../common/config/main.php'),
require(__DIR__ . '/../api/config/main.php')
);
// 创建应用实例但不运行
new yii\web\Application($config);
单测范例
单测环境搭建好后,我们在 tests 目录下创建一个测试用例文件,测试单例执行效果:
<?php
namespace tests;
class DemoTest extends BaseTestCase
{
public function testDemo()
{
$cases = [
[
"input" => "123",
"expected" => "123"
],
[
"input" => "124",
"expected" => "124"
],
[
"input" => "125",
"expected" => "125"
],
];
foreach ($cases as $case) {
$this->assertEquals($case["expected"], $case["input"]);
}
}
}
phpunit 对 php 版本的要求
以下是 PHPUnit 5.0 及以上版本对 PHP 版本的要求:
PHPUnit 版本 | PHP 版本要求 |
---|---|
PHPUnit 5.0 - 5.7 | PHP 5.6 - PHP 7.1 |
PHPUnit 6.0 - 6.4 | PHP 7.0 - PHP 7.2 |
PHPUnit 7.0 - 7.5 | PHP 7.1 - PHP 7.3 |
PHPUnit 8.0 - 8.5 | >= PHP 7.2 |
PHPUnit 9.0 - 9.6 | >= PHP 7.3 |
PHPUnit 10.0 - 10.5 | >= PHP 8.1 |
PHPUnit 11.0 - 11.5 | >= PHP 8.2 |
PHPUnit 12.0 - 12.5 | >= PHP 8.3 |
常见问题
找不到业务类
大多是因为 composer 没有重新生成自动加载文件导致。
从错误信息 Error : Class 'App\Services\Pipo\SlogService' not found
,可以推断出在测试文件 SlogServiceTest.php
中引用的 SlogService
类没有被正确加载。一些可能的原因和解决方法:
-
命名空间问题:
- 确认
SlogService
类所在的文件路径和命名空间是否正确。 - 例如,如果
SlogService
类位于app/Services/Pipo/SlogService.php
,则文件内容应如下所示:<?php namespace App\Services\Pipo; class SlogService { // 类内容 }
- 确认
-
自动加载问题:
- 确保 Composer 的自动加载文件已生成并包含在项目中。运行
composer dump-autoload
命令来重新生成自动加载文件。 - 确认
composer.json
文件中的autoload
部分正确配置了App\Services\Pipo
命名空间的路径:"autoload": { "psr-4": { "App\\": "app/" } }
- 确保 Composer 的自动加载文件已生成并包含在项目中。运行
-
文件路径问题:
- 确认
SlogService.php
文件确实存在于app/Services/Pipo/
目录下。
- 确认
-
测试环境配置问题:
- 确认测试环境配置正确,特别是
bootstrap
文件中是否正确加载了 Composer 的自动加载文件。通常在tests/bootstrap.php
或tests/TestCase.php
中会有类似以下的代码:require __DIR__ . '/../vendor/autoload.php';
- 确认测试环境配置正确,特别是
-
更新 composer 文件:
composer dump-autoload
通过以上步骤,应该能够解决 Class 'App\Services\Pipo\SlogService' not found
的问题。如果问题仍然存在,请检查是否有其他配置或环境问题。
参考
PHPUnit Manual — PHPUnit 8.5 Manual
9ong@TsingChan 文章内容由 AI 辅助生成。