- CLI
- 开发工具
- 后端
【免费下载链接】wp-cli
⚙️ WP-CLI framework
WP-CLI 是 WordPress 的官方命令行工具,本仓库(wp-cli/wp-cli)是其框架核心源码。本文以仓库根目录的 AGENTS.md 为骨架,系统讲解向该仓库提交代码时的开发规范、构建与测试命令、编码风格约束,以及基于 Behat 的行为驱动测试(BDD)体系与全部自定义步骤定义,帮助读者掌握 WP-CLI 框架的完整开发与验证流程。
一、仓库定位:一份给 Agent 与开发者的开发指南
AGENTS.md 是 WP-CLI 框架仓库的“开发代理指南”,开篇即说明:本包是 WP-CLI(WordPress 官方命令行接口)的组成部分,关于项目结构与开发工作流的详细解释请参阅主 README.md。
在动手写代码之前,文档要求开发者先做四件事:
- 遵循现有约定:分析现有代码库,理解编码风格、命名约定与架构模式;
- 聚焦本包范围:所有改动必须与本包功能相关,不得发散到无关模块;
- 编写测试:所有新功能与缺陷修复必须附带 Behat 验收测试(位于
features/目录),同时tests/目录下也可能存在 PHPUnit 单元测试; - 更新文档:若改动影响用户可见功能,需同步更新对应的行内代码文档。
其中第 3 点是本项目最鲜明的特色:WP-CLI 框架的测试以行为驱动测试为主,全部功能验收都沉淀在features/目录下的大量.feature文件中(如 features/cli.feature、features/command.feature、features/runner.feature 等),这是后续章节的重点。
二、构建与运行:最小化检查矩阵
AGENTS.md 给出了一套“改动类型 → 最小检查命令”的对应关系,这是日常开发中最实用的速查表:
| 你改了什么 | 需要运行 |
|---|---|
| 任意 PHP 文件 | composer phpcs -- <file>与composer phpstan |
| 有单元测试覆盖的逻辑 | composer phpunit -- --filter <TestName> |
| 单个 feature 文件 | composer behat -- features/<name>.feature |
| 单个场景(Scenario) | composer behat -- features/<name>.feature:<line> |
核心思想是“只跑覆盖你改动的最窄检查”,避免无谓的耗时。例如只改了一个 PHP 文件,就先做代码风格与静态分析;改动了被单元测试覆盖的逻辑,就用--filter精确到某个测试类/方法。
失败后的重跑策略
composer behat-rerun:只重新运行上次失败的场景;composer behat -- --stop-on-failure:遇到第一个失败即停止,而不是跑完所有场景。
这两条命令对应 composer.json 中的behat-rerun与behat脚本,它们在长时间运行的 Behat 套件下能大幅缩短迭代周期。
全量测试composer test:谨慎运行
composer test会运行全部套件,包括整个 Behat 套件。文档特别提醒:
- 在大多数包中,这意味着每个场景都要从零安装一次 WordPress,整个流程需要数十分钟;
- 需要
jq、MySQL/MariaDB 客户端以及预先准备好的测试数据库; - 需要访问 WordPress.org 的网络权限(下载安装包)。
因此它只适合在改动涉及跨模块(cross-cutting)内容、准备开 Pull Request 之前运行;不要为了验证两行改动去跑全量测试。在 composer.json 中可以看到test脚本由@lint、@lint-gherkin、@phpcs、@phpstan、@phpunit、@behat六个子任务按顺序串联而成。
环境变量:让工具输出干净可读
在运行上述命令前,建议先设置两个环境变量,让工具以紧凑的纯文本方式报告问题,而不是把进度条和 ANSI 颜色画进你回读的输出里:
export NO_COLOR=1 export WP_CLI_TEST_QUIET=1绿色 ≠ 通过 CI
文档明确提示:本地composer test全绿不等于CI 全绿。actionlint(GitHub Actions 工作流检查)与typos(拼写检查)也在每次 Pull Request 上运行,但它们并不属于composer test的一部分。这意味着提交前还应对照 CI 配置自查这两项。
三、Composer 命令速查
项目使用 Composer 管理依赖并驱动脚本(脚本定义见 composer.json 的scripts段),常用命令如下:
| 命令 | 作用 |
|---|---|
composer install | 安装依赖 |
composer test | 运行完整测试套件:lint、gherkin 风格检查、代码风格、静态分析、单元测试与行为测试 |
composer lint | 检查语法错误 |
composer lint-gherkin | 检查 Behat feature 文件的风格规范 |
composer phpcs | 检查代码风格违规 |
composer phpcbf | 自动修复代码风格违规 |
composer phpstan | 运行静态分析 |
composer phpunit | 运行单元测试 |
composer behat | 运行行为驱动测试 |
值得注意的是,phpcs、phpstan、phpunit、behat等脚本在 composer.json 中实际委托给wp-cli/wp-cli-tests包提供的工具函数(run-phpcs-tests、run-phpstan-tests、run-php-unit-tests、run-behat-tests等),因此运行composer test前需先composer install并通过 composer.json 的require-dev安装好wp-cli/wp-cli-tests。
四、编码规范:WP_CLI_CS 与 PHP_CodeSniffer
项目遵循WP_CLI_CS编码标准,由 PHP_CodeSniffer 强制执行,配置位于 phpcs.xml.dist。提交代码前需运行:
composer phpcs # 检查违规 composer phpcbf # 自动修复违规从 phpcs.xml.dist 源码可以看到该规则的几个关键细节:
- 基于
WP_CLI_CS规则集,仅放行while控制结构中的赋值表达式(Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition); testVersion设置为7.2-,即通过 PHPCompatibility 检查代码对 PHP 7.2 及以上版本的兼容性(与 composer.json 中php: >=7.2.24 || ^8.0的要求一致);- 使用
WordPress.NamingConventions.PrefixAllGlobals要求全局命名空间中的类、函数均以前缀命名,并为钩子函数额外放行cli_前缀; - 对
tests/data/、bundle/等目录整体排除检查。
行内文档原则
文档要求“尽量只写高价值注释”,不要通过注释“跟用户对话”——即注释应解释代码意图而非复述显而易见的逻辑。
五、测试体系总览
项目拥有包含单元测试、行为测试与静态分析在内的完整测试体系,全部测试会在每次 Pull Request 时由 GitHub Actions 运行。
| 测试类型 | 框架 | 位置 | 配置 |
|---|---|---|---|
| 单元测试 | PHPUnit | tests/ | phpunit.xml.dist |
| 行为驱动测试 | Behat | features/ | behat.yml |
| 静态分析 | PHPStan | — | phpstan.neon.dist |
单元测试(PHPUnit)
单元测试位于tests/目录,配置在 phpunit.xml.dist:引导文件为tests/bootstrap.php,测试套件扫描tests目录下所有*Test.php文件,并将php/目录纳入覆盖率统计。
从 tests/bootstrap.php 可以看到引导流程:定义WP_CLI_ROOT、加载 Composer 自动加载器、引入php/utils.php与php/dispatcher.php、注册bundle/rmccue/requests的 Requests 自动加载器,并加载测试专用的wpdb.php与 mock HTTP 传输层。
phpunit.xml.dist 还开启了严格的失败语义:convertErrorsToExceptions、convertWarningsToExceptions、convertNoticesToExceptions、convertDeprecationsToExceptions均为true,任何级别的 PHP 告警都会让测试失败。
编写单元测试的约定:继承基类WP_CLI\Tests\TestCase。例如 tests/UtilsTest.php 中的class UtilsTest extends TestCase,并通过set_up_before_class()调用WP_CLI::get_runner()->init_config()完成运行器配置初始化。同类测试还包括 tests/RunnerTest.php、tests/FormatterTest.php、tests/CommandFactoryTest.php 等。
行为驱动测试(Behat)
行为测试用 Behat 编写,配置在 behat.yml:默认套件使用WP_CLI\Tests\Context\FeatureContext上下文,扫描features目录。
从 features/command.feature 可以看到典型场景——用Given an empty directory准备环境,用When I run \wp help --help`执行命令,再用Then STDOUT should contain:` 断言输出:
Scenario: Registered WP-CLI commands Given an empty directory When I run `wp help --help` Then STDOUT should contain: """ wp help [<command>...] """features/runner.feature 则展示了wp-cli.yml配置与--path参数处理的验证,而 features/utils.feature 演示了When I try(期望失败输出)、Then STDERR should contain、Then the return code should be 1的组合用法:
Scenario Outline: Check that `proc_open()` and `proc_close()` aren't disabled for `Utils\run_mysql_command()` When I try `{INVOKE_WP_CLI_WITH_PHP_ARGS--ddisable_functions=<func>} --skip-wordpress eval "WP_CLI\Utils\run_mysql_command( null, array() );"` Then STDERR should contain: """ Error: Cannot do 'run_mysql_command': The PHP functions `proc_open()` and/or `proc_close()` are disabled """ And STDOUT should be empty And the return code should be 1注意:如果测试中预期命令产生错误输出,必须使用
When I try ...而不是When I run ...,否则 Behat 会直接把错误当作运行失败处理。
静态分析(PHPStan)
phpstan.neon.dist 显示该项目在level 9(最高严格级别)下扫描php/commands、php/WP_CLI、php/*.php与tests目录,启用 bleedingEdge 配置与 strictRules(uselessCast、closureUsesThis等),并通过scanDirectories把bundle/rmccue/requests与vendor/wp-cli/wp-cli-tests纳入分析范围。
六、Behat 自定义步骤定义全解
WP-CLI 在 Behat 之上封装了一套自定义步骤定义(step definitions),用于编写 feature 测试。下文按 Given / When / Then 三类完整列出。
Given 步骤(准备阶段)
| 步骤 | 作用 |
|---|---|
Given an empty directory | 创建空目录 |
Given an empty|non-existent <name> directory | 创建或删除指定目录 |
Given an empty cache | 清空 WP-CLI 缓存目录 |
Given a <name> file:/Given a <name> cache file: | 以给定内容创建文件 |
Given "<a>" replaced with "<b>" in the <name> file | 用正则表达式对文件做查找替换 |
Given that HTTP requests to <url> will respond with: | 模拟对指定 URL 的 HTTP 请求响应(由 tests/includes/mock-requests-transport.php 提供底层支持) |
Given WP files | 下载 WordPress 文件但不安装 |
Given wp-config.php | 通过wp config create生成 wp-config.php |
Given a database | 创建空数据库 |
Given a WP install(ation) | 安装 WordPress |
Given a WP install(ation) in :subdir | 在指定子目录安装 WordPress |
Given a WP install(ation) with Composer | 用 Composer 安装 WordPress |
Given a WP install(ation) with Composer and a custom vendor directory :vendor_directory | 用 Composer 安装 WordPress 并指定自定义 vendor 目录 |
Given a WP multisite (subdirectory\|subdomain)? install(ation) | 安装 WordPress Multisite |
Given these installed and active plugins: | 安装并激活一个或多个插件 |
Given a custom wp-content directory | 配置自定义wp-content目录 |
Given download: | 将多个文件下载到指定位置 |
Given save (STDOUT\|STDERR) <contents>? as {<var>} | 将 STDOUT 或 STDERR 内容存入变量 |
Given a new Phar with (the same version\|version "<ver>") | 以指定版本构建新的 WP-CLI Phar 文件 |
Given a downloaded Phar with (the same version\|version "<ver>") | 从 GitHub 下载指定版本的 WP-CLI Phar |
Given save the <name> file <contents>? as {<var>} | 将指定文件内容存入变量 |
Given a misconfigured WP_CONTENT_DIR constant directory | 修改 wp-config.php 将WP_CONTENT_DIR设为空字符串 |
Given a dependency on current wp-cli | 将wp-cli/wp-cli添加为 Composer 依赖 |
Given a PHP built-in web server | 在当前目录启动 PHP 内置 Web 服务器 |
Given a PHP built-in web server to serve :subdir | 在指定子目录启动 PHP 内置 Web 服务器 |
When 步骤(执行阶段)
| 步骤 | 作用 |
|---|---|
When I launch in the background \`` | 后台启动给定命令 |
When I (run\|try) \`| 运行或尝试运行给定命令(try` 用于预期失败场景) | |
When I (run\|try) \` from ' | 在指定子目录中运行或尝试运行命令 |
When I (run\|try) the previous command again | 再次运行或尝试上一条命令 |
Then 步骤(断言阶段)
| 步骤 | 作用 |
|---|---|
Then the return code should( not)? be <n> | 断言上一条命令的退出码 |
Then (STDOUT\|STDERR) should( strictly)? (be\|contain\|not contain): | 断言 STDOUT/STDERR 的内容(strictly表示严格比较) |
Then (STDOUT\|STDERR) should be a number | 断言输出为数字 |
Then (STDOUT\|STDERR) should not be a number | 断言输出非数字 |
Then STDOUT should be a table containing rows: | 断言 STDOUT 为包含给定行的表格 |
Then STDOUT should end with a table containing rows: | 断言 STDOUT 以包含给定行的表格结尾 |
Then STDOUT should be JSON containing: | 断言 STDOUT 为合法 JSON |
Then STDOUT should be a JSON array containing: | 断言 STDOUT 为合法 JSON 数组 |
Then STDOUT should be CSV containing: | 断言 STDOUT 为包含特定值的 CSV |
Then STDOUT should be YAML containing: | 断言 STDOUT 为包含特定内容的 YAML |
Then (STDOUT\|STDERR) should be empty | 断言输出为空 |
Then (STDOUT\|STDERR) should not be empty | 断言输出非空 |
Then (STDOUT\|STDERR) should be a version string (<\|<=\|>\|>=\|==\|=\|<>) <ver> | 断言输出为与给定版本比较的版本字符串 |
Then the <name> (file\|directory) should( strictly)? (exist\|not exist\|be:\|contain:\|not contain): | 断言文件/目录(不)存在或包含特定内容 |
Then the contents of the <name> file should( not)? match <regex> | 用正则匹配文件内容 |
Then (STDOUT\|STDERR) should( not)? match <regex> | 用正则匹配 STDOUT/STDERR |
Then an email should (be sent\|not be sent) | 断言(未)发送邮件 |
Then the HTTP status code should be :code | 断言访问http://localhost:8080的 HTTP 状态码 |
这些步骤与 features/ 目录下数十个 feature 文件一一对应,例如 features/help.feature 大量使用Then STDOUT should contain,features/validation.feature 使用Then the return code should be验证参数校验,features/context.feature 使用Given a WP install(ation)准备运行上下文。读者在新增场景时,应先在这些既有文件中寻找相近的模式进行模仿,保持风格一致。
七、测试编写约定与提交前自检清单
测试约定
- 先看既有测试:新增测试前先阅读现有测试,遵循既定模式;
- 单元测试:继承基类
WP_CLI\Tests\TestCase; - Behat 测试:只能运行 composer.json 中安装的 WP-CLI 命令(
require-dev中声明的wp-cli/db-command、wp-cli/entity-command、wp-cli/extension-command等命令包才可用)。
提交前自检清单
- 改动 PHP 文件 → 运行
composer phpcs -- <file>与composer phpstan; - 改动有单测覆盖的逻辑 → 运行
composer phpunit -- --filter <TestName>; - 修改/新增 feature 文件 → 运行
composer behat -- features/<name>.feature,失败后可用composer behat-rerun精准重跑; - 涉及跨模块改动 → 设置
NO_COLOR=1与WP_CLI_TEST_QUIET=1后运行composer test; - 额外检查 CI 中会运行、但本地
composer test不覆盖的actionlint与typos。
文档同步
AGENTS.md 还提醒:README.md 可能是通过wp scaffold package-readme从代码库动态生成的。若改动影响用户可见行为,需要修改代码库中对应的文档源(如命令的 PHPdoc),而非直接手改 README;同时遵循“只写高价值注释”的行内文档原则。
通过以上流程,开发者可以在保持 WP-CLI 框架高质量标准的前提下,快速、精准地完成代码贡献的验证闭环——从最小化检查到全量测试,从编码规范到行为驱动测试步骤的熟练运用。
- CLI
- 开发工具
- 后端
【免费下载链接】wp-cli
⚙️ WP-CLI framework
相关推荐
Farm 仓库中的测试驱动开发(TDD)实战指南:从 Red-Green-Refactor 到仓库级测试基建
Farm 仓库中的测试驱动开发(TDD)实战指南:从 Red Green Refactor 到仓库级测试基建 导读 本文以 Farm 仓库中 .agents/s
前端构建构建工具开发工具深入 Valkey 仓库:从构建、单元测试到集成测试的 AGENTS.md 开发指南
深入 Valkey 仓库:从构建、单元测试到集成测试的 AGENTS.md 开发指南 本指南以仓库根目录的 AGENTS.md https://link.git
KV存储缓存数据库node-crawler 仓库开发与测试指南:从 AGENTS.md 读懂构建、测试与架构约定
node crawler 仓库开发与测试指南:从 AGENTS.md 读懂构建、测试与架构约定 导读 AGENTS.md 是本仓库面向 AI Agent(以及所
网页爬虫
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考