资讯动态

ComfyUI-Impact-Pack 端到端(E2E)测试策略实战:隔离启动、基线冒烟与真实工作流验证

发布时间:2026/10/14 1:01:48 来源:尧图企业网站定制
AI 应用计算机视觉图像处理【免费下载链接】ComfyUI-Impact-PackCustom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more.项目地址https://gitcode.com/gh_mirrors/co/ComfyUI-Impact-Pack点击查看免费下载本篇技术指南以仓库中的 E2E_TEST_STRATEGY.md 为骨架结合 tests/e2e_dd_compat.py、modules/impact/utils.py、modules/impact/segs_nodes.py 等源码系统讲解如何在真实 ComfyUI 运行时中验证 Impact Pack从--disable-all-custom-nodes--whitelist-custom-nodes的隔离启动、Playwright 冒烟基线到通过/promptAPI 提交 Detailer 工作流、轮询/history、用/view下载产物并做像素级断言的完整链路。读完本文你将掌握一套可复现、可扩展的 E2E 测试模板能独立编写自己的工作流级回归测试。一、E2E 测试的目标与范围端到端E2E测试验证的是 ComfyUI Impact Pack 在真实 ComfyUI 运行时中的表现而不仅是单元级的断言结果。它的核心目标是捕捉只有在完整加载整个技术栈时才会暴露的回归问题包括服务启动、节点注册、REST API 响应、前端页面加载以及通过/promptAPI 完成的真实工作流执行。为什么需要隔离式 E2E开发者日常使用的 ComfyUI 通常装有大量自定义节点任何其中一个都可能导入失败、打印警告、注册前端路由或遮蔽 Impact Pack 的行为在干净环境中运行 Impact Pack 可以消除干扰噪音产生可复现的结果--disable-all-custom-nodes与--whitelist-custom-nodes组合使用可以把 Impact Pack及其配套子包与其他所有已安装自定义节点隔离同时仍允许它们正常加载。本策略验证的内容ComfyUI 服务在加载 Impact Pack 与 Impact Subpack 后能够正常启动前端页面被正常提供并渲染出 ComfyUI 应用外壳/object_infoREST 端点返回两个包的完整节点目录存在基线节点数量与预期的节点名称样本防止节点注册静默回退Detailer 工作流通过/promptAPI 执行并产生非退化的输出证明完整推理链路detector → SEGSDetailer → SEGSPaste端到端跑通。明确不在范围内通过 UI 创建与连接节点见文末扩展点超出像素差 sanity 检查的视觉回归测试性能基准测试。二、前置条件环境要求组件要求Python 3.12Playwright (Python) 1.58.0Chromium 运行时通过playwright install chromium安装ComfyUI 仓库Checkout 在custom_nodes/comfyui-impact-pack的父目录Impact Pack作为自定义节点安装即本仓库Impact Subpack与 Impact Pack 一起安装提供 Ultralytics / SAM 节点类型目录布局E2E 测试假定标准的 ComfyUI 自定义节点布局ComfyUI/ ├── main.py ├── custom_nodes/ │ ├── comfyui-impact-pack/ ← 本仓库 │ └── comfyui-impact-subpack/ ← detector / SAM 节点提供者 └── ...安装命令# 在 ComfyUI 仓库根目录执行 pip install playwright playwright install chromiumImpact Pack 自身的 Python 依赖预期已安装参见 pyproject.toml包含segment-anything、scikit-image、opencv-python-headless、numpy、dill、sam2等。Impact Subpack 有自己独立的依赖列表请按其文档说明安装。模型资源依赖 Detailer 的工作流需要磁盘上的模型文件请放到以下 ComfyUI 相对路径路径用途models/checkpoints/SD1.5/realcartoonPixar_v8.safetensorsCheckpointLoaderSimple使用的 SD1.5 checkpoint任何兼容的 SD1.5 checkpoint 均可需相应调整工作流的ckpt_namemodels/ultralytics/bbox/face_yolov8m.ptUltralyticsDetectorProvider使用的人脸 bbox 检测器models/sams/sam_vit_b_01ec64.pth工作流包含SAMLoader时使用的 SAM 权重input/ComfyUI_00156_.png参考工作流中LoadImage使用的人像图需清晰可见人脸注意Ultralytics 与 SAM 节点类本身由 Impact Subpack 提供——安装 subpack 是这些节点类型的交付载体与上述模型权重是两回事。纯 冒烟基线 测试不需要任何上述资源只有工作流命中 detector 或 loader 节点时才需要。三、服务启动Server Launch默认启动方式以 Impact Pack 和 Impact Subpack 作为仅有的两个激活自定义节点启动隔离的 ComfyUI 实例这是除纯冒烟层之外所有测试的默认方式# 工作目录ComfyUI 仓库根目录custom_nodes/ 的父目录 python main.py \ --disable-all-custom-nodes \ --whitelist-custom-nodes comfyui-impact-pack comfyui-impact-subpack \ --port 18188大多数 Detailer 工作流依赖UltralyticsDetectorProvider、SAMLoader及相关 detector/segmenter 节点类型这些由 Impact Subpack 提供。不带 subpack 启动时这些节点类不会注册任何引用它们的工作流都会在 prompt 校验阶段失败。最小启动方式仅冒烟对于纯 API 冒烟路径——页面加载 /object_info检查不执行工作流——仅 Impact Pack 即可python main.py \ --disable-all-custom-nodes \ --whitelist-custom-nodes comfyui-impact-pack \ --port 18188这种最小启动不足以支撑依赖检测的工作流测试仅在测试内容为启动 /object_info检查时使用。参数说明Flag用途--disable-all-custom-nodes跳过custom_nodes/中所有自定义节点的导入消除无关插件带来的副作用--whitelist-custom-nodes comfyui-impact-pack comfyui-impact-subpack只重新启用列出的文件夹名支持空格分隔的多个值--port 18188绑定非默认端口避免与开发者日常运行在 8188 的 ComfyUI 实例冲突预期启动日志标记启动后服务日志应包含类似如下内容### Loading: ComfyUI-Impact-Pack (V8.28.2) ### Loading: ComfyUI-Impact-Subpack (Vversion) Skipping other-custom-node due to disable_all_custom_nodes and whitelist_custom_nodes ... To see the GUI go to: http://127.0.0.1:18188Skipping ...行确认了隔离生效其他自定义节点在磁盘上存在但未被加载。最后的To see the GUI ...行确认服务已就绪、可以接受连接。这条加载日志的源码位置在init.py即logging.info(f### Loading: ComfyUI-Impact-Pack ({impact.config.version}))版本号由 modules/impact/config.py 中的version_code [8, 28, 3]生成当前仓库对应V8.28.3pyproject.toml 中version 8.28.3可交叉印证。判断启动日志时应以日志中出现Loading: ComfyUI-Impact-Pack前缀为准不必死板匹配具体小版本号。四、基线冒烟测试Baseline Smoke Test冒烟测试确认隔离服务同时提供了前端页面与节点目录设计得刻意小巧除 Playwright 外无任何外部依赖。测试脚本# e2e_smoke.py # Usage: python e2e_smoke.py # Preconditions: # - ComfyUI is running at http://127.0.0.1:18188 with Impact Pack AND # Impact Subpack whitelisted (default launch). # - Playwright Python chromium runtime are installed. from playwright.sync_api import sync_playwright BASE_URL http://127.0.0.1:18188 REQUIRED_SUBPACK_NODES { UltralyticsDetectorProvider, SAMLoader, SAMDetectorCombined, SAMDetectorSegmented, } def main() - None: with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_context().new_page() # 1. Frontend page loads page.goto(f{BASE_URL}/, wait_untilnetworkidle) title page.title() assert ComfyUI in title, fUnexpected page title: {title!r} # 2. /object_info returns the node catalog resp page.request.get(f{BASE_URL}/object_info) assert resp.status 200, f/object_info HTTP {resp.status} object_info resp.json() # 3. Impact Pack nodes are registered impact_nodes [name for name in object_info if name.startswith(Impact)] assert len(impact_nodes) 85, ( fImpact node count regression: got {len(impact_nodes)}, expected 85 ) # 4. Impact Subpack nodes are registered missing REQUIRED_SUBPACK_NODES - set(object_info.keys()) assert not missing, fSubpack nodes missing: {sorted(missing)} print(fTitle: {title}) print(fTotal nodes: {len(object_info)}) print(fImpact nodes: {len(impact_nodes)}) print(fSample: {impact_nodes[:3]}) browser.close() if __name__ __main__: main()预期输出在 Impact Pack v8.28.2 Impact Subpack 的隔离服务双包白名单的默认启动上观测到的基线为Title: *Unsaved Workflow - ComfyUI Total nodes: 858 Impact nodes: 87 Sample: [ImpactSegsAndMask, ImpactSegsAndMaskForEach, ImpactFlattenMask]另有 Subpack 贡献的节点名验证存在UltralyticsDetectorProvider、SAMLoader、SAMDetectorCombined、SAMDetectorSegmented。具体数值会随代码演进而漂移上述断言校验的是最低契约而非字面相等。例如Impact前缀的节点在 modules/impact 各节点文件中以CATEGORY ImpactPack/...组织参见 segs_nodes.py 的SEGSDetailer新增节点会自然改变计数断言阈值应当随发布刻意调整而不是盲目放宽。五、工作流执行 E2EWorkflow Execution E2E冒烟基线只确认节点注册不验证执行逻辑。工作流执行 E2E 把具体图提交给/prompt轮询/history/{prompt_id}直到完成再从/view下载输出产物检查——它能捕捉到目录级检查看不见的推理路径回归。API 模式POST /prompt — 提交 {prompt, client_id}收到 {prompt_id} GET /queue — running pending prompts进度监控 GET /history/{prompt_id} — 执行完成后返回状态 输出 GET /view?filename... — 下载单个输出产物PNG 等/history轮询周期约 3 秒即可prompt 仍在执行时该端点返回空对象完成后才会完整填充。Flat Prompt 格式/prompt端点期望扁平图一个以节点 ID 为键的 dict每个值是{class_type, inputs}。socket 连接表示为两元素列表[上游节点ID, 输出槽索引]。PROMPT { ckpt: { class_type: CheckpointLoaderSimple, inputs: {ckpt_name: SD1.5/realcartoonPixar_v8.safetensors}, }, pos: { class_type: CLIPTextEncode, inputs: {clip: [ckpt, 1], text: a detailed face, sharp focus}, }, img: { class_type: LoadImage, inputs: {image: ComfyUI_00156_.png}, }, detector: { class_type: UltralyticsDetectorProvider, inputs: {model_name: bbox/face_yolov8m.pt}, }, detail: { class_type: SEGSDetailer, inputs: { image: [img, 0], segs: [bbox_segs, 0], # ... sampler knobs elided ... noise_mask_feather: 20, # non-zero triggers DifferentialDiffusion path }, }, }陷阱子图蓝图Blueprint从 ComfyUI UI 导出的工作流 JSON 可能包含高层蓝图节点例如workflow/Impact::MAKE_BASIC_PIPE。这些是模板/子图引用由 UI 在客户端展开不能作为class_type直接提交给/prompt。程序化 E2E 必须在提交前把蓝图展开为其具体构成节点。例如MAKE_BASIC_PIPE蓝图展开为CheckpointLoaderSimple → (model, clip, vae) CLIPTextEncode (positive prompt) CLIPTextEncode (negative prompt) ToBasicPipe (model, clip, vae, positive, negative)这正是仓库参考实现 tests/e2e_dd_compat.py 的做法它显式构造ckptCheckpointLoaderSimple、pos/negCLIPTextEncode与pipeToBasicPipe五个节点把model/clip/vae/positive/negative五路输入接进ToBasicPipe产出BASIC_PIPE供SEGSDetailer的basic_pipe输入使用。参考实现tests/e2e_dd_compat.py是经过验证的参考工作流覆盖关键 Detailer 路径LoadImage → UltralyticsDetectorProvider → BboxDetectorSEGS → SEGSDetailer(noise_mask_feather20) # activates DifferentialDiffusion compat → SEGSPaste → PreviewImage (paste output) → PreviewImage (untouched input)通过标准提交返回 HTTP 200 并带prompt_id/history/{prompt_id}最终报告status.status_str success且无execution_error消息两个预期的PreviewImage输出都出现在history[prompt_id].outputs中输入预览与 paste 预览尺寸一致paste 预览具有非退化统计量std 1.0paste 预览与输入存在差异abs(mean_delta) 0.005或abs(std_delta) 0.005——完全相同意味着 Detailer 路径从而 DifferentialDiffusion 兼容垫片被绕过了。参考图像观测到的典型差值mean_delta ≈ 0.01、std_delta ≈ 0.03。数值小是因为SEGSPaste只重写被裁剪的人脸区域画面大部分像素未改动并在求差时被抵消。源码层面的支撑noise_mask_feather与 DifferentialDiffusion 兼容垫片为什么这个测试特别关注noise_mask_feather20从源码看Impact Pack 在多个 Detailer 实现中都有一个统一的激活条件。例如 modules/impact/segs_nodes.py 中SEGSDetailer.do_detailif not (isinstance(model, str) and model DUMMY) and noise_mask_feather 0 and denoise_mask_function not in model.model_options: model utils.apply_differential_diffusion(model)相同的模式还出现在 modules/impact/impact_pack.py、modules/impact/core.py 与 modules/impact/segs_upscaler.py后者还先对noise_mask做tensor_gaussian_blur_mask高斯羽化。也就是说只要noise_mask_feather 0且模型尚未挂上denoise_mask_function就会调用utils.apply_differential_diffusion包装模型——这是 E2E 能确定性触发该兼容垫片的最小开关。而apply_differential_diffusion本身modules/impact/utils.py是一个跨版本兼容垫片ComfyUI ≥ 0.3.63 暴露 V3 schema类方法execute旧版本使用实例方法apply。实现采用延迟导入comfy_extras.nodes_differential_diffusion随后按hasattr(dd, execute)/hasattr(dd, apply)分派两者都不存在则抛出带升级提示的AttributeError。测试注释中也写明该 E2E 的首要目的就是确保SEGSDetailer推理不会在 DifferentialDiffusion 上抛AttributeError——这正是跨 ComfyUI 版本回归最容易出现的地方。断言细节为什么输出与输入相同是失败tests/e2e_dd_compat.py中测试会下载两张预览 PNG经/view取回二进制后用PIL解码、numpy统计 mean/std然后要求mean_delta或std_delta至少达到 0.005。逻辑是SEGSPastesegs_nodes.py 定义功能为把 SEGSDetailer 增强后的 SEGS 贴回原图支持feather高斯羽化与alpha透明度合成若正常执行必然改写人脸区域像素若输出与输入逐位统计完全相同只能说明 detailer 分支被跳过例如模型被替换为DUMMY、is_mask_all_zeros导致 segment skip此时测试失败并提示detailer likely didnt run。加上std 1.0的非退化检查双重防止全图贴黑/贴平这类假通过。六、验证标准Verification Criteria冒烟测试在所有以下条件同时成立时才判定PASS#标准如何验证1服务启动日志包含Loading: ComfyUI-Impact-Pack检查服务 stdout / 日志尾部2服务启动日志包含Loading: ComfyUI-Impact-Subpack默认启动检查服务 stdout / 日志尾部3日志包含针对至少一个其他自定义节点的Skipping ... due to disable_all_custom_nodes and whitelist_custom_nodes当安装了其他节点时检查服务日志4http://127.0.0.1:18188/返回 HTTP 200 且页面标题包含ComfyUIpage.goto(...)page.title()5GET /object_info返回 HTTP 200 且 JSON bodypage.request.get(...).status与.json()6/object_info中至少 85 个Impact前缀节点名统计name.startswith(Impact)的键数7必需的 Subpack 节点存在UltralyticsDetectorProvider、SAMLoader、SAMDetectorCombined、SAMDetectorSegmented与object_info键做集合成员检查基线阈值 85 选在观测值 87 之下是为了容忍少量节点重命名/删除的重构不会触发误报。新节点发布时应刻意上调阈值下调必须附有经过评审的解释。工作流执行测试的通过标准因场景而异见各参考实现旁的逐条标准。七、操作注意事项Operational Notes缓存失效Cache BustingComfyUI 在节点输入完全相同时会跨运行缓存采样器输出这可能掩盖回归——工作流看起来通过了实际只是在重放一次缓存的成功。策略使用时机每次运行随机化种子seed int(time.time()) 0xFFFFFFFF默认方案对含采样器的节点是最便宜的失效手段完全重启服务修改了modules/impact/内或已加载包中的 Python 源码之后清理modules/impact/__pycache__/当.pyc可能相对编辑后的.py过期时参考实现 tests/e2e_dd_compat.py 正是采用_SEED int(time.time()) 0xFFFFFFFF保证每轮执行的seed输入都不同从源头避免采样缓存重放。重启服务时先杀掉旧实例并确认端口空闲再重新启动pkill -9 -f python main.py # 稍等片刻然后确认测试端口上已无进程在监听 curl -fsS http://127.0.0.1:18188/system_stats echo still up || echo port free只有探测报告端口空闲后才重新启动。在垂死进程仍持有 socket 时启动会产生令人困惑的address already in use错误。仓库还提供了现成的辅助脚本 tests/restart_test_server.sh它封装了杀旧进程 → 后台启动 → 轮询curl就绪探测的完整流程默认端口 8188可用第一个参数覆盖。验证内部代码路径确实被执行工作流级通过标准status_str success、无异常、非零像素差只证明图端到端跑完了不能证明某个特定内部函数被触达——静默绕过兼容垫片的 bug 依然可能返回success。要确认某个分支确实执行可临时在目标处打标记# modules/impact/utils.py (temporary) import logging def apply_differential_diffusion(...): logging.warning([E2E-MARKER] apply_differential_diffusion:execute) ...运行工作流后在服务日志中 grep 标记grep E2E-MARKER /tmp/server.log在status_str success的前提下标记缺席意味着该代码路径被跳过——通常是因为上游分派选择了别的分支。提交代码前务必移除标记。日志文件解码tqdm采样器、detector、SAM 都会用到输出的进度条写入的是回车符\r而非换行会把长运行折叠成日志文件中的一行物理文本导致朴素grep只能看到最终的进度状态。grep 前先归一化tr \r \n /tmp/server.log | grep -F [E2E-MARKER]或者在 Python 中with open(/tmp/server.log, r, errorsreplace) as f: text f.read().replace(\r, \n)八、扩展点Extension Points冒烟与参考工作流测试是基线验证层未来的 E2E 场景应建立在同样的隔离启动地基之上参考测试实现tests/e2e_dd_compat.py是经过验证的工作流覆盖 LoadImage → UltralyticsDetectorProvider → BboxDetectorSEGS → SEGSDetailer → SEGSPaste → PreviewImage演示了完整的/prompt/history/view生命周期与像素差断言模式。把它当作新工作流执行测试的标准模板。更多工作流场景除 Detailer 兼容路径外值得做的工作流级测试包括FaceDetailer 端到端KSampler 生成的人脸 pipe、cycle 1的 SEGSDetailer迭代细化、MASK_TO_SEGS SEGSPaste掩码驱动编辑、以及 Impact Switch / Pipe 节点控制流回归。UI 驱动的节点创建用 Playwright 打开前端从节点库把 Impact 节点拖到画布并连接输入/输出验证前端元数据category、显示名、输入 schema与后端定义保持同步。节点签名回归检测为某个已知良好版本快照完整的/object_info载荷再与当前响应 diff。标记任何输入类型、输入名、输出类型或输出数量的变化作为发布前防止公共 API 意外破坏的守卫。Headed 模式调试交互式调试时用headlessFalse启动 Playwright可加slow_mo500并在失败点配合page.pause()检查实时浏览器状态browser p.chromium.launch(headlessFalse, slow_mo500) # ... later ... page.pause() # opens Playwright Inspector跨浏览器覆盖在p.chromium、p.firefox、p.webkit上参数化浏览器启动器。Impact Pack 的前端面很薄但跨浏览器验证可以守卫未来前端功能引入的回归。九、与本仓库其他测试资产的关系除本 E2E 策略外仓库 tests 目录还包含完整的 Wildcard 系统测试体系tests/README.mdtest_encoding.sh、test_edge_cases.sh、test_deep_nesting.sh、test_ondemand_loading.sh、test_dynamic_prompts_full.sh等 7 个套件每个套件在独立端口启动专用 ComfyUI 服务、配置测试 wildcard 路径、自动清理并输出/tmp/*_test.log。这套体系与本 E2E 策略共享独立端口 独立服务生命周期的基础设施哲学但验证目标不同Wildcard 套件聚焦动态提示词引擎的统计与边界行为而本策略聚焦真实运行时全栈加载 真实推理执行。两者配合即可覆盖 Impact Pack 从配置解析到推理产物的完整质量面。十、小结一套可靠的 E2E 测试并不复杂但必须抓住三个关键点隔离--disable-all-custom-nodes--whitelist-custom-nodes双旗标是消除环境噪音、保证可复现的基石配套--port避免与日常实例冲突分层先做无模型的冒烟基线页面 /object_info契约再做真实工作流执行/prompt/history/view 像素断言两层各有独立通过标准防假通过随机化 seed 破除采样缓存、对noise_mask_feather 0的 DifferentialDiffusion 路径做像素差校验、必要时用日志标记确认内部分支真实执行——这三招能识别绝大多数表面成功、实际绕过的回归。以 tests/e2e_dd_compat.py 为模板你可以低成本地把任何 Impact Pack 工作流改造成可复现的 E2E 回归测试。赞分享AI 应用计算机视觉图像处理【免费下载链接】ComfyUI-Impact-PackCustom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more.项目地址https://gitcode.com/gh_mirrors/co/ComfyUI-Impact-Pack点击查看免费下载相关推荐ComfyUI-Impact-Pack 通配符系统测试套件实战7 套测试脚本、端口隔离与源码级验证ComfyUI Impact Pack 通配符系统测试套件实战7 套测试脚本、端口隔离与源码级验证 本文为 ComfyUI Impact Pack 的 WilAI 应用计算机视觉图像处理devenv 交互式 Shell 冒烟测试基于真实 PTY 的端到端验证方案devenv 交互式 Shell 冒烟测试基于真实 PTY 的端到端验证方案 本篇指南介绍 devenv 仓库中 devenv shell/tests/REA开发工具CLIcli-anything-calibre 两阶段验证体系全解析无后端冒烟测试与真实 Calibre E2E 验证实战cli anything calibre 两阶段验证体系全解析无后端冒烟测试与真实 Calibre E2E 验证实战 本文以 PR 223 的 Calibre人工智能AI AgentAI 技能工具调用CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑