news 2026/9/10 9:04:37

CLI-Anything WireMock Harness 实战:用终端命令与 Agent 原生化方式管理 HTTP Mock 服务器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CLI-Anything WireMock Harness 实战:用终端命令与 Agent 原生化方式管理 HTTP Mock 服务器

CLI-Anything WireMock Harness 实战:用终端命令与 Agent 原生化方式管理 HTTP Mock 服务器

【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything

本文以仓库内 WIREMOCK.md 标准操作流程(SOP)为骨架,系统讲解cli-anything-wiremock这一将 WireMock Admin REST API(/__admin/)封装为命令行工具的实现与用法。你将掌握如何启动 WireMock Standalone、通过环境变量或 CLI 参数连接服务器、创建与管理 stub、验证请求日志、驱动有状态场景、录制真实后端流量,以及如何以--json机器可读输出把整个 Mock 生命周期交给脚本或 AI Agent 自动化。

WireMock 与 CLI Harness 的定位

WireMock 是一个灵活的 HTTP Mock 服务器,专门用于 stub(打桩)与录制 HTTP 交互。它通过__admin/前缀暴露 REST Admin API,用来管理 stub、检视请求、控制有状态场景(scenario),以及从真实后端录制流量。在集成测试环境中,WireMock 常被用来以可控的 Mock 响应替代真实 HTTP 后端。

cli-anything-wiremock的价值在于:把上述 Admin 端点包成一族终端子命令,使 Agent 和开发者不必手写原始 HTTP 调用,即可在终端或脚本中完成对 WireMock 的完整控制。整个命令入口定义在 wiremock_cli.py 中,底层通过 client.py 中的WireMockClientrequests做薄封装,统一拼接{scheme}://{host}:{port}/__admin{path}并透传 Basic Auth 与超时参数。

启动 WireMock Standalone

下载

从 Maven 中央仓库下载指定版本(文档示例为 3.3.1)的 standalone JAR:

curl -fsSL https://repo1.maven.org/maven2/org/wiremock/wiremock-standalone/3.3.1/wiremock-standalone-3.3.1.jar \ -o wiremock-standalone.jar

默认端口启动(8080)

java -jar wiremock-standalone.jar --port 8080 --verbose

--verbose会在控制台打印每个收到请求的详细信息,便于调试 stub 匹配过程。

使用持久化 mappings 目录启动

java -jar wiremock-standalone.jar \ --port 8080 \ --root-dir ./wiremock-data \ --verbose

指定--root-dir后,WireMock 会把mappings/目录中的 JSON 文件在启动时加载为 stub,并可在运行时通过 Admin API 的save操作落盘,实现"重启不丢 stub"的持久化工作流。

启用 HTTPS

java -jar wiremock-standalone.jar \ --port 8443 \ --https-port 8443 \ --verbose

同时监听 8443 的 HTTP 与 HTTPS 端口。对应地,CLI 端需要把WIREMOCK_SCHEME--scheme设为https才能正确握手(WireMock 默认使用自签名证书,测试环境中通常需要信任该证书或关闭校验)。

Docker 方式(备选)

docker run -d --name wiremock \ -p 8080:8080 \ wiremock/wiremock:latest

安装 CLI

进入 harness 目录后以可编辑模式安装,并验证命令可用:

cd /path/to/agent-harness pip install -e . cli-anything-wiremock --help

setup.py 声明了包名cli-anything-wiremock(版本 0.1.0),依赖click>=8.0requests>=2.28rich>=13.0,并要求 Python>=3.10;安装时通过entry_points把控制台脚本cli-anything-wiremock指向 wiremock_cli.py 中的cli入口组。README 中的 Quick Start 也给出了同样的安装与三条验证命令(status / stub quick / request count),见 wiremock README。

连接配置:环境变量与 CLI 标志

所有连接参数均可通过环境变量或 CLI 标志设置。在 session.py 的Session.from_env()中,先读取环境变量构造默认会话;随后 wiremock_cli.py 会用显式传入的 CLI 标志覆盖同名环境变量——即CLI 标志优先级高于环境变量

环境变量CLI 标志默认值说明
WIREMOCK_HOST--hostlocalhostWireMock 主机名
WIREMOCK_PORT--port8080WireMock 端口
WIREMOCK_SCHEME--schemehttphttphttps
WIREMOCK_USER--user(无)Basic Auth 用户名
WIREMOCK_PASSWORD--password(无)Basic Auth 密码
WIREMOCK_JSON--jsonfalseJSON 输出模式

连接远程 WireMock 实例的示例:

export WIREMOCK_HOST=wiremock.internal export WIREMOCK_PORT=9090 cli-anything-wiremock status

两个细节值得说明:

  • Basic Auth 只有在usernamepassword同时设置时才会生效,Session.auth()会返回(user, password)元组;只设置其一则返回None(见 session.py 及对应单测test_auth_returns_none_when_partial)。
  • WIREMOCK_PORT环境变量在解析失败(非数字)时会安全回退到默认值8080,不会导致程序崩溃。
  • 健康检查通过GET /__admin/health完成,超时 3 秒;非 200 或抛异常均判定为"未运行"(见 client.py)。

Stub 工作流:从快速打桩到批量导入

stub 相关命令由stub命令组承载,底层封装在 stubs.py 的StubsManager中,逐一对应 WireMock 的/mappings系列端点。

1. 验证服务器运行

cli-anything-wiremock status

2. 创建简单 stub

快速形式(Quick Form):METHOD URL STATUS_CODE [--body JSON]

cli-anything-wiremock stub quick GET /api/users 200 --body '{"users":[]}'

该命令对应stub_quick(wiremock_cli.py),支持--body--content-type(默认application/json)。其底层quick_stub()实现(stubs.py)会自动将 METHOD 转为大写,组装{"request": {"method", "url"}, "response": {"status", ...}}后 POST 到/mappings;只有传入--body时才会附加bodyheaders.Content-Type。这一点在单测test_quick_stub_with_body/test_quick_stub_no_body/test_quick_stub_method_uppercased中有明确验证。

完整 JSON 形式:

cli-anything-wiremock stub create '{ "request": { "method": "POST", "url": "/api/orders" }, "response": { "status": 201, "body": "{\"id\":42}", "headers": { "Content-Type": "application/json" } } }'

stub create还支持@file.json语法——参数以@开头时,CLI 会读取该文件并解析为 JSON 映射,方便把大型 stub 定义放在版本管理文件中(见 wiremock_cli.py)。

3. 列出所有 stub

cli-anything-wiremock stub list cli-anything-wiremock stub list --json # 机器可读

stub list还支持--limit--offset分页参数(透传给/mappings?limit=&offset=,见 stubs.py)。人类可读模式下会用表格展示 ID(前 8 位)、Name、Method、URL、Status,并显示总数。

4. 获取单个 stub

cli-anything-wiremock stub get <stub-id>

对应GET /mappings/{id}(stubs.py),ID 为 WireMock 生成的 UUID。

5. 删除 stub

cli-anything-wiremock stub delete <stub-id>

6. 重置全部 stub 为默认

cli-anything-wiremock stub reset

对应POST /mappings/reset,会把内存中的 stub 恢复为磁盘(root-dir)上的默认映射。

7. 持久化 stub 到磁盘

cli-anything-wiremock stub save

对应POST /mappings/save,将当前内存中的 stub 写入root-dir/mappings/,与启动时的--root-dir配合形成闭环。

8. 从文件导入 stub

cli-anything-wiremock stub import ./my-stubs.json

对应POST /mappings/import,一次导入整个{"mappings": [...]}批量定义。

此外,StubsManager还实现了文档之外的update(stub_id, mapping)PUT /mappings/{id})与find_by_metadata(pattern)POST /mappings/find-by-metadata,可基于 metadata 的 JsonPath 表达式检索 stub),适合在自动化流水线中做"先查询后更新"的操作(见 stubs.py)。

请求验证:断言系统是否真的按预期调用了 Mock

request命令组封装了 requests_log.py 的RequestsLog,用于检视 WireMock 的请求日志(serveEvents)。

# 列出最近的请求 cli-anything-wiremock request list cli-anything-wiremock request list --limit 10 # 按模式查找请求 cli-anything-wiremock request find '{"method": "GET", "url": "/api/users"}' # 统计匹配请求数(适合做断言) cli-anything-wiremock request count '{"method": "POST", "urlPath": "/api/orders"}' # 列出未匹配的请求(即 404) cli-anything-wiremock request unmatched # 清空请求日志 cli-anything-wiremock request reset
  • request list人类可读模式以表格输出 ID、Method、URL、Status、Matched(wasMatched字段),可快速发现哪些请求命中了 stub、哪些没有。
  • request find/request count使用 WireMock 的匹配器语法(methodurlurlPathurlPatternbodyPatterns等)作为 JSON pattern 传入,对应POST /requests/findPOST /requests/count
  • request unmatched对应GET /requests/unmatched,是排查"为什么 404"的核心工具;RequestsLog还暴露了near_misses_unmatched()GET /requests/unmatched/near-misses)用于查看"近似匹配但未命中"的请求,便于修正 stub 匹配条件(见 requests_log.py)。
  • request reset底层是DELETE /requests,清空整个请求日志,适合在每个测试用例前调用以保证断言隔离。

一个典型的测试断言模式是"先 clear → 触发被测系统 → count 校验次数",例如确认支付接口恰好被调用一次:cli-anything-wiremock --json request count '{"method":"POST","url":"/api/payment"}'返回{"count": 1}

有状态场景测试(Scenarios)

WireMock 支持用状态机(scenario)模拟多步骤工作流——同一 URL 在不同状态返回不同响应。scenario命令组对应 scenarios.py 的ScenariosManager

# 列出所有场景及其当前状态 cli-anything-wiremock scenario list # 将指定场景设置到某个状态 cli-anything-wiremock scenario set "login-flow" "logged-in" # 重置所有场景到初始状态 cli-anything-wiremock scenario reset
  • scenario list对应GET /scenarios,表格展示 Name、Current State、Possible States,可直观观察状态机推进情况。
  • scenario set对应PUT /scenarios/{name}/state,body 为{"state": "..."};实现中用urllib.parse.quote(name, safe='')对场景名做 URL 编码,确保含空格或特殊字符的场景名也能正确传递(见 scenarios.py)。
  • scenario reset对应POST /scenarios/reset,把所有场景拉回初始状态,保证用例间互不影响。

典型用法是配合request组:先scenario set推进状态,再触发被测系统调用,最后用request count验证每个状态分支被正确执行。

录制真实后端流量(Recording)

当手写 stub 成本过高时,可以用录制功能让 WireMock 作为代理把请求转发给真实后端并自动生成 stub。record命令组对应 recording.py 的RecordingManager

# 开始录制——把流量代理到真实后端 cli-anything-wiremock record start https://api.example.com # ... 让被测系统向 http://localhost:8080 发请求,流量会被代理并捕获 ... # 停止录制并检视捕获到的 stub cli-anything-wiremock record stop # 检查是否正在录制 cli-anything-wiremock record status # 将内存中的请求快照为 stub cli-anything-wiremock record snapshot
  • record start <target_url>对应POST /recordings/start,请求体为{"targetBaseUrl": "..."};还支持可重复的--match-header选项,指定要捕获的请求头(如AuthorizationX-Api-Key),底层会构造captureHeaders字典并以caseInsensitive: true匹配(见 recording.py),让录制的 stub 在真实场景中更容易命中。
  • record stop对应POST /recordings/stop,返回mappings列表;人类可读模式会报告"捕获了 N 个 stub"。
  • record status对应GET /recordings/status
  • record snapshot对应POST /recordings/snapshot,可在不停止录制的情况下,把当前内存中的请求生成为 stub(RecordingManager.snapshot()支持传入自定义 spec,例如{"persist": false})。

录制工作流尤其适合"先用真实后端跑一遍 → 自动生成 stub 库 → 后续测试完全离线"的契约测试场景。

服务器管理:版本、设置与生命周期

查看版本与全局设置

# 查看 WireMock 版本 cli-anything-wiremock settings version # 获取全局设置 cli-anything-wiremock settings get

settings命令组对应 settings.py 的SettingsManagerget读取GET /settings(含fixedDelaygzipDisabledrequestJournalDisabled等全局开关),version读取GET /versionSettingsManager同样实现了update(settings)PUT /settings,如设置全局固定延迟),可满足延迟注入等高级需求。

全量重置与关闭

# 全量重置(stubs + requests + scenarios) cli-anything-wiremock reset # 关闭服务器 cli-anything-wiremock shutdown
  • reset直接向/reset发送 POST,一次性清空 stub、请求日志与场景状态,是每个测试套件收尾的"一键还原"命令(见 wiremock_cli.py)。
  • shutdown带有确认提示(--confirmation_option,交互式执行时会询问确认);底层向/shutdown发 POST,并把服务器主动断开连接视为正常成功——实现中捕获ConnectionError后输出 "Shutdown signal sent",而不是报错(见 wiremock_cli.py)。

JSON 输出模式:为脚本与 Agent 准备的机器可读接口

所有命令都支持--json,用于脚本或 Agent 调用:

cli-anything-wiremock --json stub list cli-anything-wiremock --json request count '{"method":"GET","url":"/health"}'

JSON 输出因命令类型而异(注意:这是区分类型的响应,而非统一的信封包装):

  • 数据类命令直接返回 WireMock API 的原始 JSON。例如stub list返回{"mappings": [...], "total": N}stub quick返回创建的 stub 完整对象(含id)。
  • Void 操作(delete、reset、save 等)返回{"status": "ok"}
  • status命令返回{"status": "running"|"stopped", "host": "...", "port": N}
  • 错误返回{"status": "error", "message": "..."},且以非零退出码退出;人类可读模式下错误信息打印到 stderr(见 output.py 的print_json/success/error实现,以及 test_core.py 中TestOutputFunctions对退出码与 JSON 结构的断言)。

对于 Agent 场景的推荐实践(来自 SKILL.md 的 Agent Guidance):

  1. Agent 上下文中一律使用--json,保证输出可被程序化解析;
  2. 连接参数优先走环境变量WIREMOCK_HOST/WIREMOCK_PORT),避免每条命令重复携带参数;
  3. 采用"先建 stub → 运行被测系统 →request count断言 →reset清理"的四步验证模式。

源码结构速览

文件(仓库相对路径)职责
wiremock_cli.pyClick 命令组入口:stub/request/scenario/record/settings/status/reset/shutdown
utils/client.pyWireMockClient:拼接/__admin前缀,封装 GET/POST/PUT/DELETE/PATCH 与 Basic Auth、30 秒超时
utils/output.pyprint_json/print_table/success/error,表格优先用 rich 渲染,缺依赖时回退 ASCII 表格
core/session.py从环境变量构建连接会话,CLI 标志优先覆盖
core/stubs.py/mappings全套 CRUD + reset/save/import/find-by-metadata + quick_stub
core/requests_log.py/requests列表、查找、计数、unmatched、near-misses、清空
core/scenarios.py场景列表、状态设置(URL 编码)、重置
core/recording.py录制启停、状态、快照,支持captureHeaders
core/settings.py全局设置读取/更新、版本查询

测试保障

test_core.py 采用unittest.mock拦截 HTTP 调用,无需真实服务器即可验证:WireMockClient的 base_url 拼接与 Auth 透传、Session.from_env的默认值与环境变量读取、StubsManager各方法的请求路径与 JSON body(含quick_stub的大写化与 Content-Type 逻辑)、RequestsLog的 find/count/unmatched 路径、ScenariosManager的 state 设置、RecordingManagertargetBaseUrlcaptureHeaders,以及输出工具的错误退出码(SystemExit(1))。仓库还提供tests/test_full_e2e.py用于真实 WireMock 端到端验证,详见 tests/TEST.md。

端到端实践模式

综合上述全部能力,一个可复制的 Agent 化测试循环如下:

# 1. 启动(持久化目录) java -jar wiremock-standalone.jar --port 8080 --root-dir ./wiremock-data --verbose & # 2. 确认连接 cli-anything-wiremock --json status # 3. 先打桩:模拟支付成功 cli-anything-wiremock --json stub quick POST /api/payment 200 --body '{"success":true}' # 4. 运行被测系统,让它向 http://localhost:8080 发请求 ... # 5. 断言:支付接口被调用且恰好一次 cli-anything-wiremock --json request count '{"method":"POST","url":"/api/payment"}' # 6. 排查 404:查看未匹配请求 cli-anything-wiremock request unmatched # 7. 录制真实后端流量以扩展 stub 库(可选) cli-anything-wiremock record start https://api.example.com # ... 回放流量 ... cli-anything-wiremock record stop cli-anything-wiremock stub save # 持久化到 ./wiremock-data/mappings # 8. 收尾:全量重置 cli-anything-wiremock reset

这套流程把"启动服务器 → 打桩 → 触发 → 断言 → 排查 → 录制 → 落盘 → 清理"的完整 Mock 生命周期压缩为若干条可复现的 CLI 命令,既服务于手工调试,也能被 CI 流水线或 AI Agent 以--json输出直接消费,正是"Making ALL Software Agent-Native"理念在 HTTP Mock 管理场景的具体落地。

【免费下载链接】CLI-Anything"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything

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

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

Vercel AI SDK 文件交付全攻略:从上传到验收的闭环实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 8:59:11

电机起动方式与降压控制详解:星三角、软起动与变频器

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 8:58:23

基于Python Django与Vue的前后端分离分类信息网站开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 8:55:05

Neovim 如何用 --remote 把文件直接打开到已运行的实例中?

Neovim 如何用 --remote 把文件直接打开到已运行的实例中&#xff1f; 【免费下载链接】neovim Vim-fork focused on extensibility and usability 项目地址: https://gitcode.com/GitHub_Trending/ne/neovim 当你已经在一个 Neovim 实例里工作&#xff08;比如带着 LSP…

作者头像 李华
网站建设 2026/9/10 8:52:44

物理AI:从统计拟合到机制理解的范式跃迁

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华