ComfyUI CLI Harness 测试指南零依赖 Mock 验证 Workflow、Queue 与图片下载全链路【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything导读本文聚焦 cli-anything-comfyuiComfyUI 命令行代理工具链的测试体系核心解答如何在没有安装、也没有启动 ComfyUI 的前提下完整验证 CLI 的全部功能。读完本文你将掌握该 harness 的测试环境搭建方法、单元测试与端到端模拟测试的运行方式理解其在 backend 层统一拦截 HTTP 的 Mock 策略、--json输出纯净性的保障机制以及覆盖 workflow / queue / models / images / system 五大命令组的测试设计思路——这套方法论可直接复用于任何基于 REST API 的 CLI 项目测试。测试设计前提为什么不需要 ComfyUI 安装cli-anything-comfyui 是cli-anything家族中面向 ComfyUI 的 CLI harness通过 ComfyUI 的 REST API 实现 AI 图像生成工作流管理、提示词队列、模型发现与产物下载。在 测试指南 TEST.md 开头即明确了一条核心测试原则No ComfyUI installation required — all tests use mocked HTTP responses.全部测试在backend 层拦截网络请求从而做到CI 环境无需 GPU、无需下载数 GB 的 checkpoint 模型、无需启动python main.py服务。这一可行性建立在 harness 的分层架构之上——真正发起 HTTP 请求的模块只有一个 comfyui_backend.py其模块注释明确写道This is the only module that makes network requests.于是只要把这一层的四个 HTTP 封装函数替换成可控的返回值上层所有 core 模块与 CLI 命令就能在完全离线的状态下被驱动起来。backend 层暴露给上层调用的四个函数即测试的全部拦截目标函数对应 HTTP语义超时空响应/204 处理api_get(base_url, endpoint, params)GET读取 JSON队列、历史、模型清单、系统状态30s返回{status: ok}api_post(base_url, endpoint, data)POST提交 prompt、interrupt30s返回{status: ok}api_delete(base_url, endpoint, data)DELETE清空队列携带{clear: True}30s返回{status: ok}api_get_raw(base_url, endpoint, params)GET取回图片原始字节/view60s返回resp.content字节流它们对requests.exceptions.ConnectionError / HTTPError / Timeout的统一包装统一转为带上下文提示的RuntimeError见 comfyui_backend.py也正是测试用例中大量断言异常场景抛RuntimeError的验证对象。环境要求与安装按 TEST.md 与 setup.py测试仅需要 Python 与两个测试依赖pip install pytest pytest-cov # 或者安装 harness 时一并带上 dev 附加依赖等价于上面一行 pip install -e .[dev]setup.py 中的extras_require{dev: [pytest7.0.0, pytest-cov4.0.0]}印证了[dev]这一定义python_requires3.10则提示测试运行环境需 Python 3.10。运行时依赖仅click8.0.0与requests2.28.0因此测试环境可以非常轻量。如何运行测试所有测试命令都以comfyui/agent-harness为工作目录包结构为cli_anything.comfyui.*。TEST.md 给出了三档运行粒度# 从 agent-harness 目录运行全部测试 python -m pytest cli_anything/comfyui/tests/ -v # 仅运行单元测试 python -m pytest cli_anything/comfyui/tests/test_core.py -v # 仅运行端到端模拟测试 python -m pytest cli_anything/comfyui/tests/test_full_e2e.py -v # 带覆盖率统计 python -m pytest cli_anything/comfyui/tests/ --covcli_anything.comfyui --cov-reportterm-missing覆盖率命令的--cov作用域精确到整个cli_anything.comfyui包把五个 core/模块、backend 工具模块与 CLI 入口都纳入统计。测试文件名与其职责对应关系如下表tests 目录文件覆盖范围test_core.py全部 core 模块 backend CLI 命令的单元测试test_full_e2e.py模拟校验工作流 → 入队 → 查状态/下载产物的端到端生成流程被测对象一份完备的功能清单TEST.md 将测试目标归纳为七个维度每一维度都能在源码与用例中找到对应实现Workflow 管理load / save / list / validate 的合法与非法输入。对应 workflows.py 的四个函数错误分支包括文件不存在RuntimeError ... not found、非.json后缀、非法 JSON、JSON 根节点不是 dict、保存时自动创建父目录、校验时缺少class_type、inputs非 dict、空工作流仅告警不判失败等。Queue 队列submit prompt、check status、clear、history、interrupt。对应 queue.py 对/prompt、/queue、/history、/interrupt各端点的封装。Models 模型发现checkpoints、LoRAs、VAEs、ControlNets、node info、全部节点类。对应 models.py 对/object_info系列端点的解析。Images 图片列出输出、下载单张、按 prompt 批量下载。对应 images.py。Backend 传输层GET/POST/DELETE/raw 字节包装、连接错误、超时。CLI 命令全部命令组在人类可读与--json两种输出模式下均通过。JSON 纯净性JSON purity--json模式下 stdout 必须是单一可解析文档——不允许混入人类可读摘要行不允许出现确认交互提示污染输出。以上各点并非文档中的抽象承诺而是在 test_core.py 中逐条落地为断言。例如 workflow 校验返回结构{valid, node_count, errors, warnings}、queue 状态返回{queue_running, queue_pending, running_count, pending_count}、queue_prompt 返回{prompt_id, number, node_errors, client_id}均为用例断言的契约字段。Mock 模式一在 backend 层替换 HTTP 函数TEST.md 给出的核心 Mock 手法是用unittest.mock.patch在 backend 层拦截调用——注意补丁目标不是requests.get/post而是 core 模块通过 import 语句直接引用的api_*函数符号from unittest.mock import patch with patch(cli_anything.comfyui.core.queue.api_post, return_value{prompt_id: abc}): result queue_mod.queue_prompt(http://localhost:8188, workflow)由于 queue.py 顶部是from cli_anything.comfyui.utils.comfyui_backend import api_get, api_post, api_delete补丁必须指向cli_anything.comfyui.core.queue.api_post这一消费方命名空间中的符号才能生效。四个模块各自的补丁目标与此同构queue 相关cli_anything.comfyui.core.queue.api_post/.api_get/.api_deletemodels 相关cli_anything.comfyui.core.models.api_getimages 相关cli_anything.comfyui.core.images.api_get_raw与cli_anything.comfyui.core.images.get_prompt_historysystem 相关cli_anything.comfyui.comfyui_cli.api_get这种 Mock 让返回值完全由测试定义可精确构造成功响应 / 服务器拒绝 / 连接失败 / 空响应 / 原始字节流等任意场景。典型用例包括test_queue_prompt_with_client_id断言传给 API 的 body 中client_id与用户提供的一致test_clear_queue_passes_clear_flag通过检查api_delete的调用实参验证{clear: True}被正确透传test_full_e2e.py 中的test_discover_all_model_types则利用mock_api.side_effect [ckpt_resp, lora_resp, vae_resp, cn_resp]让一次 patch 依序喂给四种模型发现命令。Mock 模式二用 Click CliRunner 驱动真实命令行CLI 层测试使用 Click 官方提供的CliRunner把命令行参数作为字符串列表直接灌入真实 CLI 入口从而同时验证参数解析、选项传递与输出格式from click.testing import CliRunner from cli_anything.comfyui.comfyui_cli import cli runner CliRunner() result runner.invoke(cli, [--json, queue, status]) assert result.exit_code 0这里runner.invoke不经过子进程配合外层的with patch(...)即可在真实命令行、模拟服务器的组合下做断言。用例同时关注人类模式与 JSON 模式的行为差异例如test_workflow_validate_human_summary断言人类模式下会输出Workflow is valid.与N error(s) found.而test_workflow_validate_json_output则断言--json模式下 stdout 可直接被json.loads解析且失败时两个 error输出同样保持纯净。陷阱规避JSON 纯净性为何需要真实子进程TEST.md 强调的JSON purity是 Agent 可消费性的关键设计。实现上CLI 用两套输出通道来保证纯净数据走output()人类信息走echo_human()在--json模式下直接 no-op见 comfyui_cli.py 中echo_human的定义需要交互确认的queue clear则通过click.confirm(..., err_json_output)把提示重定向到 stderr源码注释明确写着the prompt goes to stderr so stdout stays parseable。但要测试这种纯净性CliRunner自身反而成了障碍。test_core.py 顶部run_cli_subprocess的 docstring 揭示了原因CliRunneremulates a terminal by echoing the answer typed at a prompt onto stdout — on click 8.2 it lands there even when the prompt itself was sent to stderr. That echo would hide exactly the kind of stdout contamination the JSON-purity tests are looking for, so those tests read the real streams instead.也就是说CliRunner 会把用户对确认提示的回答回显到 stdout从而掩盖真实的 stdout 污染问题。因此 JSON 纯净性测试改用真实子进程读取独立流proc run_cli_subprocess([--json, queue, clear], stdinn\n) assert proc.returncode 1 data json.loads(proc.stdout) # stdout 必须是纯 JSON{type: Abort} assert Clear the queue? in proc.stderr # 人类提示必须出现在 stderrrun_cli_subprocesstest_core.py 中定义会显式设置PYTHONPATH指向 harness 根目录并以subprocess.run调用python -m cli_anything.comfyui.comfyui_cli这是queue clear、以及所有验证交互不污染 JSON场景的标准做法。端到端模拟用 Mock 编排完整生成生命周期test_full_e2e.py 不依赖真实 ComfyUI而是把多条 HTTP 调用串成模拟服务器剧本验证跨命令的完整业务闭环test_queue_and_check_statusvalidate 工作流 →queue prompt返回e2e-prompt-001→queue status全程 exit code 为 0test_queue_then_download入队后在 history 中编排出一张ComfyUI_00001_.png依次执行images list --prompt-id与images download --filename ... --output ...并断言磁盘上落盘字节与 mock 的 PNG 字节完全一致test_json_mode_full_flow--json queue prompt的 stdout 可解析且prompt_id正确test_interrupt_generation/test_clear_queue_and_verifyinterrupt 后返回interruptedclear 后用--json queue status验证 running/pending 均为 0TestErrorHandling连接拒绝、服务器拒绝工作流{error: {message: Node not found: BadNode}}、工作流文件不存在、下载 404 图片等场景均验证了友好的非零退出与错误信息展示。两张用例共用的sample_workflowfixture 是标准 ComfyUI API 格式的最小 SD 生成图CheckpointLoaderSimple → 正/负 CLIPTextEncode → EmptyLatentImage → KSampler → VAEDecode → SaveImage含cfg7, denoise1, seed, steps20, euler/normal等典型参数与 README.md 中介绍的 API 导出格式一致——在实际使用中可从 ComfyUI Web UI 通过Save (API Format)导出此类 JSON。覆盖率之外边界与错误处理验证矩阵综合两份测试文件错误处理被系统性地验证为一张覆盖矩阵均要求触发友好错误JSON 模式为 stdout 上的{error: ..., type: ...}人类模式为 stderr 上的Error: ...场景触发方式断言连接被拒绝api_postside_effect 抛Cannot connect to ComfyUI ...exit code ! 0输出含 Cannot connect服务器拒绝工作流返回{error: {message: Node not found: BadNode}}exit code ! 0文件不存在queue prompt --workflow /nonexistent.jsonexit code ! 0下载目标已存在且未加--overwrite预写同名文件抛RuntimeError(... already exists)prompt 尚未完成就列出图片historycompleted: False抛RuntimeError(... not completed yet)图片请求 404api_get_rawside_effect 抛 404exit code ! 0backend 超时/连接错误直接 patchrequests.get抛Timeout/ConnectionError抛RuntimeError含 timed out / Cannot connectbackend 自身的传输细节也覆盖到位204/空内容返回{status: ok}、api_get_raw原样返回字节含 PNG 魔数断言、HTTP 错误透出状态码与响应文本。当某个模块的 Mock 返回结构与代码预期的 object_info 结构不符时还会触发无法解析 checkpoint 列表一类的RuntimeError防止实现对上游响应格式过于脆弱。总结与适用边界cli-anything-comfyui 的测试体系回答了 CLI-for-Agent 项目测试的三个关键问题测什么功能清单 CLI 五大命令组 backend 传输层、怎么 mock只补丁 backend 层的四个api_*符号让 core 与 CLI 全链路离线可跑、如何保证输出可被程序消费JSON 纯净性通过真实子进程 分流的echo_human/stderr 通道双重保障。值得注意的是其适用前提这些测试验证的是 harness 对 ComfyUI REST API 契约的正确使用而非 ComfyUI 服务端本身的行为——服务端行为验证仍需真实部署。此外若未来 ComfyUI API 返回结构变化需同步更新 Mock 结构测试中刻意构造了意外结构即报错的防御用例可提前暴露此类漂移。对希望将同一套backend 单点拦截 CliRunner 子进程 JSON 纯净性校验模板复用到其他 GUI 软件 CLI 化项目本仓库的 blender、freecad、shotcut 等同族 harness 均遵循相似模式的开发者本文的 TEST.md、test_core.py 与 test_full_e2e.py 是可直接对照的完整参考实现。【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考