mcpField
B
behave

behave

本地服务
github.com/emirmrkaljevic开发工具41 天前更新

关于 behave

behave 将 CLI 的行为记录为测试用例,并可对原工具或另一实现重放。它面向移植、重构或比较命令行工具的开发者,规格可审阅并用于 CI。

主要功能

  1. 01根据帮助文档生成用例
  2. 02记录标准输出、错误输出和退出码
  3. 03对另一实现重放用例
  4. 04统计文档所列选项的覆盖率
  5. 05规范化可变输出并识别不稳定用例
  6. 06生成供 CI 使用的 JUnit 报告

适用场景

  1. 01检查 CLI 重写版本的兼容性
  2. 02发现重构或升级后的回归
  3. 03比较两个命令行实现
  4. 04跟踪选项测试情况并在 CI 中报告

MCP 相关

MCP 服务提供运行命令、生成和扩展行为规格、列出用例,以及将实现与记录行为进行比较的工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
mcpbbehave_0.1.7_linux_amd64.mcpb
mcpbbehave_0.1.7_linux_arm64.mcpb
mcpbbehave_0.1.7_darwin_amd64.mcpb
mcpbbehave_0.1.7_darwin_arm64.mcpb

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

behave

支持我的开源工作:购买 SkinToScan 套装
如果你觉得这个项目有用,可以购买 SkinToScan 套装来支持我,这是我的另一个项目。这是一次性购买,收入将直接用于资助我的开源工作。

购买单张图片检查,€4.49 购买 5 张图片套装,€19.99(热门) 购买 15 张图片套装,€54.99

记录任意 CLI 的行为,证明你的重写版本行为一致。

behave 将命令行工具视为黑盒。它会读取 --help(以及 man 页面), 生成数百个测试用例(覆盖每个标志、标志对、帮助中列出的每个标志取值、 stdin 边界情况、文件参数、错误取值、缺失文件),记录工具的实际行为(stdout、stderr、退出码), 并针对另一个实现重放这些用例。

behave 记录 jq 并据此检查 gojq

适用于以下场景:

  • 将工具移植到 Rust 或 Go,并希望证明移植版本兼容;
  • 重构或升级 CLI,并希望在几秒内建立回归防护网;
  • 比较同一工具的两个实现。

状态:早期版本(v0.1)。CLI 和 MCP 服务已可用;欢迎反馈。

快速开始

使用 Homebrew(macOS 和 Linux)安装,从 Releases 下载二进制文件,或使用 go install:

brew install emirmrkaljevic/tap/behave
# or: go install github.com/emirmrkaljevic/behave/cmd/behave@latest

# 1. record how GNU sort behaves (writes ./behave-sort/)
behave probe sort

# 2. check that the recording is stable
behave run behave-sort

# 3. compare another implementation against it
behave diff behave-sort --impl ./target/release/sort --skip-tag meta

也可以先尝试已提交的示例:behave run examples/cut(27 个 GNU cut 用例)、 behave run examples/paste(18 个 GNU paste 用例)、behave run examples/join(26 个 GNU join 用例)、behave run examples/nl(26 个 GNU nl 用例)、behave run examples/fold(28 个 GNU fold 用例),或 behave run examples/jq(33 个 jq 1.7 用例);请参阅 examples/。

对于需要位置参数(过滤器、模式、字段列表)的工具,请提供样例:

behave probe jq --arg . --arg '.a' --arg '.[]' --arg 'map(.+1)' --arg keys
behave diff behave-jq --impl gojq --ignore-stderr

如果帮助文本列出了标志可接受的取值,probe 会在错误取值用例旁为每个取值添加一个用例。它支持 GNU 风格(WHEN can be: auto, always, never、--sort=WORD ... to WORD: none (-U), size (-S), ...、The WHEN argument defaults to 'always' and can also be 'auto' or 'never'.)、clap 的 [possible values: ...]、argparse 的 {json,yaml} 和 <fast|safe>。它只保留能够关联到相应标志的纯小写列表。--dry-run 会显示它找到的内容:

$ behave probe ls --dry-run
       --color                      WHEN  {always,auto,never}
       --sort                       WORD  {none,size,time,version,extension,name,width}

输出示例(节选):

✗ flag --output-delimiter, value -1, arg -f1  0135-flag-output-delimiter-value-1-arg-f1.yaml
  $ cut --output-delimiter -1 -f1
  exit:
    exit: want 0, got 1
  stdout:
    - hello

flags with differences:
  --output-delimiter             2/16  cases differ
flags fully compatible: 9 of 10

cut vs ./uu/cut: 172/175 passed, 3 failed, 0 skipped  (differs in: exit 2, stdout 3)  [0.1s]

首日发现结果

在此机器上针对真实工具运行,仅使用生成的用例,并排除 --help/--version:

原版候选版本用例数通过数显著差异
GNU wc 9.7uutils wc 0.12.06363无
GNU headuutils head5151无
GNU uniquutils uniq100100无
GNU truutils tr6363无
GNU tac 9.12uutils tac (main)3635拒绝 -s -1(值以 - 开头,#15497,现已修复)
GNU tail 9.12uutils tail (main)6058接受不带计数的 -c(#15528,现已修复);文件名如 007 被打印为 7(#15533,现已在 tail 中修复);手动添加的 -cf FILE 用例被拒绝(#15517)
GNU cutuutils cut175172拒绝 --output-delimiter -1(值以 - 开头)
GNU base64uutils base643631对无效输入使用 -d:GNU 会打印已解码的字节,uutils 不打印任何内容
GNU sortuutils sort290~260†用法错误的退出码是 1 而非 2;--debug 下划线宽度;--check --merge
jq 1.7gojq 0.12.19596331*不支持的标志(--seq、--ascii-output、…)、键顺序、大数格式

* 使用 --ignore-stderr;几乎所有情况下的错误消息措辞都不同。 † 结果会有一两个用例的浮动:有些 --random-sort 用例在输入极小时,有时才会被检测为不稳定。

其中许多是有意为之的设计选择,并非 bug。behave 只是让它们显现出来。 请记录改写实际针对的版本。uutils 会跟随最新的 GNU 版本,而 GNU 9.12 在 tail -v 标头中会打印 ==> 'standard input' <==,9.7 则不带引号,因此基于旧版 GNU 记录的规格会报告一些实际上是 GNU 变更造成的差异。behave.yaml 会保留所记录工具的 --version 行,run/diff 会在回放版本旁打印该行。 其中一些是真正的 bug,现已在上游修复:

仍未解决:uutils sort -c dir 会以 0 退出且不显示消息,而不是报告读取错误(uutils/coreutils#15615,修复见 #15616);另外还有一些错误消息会丢失文件名,这些问题大多由 v0.1.7 中新增的“文件名末尾带斜杠”探测用例发现:

  • cp f/ dest 会打印 Not a directory (os error 20),而不是 cannot stat 'f/': Not a directory(#15691,修复见 #15692)
  • paste 打开和读取文件出错时未显示文件名(#15254,修复见 #15642)
  • shred dir 会显示 Not a file,而不是 failed to open for writing: Is a directory(#15630,修复见 #15631)
  • mv missing/ g 会显示 Not a directory,而对不可搜索的 d 执行 mv d/f g 会显示 No such file or directory;GNU 会给出真正的原因(#15704,修复见 #15705)

MCP 服务

behave mcp 通过 stdio 提供相同的功能,因此编码助手可以探索原始工具,在工作过程中扩展规范,并在每次更改后检查其移植版本。

{
  "mcpServers": {
    "behave": { "command": "behave", "args": ["mcp"] }
  }
}
工具功能
behave_exec在临时目录中运行一次命令,返回退出状态、stdout 和 stderr(用于探索)
behave_probe根据 --help 生成并记录规范
behave_add_case添加一个测试用例,并记录原始工具的行为
behave_list_cases列出测试用例,可按标签筛选(flag:--sort、manual)
behave_diff针对某个实现重放测试用例,并返回带差异的失败用例

规范格式

规范是一个可提交并审查的目录:

behave-cut/
  behave.yaml           # command, timeout, normalizers, recorded_from (--version line)
  cases/
    0001-help.yaml
    0135-flag-output-delimiter-value-1-arg-f1.yaml
    ...
name: flag --output-delimiter, value -1, arg -f1
args: [--output-delimiter, "-1", -f1]
stdin: |
  hello
tags: [flag-value, "flag:--output-delimiter"]
expect:
  exit: 0
  stdout: |
    hello
  stderr: ""

测试用例还可以设置 env、files(在全新的临时目录中创建)和 timeout_ms。 使用 behave add behave-cut --stdin 'a,b' -- -d, -f2 添加自己的测试用例。

如何确保结果具有确定性

  • 每个测试用例都会在新的临时目录中运行,并使用固定环境 (LC_ALL=C.UTF-8、TZ=UTC、NO_COLOR=1、HOME=临时目录)
  • 输入文件的修改时间固定;读取当前目录的工具(ls、du、rg;帮助文本中提到“当前目录”或递归操作的工具)会获得一份小型示例 目录树(--sample-files auto|on|off),其中文件名、大小和扩展名的排序方式各不相同, 因此 ls --sort=size、ls -t、du --time 和 du -S 会生成值得比较的输出
  • 每个测试用例都会记录 3 次;运行结果有任何变化都会标记为 flaky 并跳过 (例如 sort --random-sort)
  • 比较前,规范化器会移除噪声:ansi、workdir、cmd(jq: 与 gojq:)、timestamp、hexaddr、duration、pid,以及你在 behave.yaml 中定义的正则规则
  • 超时会终止整个进程组

命令

命令功能
behave probe <cmd>发现标志、生成并记录用例(--arg、--inputs text|json|both、--max、--skip-flag、--sample-files、--dry-run)
behave record <spec>根据原始程序重新记录预期结果
behave add <spec> -- ARGS添加一个手动编写的用例
behave run <spec>对照原始程序重放
behave diff <spec> --impl <bin>对照另一个实现重放(--ignore-stderr、--ignore-exit、--tag、--skip-tag、--json、--junit file、-v)
behave coverage <spec>查看用例覆盖了哪些有文档说明的标志(来自 --help/man)(--min PCT、--all、--json)
behave normalizers列出内置规范化器

如果有任何用例失败,run 和 diff 会以 1 退出,因此可直接用于 CI。传入 --junit report.xml 可生成 JUnit XML 报告,供 CI 控制面板使用(GitHub Actions、Jenkins 等)。

coverage 会告诉你某个 spec 尚未测试哪些内容。以手动挑选的 cut 示例为例:

$ behave coverage examples/cut
cut: 27 cases exercise 7 of 12 documented flags (58%)
not exercised (5): -n --zero-terminated --help --version -M
used but not in help: --no-such-flag

它读取标志的方式与 probe 相同,能够识别 --long=value、无歧义的长标志前缀和组合短标志(-sf1);当覆盖率低于 80% 时,传入 --min 80 会使其以 1 退出。

仓库提供了一个多阶段 Dockerfile,用于构建二进制文件,并通过标准输入输出启动 behave mcp(适用于 Glama 和其他从 Dockerfile 构建的 MCP 注册表)。

规划

  • 提交更多示例 spec(head、tail、wc,以及与 ripgrep 对比的 grep 子集)
  • Homebrew tap

安全

behave 只会在临时目录中运行你指定的二进制文件。不要在未使用 --skip-flag 和沙盒的情况下,对会更改工作目录之外内容的工具(包管理器、rm -rf 类工具)进行探测。

链接

  • MCP Registry 名称:io.github.emirmrkaljevic/behave

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。