tests/ 目录必须与 app/ 同级,TestCase 必须继承 think estingTestCase 并实现 createApplication() 返回 thinkApp 实例,测试文件需以 Test.php 结尾且类名匹配,phpunit.xml 必须配置 bootstrap="vendor/autoload.php" 和 testdox="true"。

tests/ 目录必须和 app/ 同级,不能放在 app/ 下面
ThinkPHP 默认不内置测试目录,phpunit 执行时会从当前工作目录找 phpunit.xml 和 tests/,如果把 tests/ 塞进 app/ 里,phpunit 就找不到测试用例,也加载不了框架引导文件。
正确结构是:
project-root/ ├── app/ ├── public/ ├── tests/
-
tests/TestCase.php要继承think estingTestCase,不是PHPUnitFrameworkTestCase -
tests/下不要放bootstrap.php—— ThinkPHP 的测试基类已自动处理 autoload 和应用初始化 - 如果用
composer require --dev "phpunit/phpunit:^9",注意 PHP 版本兼容性:phpunit:^9要求 PHP >=7.3,TP6.0+ 支持,但 TP5.1 最好用phpunit:^7
TestCase.php 中必须调用 $this->createApplication()
不调这个方法,$this->get()、$this->post()、$this->mock() 全部失效,所有请求测试都会报 Call to a member function bind() on null 或直接抛出 InvalidArgumentException: Application not initialized。
最小可用基类写法:
namespace tests;
<p>use think estingTestCase as BaseTestCase;</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站"><img
src="https://img.php.cn/upload/skill/000/000/081/179040786932301.jpg" alt="btpanel phpsite 宝塔面板PHP网站" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站" class="overflowclass">btpanel phpsite 宝塔面板PHP网站</a>
<p class="overflowclass">宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理</p>
</div>
<a rel="nofollow" href="/xiazai/skill5233" title="btpanel phpsite 宝塔面板PHP网站" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><p>class TestCase extends BaseTestCase
{
protected function createApplication()
{
$app = include <strong>DIR</strong> . '/../thinkphp/start.php';
return $app;
}
}</p>
-
createApplication()返回的是thinkApp实例,不是thinkContainer - 别用
include __DIR__.'/../public/index.php'—— 这是 HTTP 入口,会触发响应输出,导致测试中断 - TP6.1+ 可用
thinkacadeApp::getFacadeRoot()替代,但前提是createApplication()已执行并完成初始化
单元测试文件名必须以 Test.php 结尾,且类名要匹配
PHPUnit 默认只扫描 *Test.php 文件,且要求类名和文件名严格对应,否则直接跳过。比如 UserLogicTest.php 里定义 class UserLogicTest 是对的;写成 class UserTest 就不会被识别。
- 路径不敏感:放在
tests/unit/、tests/feature/都行,只要后缀是Test.php - 命名空间建议和被测代码一致:
appcommonlogicUserLogic对应testsunitcommonlogicUserLogicTest - TP 自带的
$this->mock()只支持对类完整路径 mock,比如$this->mock('appcommonserviceUserService'),写成'UserService'会报Class not found
phpunit.xml 里必须配置 bootstrap 和 testdox
缺 bootstrap 会导致 Composer autoloader 没加载,所有 use 报错;缺 testdox 不影响运行,但会让测试输出变成难读的 testSomething,而不是 “should create user when valid data provided” 这种可读描述。
<?xml version="1.0" encoding="UTF-8"?><phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nonamespaceschemalocation="https://schema.phpunit.de/9.5/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" testdox="true"><testsuites><testsuite name="Unit"><directory>tests/unit</directory></testsuite></testsuites></phpunit>
-
bootstrap="vendor/autoload.php"是必须的,ThinkPHP 的测试基类依赖 Composer 自动加载机制 - 不要写
bootstrap="tests/TestCase.php"—— 这个文件不是启动器,只是基类 - TP6.0+ 若启用了多应用模式,
createApplication()中需显式传入应用名,例如include __DIR__ . '/../thinkphp/start.php'; App::env('app_namespace', 'app\admin');
测试目录看着简单,但 tests/ 放错位置、createApplication() 漏写、类名后缀不统一这三处,占了新人跑不通的 80% 以上。尤其注意 TP 的测试基类不走标准 PHPUnit 生命周期,它自己接管了应用初始化时机。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










