news 2026/9/27 12:07:49

phpMyAdmin 测试套件实战指南:单元测试与 Selenium 端到端测试环境搭建

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
phpMyAdmin 测试套件实战指南:单元测试与 Selenium 端到端测试环境搭建
  • 数据库
  • 后端

【免费下载链接】phpmyadmin

A web interface for MySQL and MariaDB

项目地址:https://gitcode.com/gh_mirrors/ph/phpmyadmin
点击查看免费下载

本指南围绕 tests/README.rst 展开,系统讲解 phpMyAdmin 仓库中tests/目录的组织结构、单元测试与 Selenium 端到端测试的运行原理,以及如何通过环境变量、PHPUnit 配置和 BrowserStack/本地 Selenium 完成测试环境的完整搭建。读完本文,你将掌握 phpMyAdmin 测试套件的目录规划、关键环境变量的含义与取值、本地与云端两种 WebDriver 接入方式,并能直接照着配置跑通登录、建库、查询等端到端场景。

tests 目录的定位与访问保护

phpMyAdmin 的全部测试代码集中在仓库根目录的tests/下,主要包括:

  • tests/unit/:PHPUnit 单元测试,覆盖src/下绝大多数类与控制器(约 160 个控制器测试与大量组件测试);
  • tests/end-to-end/:基于 Selenium WebDriver 的浏览器端到端测试,如LoginTest.php、SqlQueryTest.php、CreateDropDatabaseTest.php、CreateRemoveUserTest.php、ExportTest.php、ImportTest.php等;
  • tests/bootstrap.php与tests/bootstrap-static.php:PHPUnit 引导文件;
  • tests/test_data/:导入导出测试用的样例数据(SQL、CSV、ODS、XML、GIS 数据等);
  • tests/stubs/:静态分析用的 PHP stub 文件;
  • 配套脚本tests/start-local-server与tests/stop-local-server:一键拉起/关闭本地 Web 服务与 Selenium 进程。

文档特别强调:该目录通过.htaccess文件对 Web 访问者进行保护,目的是防止测试数据与内部脚本被外部浏览器直接读取。如果你确实需要允许 HTTP 访问该目录,需要自行在 Web 服务器层(如 Apache 的mod_authz_host模块)配置放行规则;在 nginx 场景下,仓库同样提供了tests/nginx.conf作为端到端测试用的站点配置。默认情况下保持禁止访问即可,这与tests/php.ini中open_basedir限定到%ROOT%的安全策略相互呼应。

单元测试的运行基础

根目录的phpunit.xml定义了测试的组织方式:

  • bootstrap="tests/bootstrap.php":每个测试进程启动时先执行 tests/bootstrap.php,该文件设置TESTSUITE常量、将 PHPprecision固定为 14(避免round(1.2, 2)这类浮点运算出现异常尾数)、开启E_ALL全量错误报告、把时区统一为UTC,并加载app/constants.php与自动加载文件;
  • 两个测试套件:unit(tests/unit目录)与end-to-end(tests/end-to-end目录),默认套件为unit;
  • 覆盖率要求requireCoverageMetadata="true",并在build/logs/下输出 clover 与 junit 报告;
  • 随机执行顺序(executionOrder="random"),同时开启failOnRisky、failOnWarning与输出严格性检查,保证测试质量。

单元测试的基类是 tests/unit/AbstractTestCase.php,它会在每个用例执行前清空$_GET、$_POST、$_COOKIE、$_FILES等超全局变量,重置Current::$server、Current::$database等运行时状态,并清理Cache、Tracker、Config、Twig 模板引擎等静态单例,确保用例之间互不污染。同时仓库在 composer.json 中把PhpMyAdmin\Tests\映射到tests/unit、PhpMyAdmin\Tests\Selenium\映射到tests/end-to-end,并提供composer phpunit、composer test等快捷命令——composer test会依次执行 phpcs、phpstan、psalm 与 phpunit,是整个 CI 的质量入口。

单元测试不需要任何 Web 服务器或数据库,直接执行即可:

composer install composer phpunit # 等价于 vendor/bin/phpunit --color=always

Selenium 端到端测试:前置条件

Selenium 测试要真实驱动浏览器访问 phpMyAdmin 界面,因此文档列出的前提是:一个可访问的 Web 服务器、一个可连接的数据库、以及一个正在运行的 Selenium Hub。测试运行时,PHPUnit 会通过环境变量决定"被测系统"与"驱动浏览器"分别在哪里。

被测系统连接参数

以下四个环境变量描述"被测的 phpMyAdmin 实例":

环境变量用途
TESTSUITE_USER登录被测界面(TESTSUITE_URL)所使用的用户名
TESTSUITE_PASSWORD登录被测界面所使用的密码
TESTSUITE_DATABASE_PREFIX测试库名前缀,文档明确提示避免使用_这类数据库分组字符(避免与 MySQL 分组规则冲突)
TESTSUITE_URL被测 phpMyAdmin 实例的访问 URL,例如http://localhost/phpmyadmin/

从 tests/end-to-end/TestBase.php 的setUp()可以看出,这些参数缺一不可:当TESTSUITE_URL未定义时测试直接跳过;当TESTSUITE_USER未定义时同样跳过并提示可以补充TESTSUITE_PASSWORD;而当TESTSUITE_DATABASE_PREFIX缺失时,getDbPrefix()返回空字符串。每个测试类还会通过bin2hex(random_bytes(4))生成随机库名(getDbPrefix() + 随机串)并执行CREATE DATABASE IF NOT EXISTS,保证用例隔离。

本地 Selenium 参数

如果使用本地 Selenium 服务器,还需要定义:

环境变量用途
TESTSUITE_SELENIUM_HOSTSelenium Hub 所在主机,如127.0.0.1
TESTSUITE_SELENIUM_PORT连接端口,默认习惯为4444
TESTSUITE_SELENIUM_BROWSER使用的浏览器,支持chrome、safari、edge

这些值会由TestBase::hasSeleniumConfig()与getHubUrl()读取并拼装成 WebDriver 端点http://<HOST>:<PORT>/wd/hub。浏览器能力由getCapabilities()构建:默认chrome会附加--lang=en参数并开启浏览器日志收集,safari、edge分支则在 CI 模式下强制指定操作系统与浏览器版本。

phpunit.xml 中的标准配置示例

文档给出了一段可直接放入phpunit.xml的<php>配置片段:

<php> <env name="TESTSUITE_USER" value="root"/> <env name="TESTSUITE_PASSWORD" value="root"/> <env name="TESTSUITE_DATABASE_PREFIX" value="test"/> <env name="TESTSUITE_URL" value="http://localhost/phpmyadmin/" /> <env name="TESTSUITE_SELENIUM_HOST" value="127.0.0.1" /> <env name="TESTSUITE_SELENIUM_PORT" value="4444" /> </php>

注意根目录 phpunit.xml 实际只内置了LC_ALL=C.UTF8环境变量,上述 Selenium 变量需要你自己按需追加,或在 shell 中以export TESTSUITE_...=...的方式导出。二者效果等价,因为TestBase内部全部通过getenv()读取。

端到端测试的登录与查询机制

TestBase还封装了一整套浏览器操作原语,理解它们有助于编写或调试端到端用例:

  • login():先退出已登录状态,等待页面加载完成,在语言选择器可用时切换到 English,然后通过input_username、input_password、input_go三个表单元素完成登录;登录是否成功以server-breadcrumb元素是否存在为标志;
  • dbQuery():在一个独立的 SQL 标签页窗口执行任意 SQL(借助 CodeMirror 注入文本并点击button_submit_query),返回是否出现.result_query .alert-success;
  • createDatabase():为每个测试类创建带随机后缀的独立数据库;
  • skipIfNotPMADB()/fixUpPhpMyAdminStorage():通过index.php?route=/check-relations检查并自动修复 phpMyAdmin 配置存储(pmadb)。

若被测环境尚未配置这些,则可能触发markTestSkipped跳过。整个测试套件根目录还提供了 tests/config.e2e.inc.php,其中以cookie认证方式连接127.0.0.1,并把上传目录指向../tests/test_data/,可作为端到端部署的最小参考配置。

使用 BrowserStack 云端执行

除了本地 Selenium,phpMyAdmin 官方 CI 使用 BrowserStack 云测试服务。文档指出:项目已在 GitHub CI 上运行这些 Selenium 测试;若要在本地复现,需要先安装 BrowserStack Local 工具以打通"本机被测服务 → 云端浏览器"的流量隧道。

只需设置以下两个环境变量,TestBase便会自动切换到云端模式:

环境变量用途
TESTSUITE_BROWSERSTACK_USERBrowserStack 用户名
TESTSUITE_BROWSERSTACK_KEYBrowserStack 访问密钥

getHubUrl()的判定顺序是:只要同时存在TESTSUITE_BROWSERSTACK_USER与TESTSUITE_BROWSERSTACK_KEY,就拼接https://<user>:<key>@hub-cloud.browserstack.com/wd/hub;否则回退到本地 Selenium 地址。addCapabilities()还会根据BUILD_TAG(Jenkins)或GITHUB_ACTION(GitHub Actions)设置bstack:options的构建名、项目名与会话名,方便在 BrowserStack 控制台追溯每次运行。

本地 BrowserStack 完整命令流程

文档给出了基于 PHP 内置服务器的一套完整操作序列,关键步骤与说明如下:

# 1. 在环境中导出 BrowserStack 凭据 export TESTSUITE_BROWSERSTACK_USER=your_username export TESTSUITE_BROWSERSTACK_KEY=your_key # 2. 指定测试运行端口,并据此导出被测 URL export TESTSUITE_PORT=9000 export TESTSUITE_URL=http://127.0.0.1:$TESTSUITE_PORT/ # 3. 启动 PHP 内置服务器 php --server 127.0.0.1:$TESTSUITE_PORT > php.log & # 4. 启动 BrowserStack Local 客户端,将本地流量转发给云端 ~/browserstack/BrowserStackLocal -localIdentifier Manual "$TESTSUITE_BROWSERSTACK_KEY" 127.0.0.1,$TESTSUITE_PORT,0 & # 5. 测试结束后停止 BrowserStack Local ~/browserstack/BrowserStackLocal --daemon stop

逐行解读:

  • 第 2 步把被测地址定为http://127.0.0.1:9000/,与TESTSUITE_URL必须严格对应;
  • 第 3 步启动的 PHP 内置服务器要求 phpMyAdmin 源码可作为文档根目录被访问(实践中也可用 nginx + php-fpm 替代,见下文配套脚本);
  • 第 4 步的 BrowserStack Local 进程会建立一个从云端到本机的安全隧道,-localIdentifier Manual与addCapabilities()中的localIdentifier相呼应,确保云端浏览器请求能落到你的本机服务上;
  • 第 5 步通过守护进程方式停止隧道,避免残留进程占用端口。

配套的一键启动/停止脚本

仓库为 CI 的CI_MODE=selenium场景准备了两个脚本,能显著简化本地复现:

  • tests/start-local-server:仅在CI_MODE=selenium时生效。它会创建一个临时目录,将tests/nginx.conf、tests/php-fpm.conf、tests/php.ini复制进去并把其中的%DIR%、%ROOT%占位符替换为真实路径,随后启动 php-fpm 与 nginx;若配置了 BrowserStack 密钥则自动下载并启动BrowserStackLocal,否则(未设置SKIP_STANDALONE时)通过selenium-standalone启动本地 Selenium,并把临时目录路径记录到/tmp/last_temp_dir_phpMyAdminTests。其中FPM_PATH可覆盖 php-fpm 二进制路径(例如FPM_PATH="php-fpm7.4"),NGINX_PATH同理;
  • tests/stop-local-server:按序停掉 BrowserStack Local、selenium-standalone、nginx 与 php-fpm,并清理临时目录。

配合tests/php.ini(基于生产配置,upload_max_filesize = 512M、post_max_size = 8M、allow_url_fopen = Off等)与tests/nginx.conf,即可获得与 CI 一致的被测环境。

环境变量与 WebDriver 端点选择速查

综合 tests/README.rst 与 tests/end-to-end/TestBase.php 的判定逻辑,可整理出如下决策表:

场景必备环境变量实际连接的 WebDriver 端点
本地 SeleniumTESTSUITE_SELENIUM_HOST+TESTSUITE_SELENIUM_PORThttp://<host>:<port>/wd/hub
BrowserStackTESTSUITE_BROWSERSTACK_USER+TESTSUITE_BROWSERSTACK_KEYhttps://<user>:<key>@hub-cloud.browserstack.com/wd/hub
两者皆无—空,所有用例被markTestSkipped跳过

另外两个可选开关值得留意:TESTSUITE_SELENIUM_COVERAGE与TESTSUITE_FULL在setUp()中作为注解注明"待实现",说明覆盖采集与全量模式是预留能力;而CI_MODE=selenium则控制start-local-server/stop-local-server是否真正执行启动动作。

常见问题与排查思路

  1. 测试全部被跳过:优先检查TESTSUITE_URL、TESTSUITE_USER是否导出;TestBase::setUp()会因这两者缺失直接跳过,并给出明确提示信息。
  2. 数据库前缀冲突:TESTSUITE_DATABASE_PREFIX不要包含_,否则可能与 MySQL 按前缀分组的语义冲突,导致库名匹配异常。
  3. BrowserStack 无法访问本机:确认 BrowserStack Local 隧道已启动、-localIdentifier与能力中的标识一致,且TESTSUITE_URL使用的是隧道能回传的127.0.0.1:<port>地址。
  4. Safari 特定功能不可用:TestBase对 Safari 的键盘输入、鼠标移动、Alert 等操作做了兼容处理,不支持的场景会调用markTestSkipped,这是预期行为而非缺陷(见keys()、moveto()、alertText()的实现)。
  5. pmadb 相关用例失败:通过index.php?route=/check-relations检查配置存储;用例会尝试自动修复,若修复失败则跳过,因此需要被测库具备创建配置存储表的权限。

小结

phpMyAdmin 的测试套件由"无外部依赖的 PHPUnit 单元测试"与"依赖 Web 服务器 + 数据库 + WebDriver 的 Selenium 端到端测试"两层构成。单元测试的基线在 tests/bootstrap.php 与 tests/unit/AbstractTestCase.php 中建立;端到端测试则以TESTSUITE_*系列环境变量为唯一配置入口,由 tests/end-to-end/TestBase.php 统一决策连接本地 Selenium 还是 BrowserStack 云端。只要按 tests/README.rst 给出的参数表完成环境变量与 PHPUnit 配置,再配合start-local-server/stop-local-server脚本,即可在本地完整复现 CI 的浏览器测试链路。

  • 数据库
  • 后端

【免费下载链接】phpmyadmin

A web interface for MySQL and MariaDB

项目地址:https://gitcode.com/gh_mirrors/ph/phpmyadmin
点击查看免费下载

相关推荐

上一篇:使用 Paho-MQTT 为夜灯接入互联网:Raspberry Pi 与虚拟 IoT 设备连接 MQTT 代理实战
下一篇:gpui-kit Combobox 原语:无样式受控搜索选择框的完整实现指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 12:05:03

IT6616桥接芯片详解:HDMI 1.4转MIPI DSI/CSI实战指南

1. 项目概述&#xff1a;为什么一块小芯片能撬动车载与工业显示的底层链路IT6616——这个名字在消费电子圈可能不显山露水&#xff0c;但在车载中控、工业HMI、医疗影像终端、无人机图传模块这些对信号时序和稳定性要求极高的场景里&#xff0c;它几乎是工程师案头常备的“信号…

作者头像 李华
网站建设 2026/9/27 12:01:50

QT自定义控件之储能电站(源码开源)

一、作品展示 先进行咱们这期的作品亮相&#xff1a; 画面主体是储能电站一次主接线图&#xff1a;35kV 母线向下分出 6 组储能支路&#xff0c;每组包含变压器、PCS 变流器、电池簇。每个支路实时展示 Uab、I、P、Q 电气量&#xff0c;下方电池色块用填充高度代表 SOC&#x…

作者头像 李华
网站建设 2026/9/27 11:58:55

万象生鲜系统温度超限自动预警技术是领先关键点

万象生鲜系统通过温度超限自动预警技术&#xff0c;在存储与运输环节确保生鲜产品保持最佳状态。该技术能实时监测温度变化&#xff0c;及时发现异常并发出预警通知相关人员。这不仅提升了产品的安全与质量&#xff0c;也让智能冷链管理发挥着关键作用。凭借这一系统&#xff0…

作者头像 李华
网站建设 2026/9/27 11:51:00

CH32L103低功耗工业MCU实战:RISC-V外设协同与七层功耗优化

1. 为什么CH32L103正在成为工业级低功耗设计的新支点最近三个月&#xff0c;我在三个不同行业的工业项目里反复遇到同一个问题&#xff1a;客户拿着STM32L4系列的BOM清单来问&#xff0c;“有没有更便宜、更省电、还不用交ARM授权费的替代方案&#xff1f;”——不是在谈消费电…

作者头像 李华
网站建设 2026/9/27 11:50:23

V1项目封装实践复盘:从axios拦截器到PCB封装库

这两年做了不少项目封装相关的活儿&#xff0c;V1这个项目是最折腾、也最值得复盘的一个。所谓V1&#xff0c;其实不单指第一个版本&#xff0c;更意味着"第一次把散落的代码、组件、接口、甚至是封装库整理成一个可以稳定复用的体系"。项目里既有前端请求层、AI交互…

作者头像 李华
网站建设 2026/9/27 11:48:56

2026深度解读:Work Agent长程任务如何重塑团队自动化工作流

AI的交互范式&#xff0c;正在从单纯对话问答转向自主执行工作。早期大模型只能完成单轮问答&#xff0c;用户给出一句指令&#xff0c;模型返回一段文本&#xff0c;整个交互过程随对话窗口关闭而终止。随后多轮对话能力落地&#xff0c;AI能够记住上下文&#xff0c;在一段会…

作者头像 李华