首页
/ 如何在不安装 Node.js 的主机上用 Docker 官方镜像运行 Bruno CLI 集合并产出 JUnit 报告

如何在不安装 Node.js 的主机上用 Docker 官方镜像运行 Bruno CLI 集合并产出 JUnit 报告

2026-09-08 19:39:40作者:伍霜盼Ellen

如果你的 CI 构建机、临时测试机或受限环境里只有 Docker 而没有 Node.js / npm,又需要在机器上执行 Bruno API 测试集合并拿到 JUnit XML 报告,可以不用安装 Bruno CLI:Bruno 官方提供了 usebruno/cli Docker 镜像(Docker Hub 与 GHCR 两个 registry),把 Node.js 环境、bru 命令和整个运行时都装在了容器里。主机上只需要做两件事:把 Bruno 集合目录绑定挂载进容器,然后在镜像上执行 run 命令并指定 JUnit 报告输出路径。

前提条件(文档明确给出的部分):

  • 主机已安装 Docker(镜像入口、用户和工作目录由官方镜像提供,不需要任何主机侧 Node.js);
  • 一个 Bruno 集合目录(包含 .bru 请求文件的目录)已保存在主机磁盘上;
  • 架构为 linux/amd64linux/arm64,这是官方镜像发布的两种架构。

选择并拉取镜像

官方镜像同时发布到两个 registry,拉取命令等价:

docker pull usebruno/cli:latest        # Docker Hub
docker pull ghcr.io/usebruno/cli:latest  # GHCR

镜像有两个变体,按 Docker 镜像说明 的建议选择:

变体 基础镜像 选择依据
Alpine(默认) node:22-alpine 默认选择,文档建议 90% 的用户用它
Debian node:22-slim 只在遇到 SSL/glibc 兼容性问题时使用

tag 决定镜像版本,常见 pattern 有:

Tag 含义
latest / latest-alpine / alpine 最新 alpine 发布
debian / latest-debian / <version>-debian debian 变体
3.3.0(即 <version> 精确版本,不可变
3.3<major.minor> 跟随该小版本的补丁更新
3<major> 跟随任意 3.x.x 发布

不带后缀的 tag(:latest:3.3.0:3 等)按约定始终解析为 alpine 变体。文档建议在 CI 生产环境固定精确版本,例如:

docker pull usebruno/cli:3.3.0

验证镜像可用

拉取后先跑一个最小命令确认 bru 能执行:

docker run --rm usebruno/cli --version

只要输出版本号即说明镜像工作正常。镜像的关键运行时属性(来自 镜像说明):入口命令是 bru,工作目录是 /bruno,以非 root 用户 node(UID 1000)运行。后面的命令都是利用这两点工作的。

运行集合并产出 JUnit 报告

以下命令假设你在集合目录下执行 docker,把当前目录挂载到容器内的 /brunobru 的参数直接跟在镜像名后面。

完整集合:

docker run -v $(pwd):/bruno usebruno/cli run

只跑集合内的某个子文件夹或单个请求文件:

docker run -v $(pwd):/bruno usebruno/cli run ./api-tests
docker run -v $(pwd):/bruno usebruno/cli run ./api-tests/login.bru

主路径——产出 JUnit XML 报告:

docker run -v $(pwd):/bruno usebruno/cli run --reporter-junit results.xml

--reporter-junit 后跟报告文件路径,这是 Bruno CLI 的命令行参数(见 Bruno CLI 选项表)。由于集合目录被绑定挂载到当前目录,生成的 results.xml 会直接落在你执行 docker 命令的那个主机目录里,无需额外拷贝。

几个使用细节:

  • $(pwd) 适用于 Bash / Zsh / Git Bash / WSL;Windows 原生 PowerShell 换成 ${PWD},CMD 换成 %cd%,例如 docker run -v %cd%:/bruno usebruno/cli run
  • 集合不在当前目录时,把挂载源换成集合的相对或绝对路径即可:docker run -v /path/to/your/collection:/bruno usebruno/cli run,其中 /path/to/your/collection 需替换为你主机上集合目录的真实路径;
  • 文档中的示例未加 --rm,这样容器退出后仍可用 docker logs / docker inspect 排查;CI 里想避免堆积停止的容器时,给 docker run 追加 --rm,它只影响容器清理,不影响挂载、输出和退出码;
  • bru run 的其余选项(-r 递归、--env 环境、--bail 失败即停等)与本地 CLI 一致,可以按需在镜像名后继续追加。

可选分支:用 Docker Compose 同时产出多种报告

如果还要同时出 JSON、JUnit、HTML 三种报告,仓库里提供了一个现成的 compose 示例(packages/bruno-tests/docker-compose.yml,其中挂载了示例集合 collection/ 并跑 echo 子集):

services:
  bruno-cli:
    image: usebruno/cli:latest
    container_name: bruno-cli-runner
    volumes:
      - ./collection:/bruno
      - ./reports:/reports
    command:
      run echo
      -r
      --env Prod
      --reporter-json /reports/results.json
      --reporter-junit /reports/results.xml
      --reporter-html /reports/results.html

执行 docker compose run bruno-cli。这里的关键是第二个挂载 ./reports:/reports:报告写到容器内 /reports 路径,通过该挂载落回主机 ./reports/ 目录。把 ./collection./reports 换成你自己的集合目录与报告目录(--env Prod 也要换成集合 environments 中真实存在的环境名),不需要某类报告时删掉对应的 --reporter-* 行即可。

可选分支:接入 CI 流水线

文档给出了两条 CI 路径,按需取用:

GitLab CI——直接用官方镜像作为作业镜像,此时在作业 shell 里直接执行 bru(入口就是它),并声明 JUnit 产物:

api-tests:
  image: usebruno/cli:latest
  script:
    - bru run --output results.xml --format junit
  artifacts:
    reports:
      junit: results.xml

GitHub Actions——runner 里已有 Docker,用 docker run 挂载 checkout 出来的仓库目录:

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Bruno collection
        run: |
          docker run --rm \
            -v ${{ github.workspace }}:/bruno \
            usebruno/cli:latest run --output results.xml --format junit

      - name: Publish Test Report
        uses: dorny/test-reporter@v3
        if: success() || failure()
        with:
          name: Bruno Test Results
          path: ${{github.workspace}}/results.xml
          reporter: java-junit

${{ github.workspace }} 是 GitHub Actions 内置变量,指 checkout 的仓库根目录,原样保留即可(要求集合就放在仓库根目录;否则把挂载源换成集合所在子目录)。注意这里用的是 --output results.xml --format junit 的写法——-f/--format 可选 json(默认)或 junit,与 --reporter-junit 是产出 JUnit 报告的两种等价参数形式。

结果验证与失败定位

一次运行可以从三个层面验证:

  1. 容器内终端输出bru run 结束时打印运行汇总(请求数、通过/失败数)。smoke-test.sh 用它做过镜像级验证,其判定逻辑是:能输出汇总且至少 1 个请求通过才算镜像可用;汇总行形如 Requests | 14 (12 Passed, 2 Failed)(新表格格式)或 Requests: 14, Passed: 12, Failed: 2(旧行格式)。个别请求断言失败属于集合本身的结果,不代表镜像坏了。
  2. 主机上的报告文件:运行结束后检查 results.xml 是否出现在你挂载的目录(或 compose 里的 ./reports/)中;接入 CI 后则由 runner 上传。
  3. 退出码:Bruno CLI 的退出状态码是文档定义的(见 Bruno CLI readme),容器退出码会原样透传,可用它区分“测试失败”和“跑不起来”:
退出码 含义
0 执行成功
1 集合中的请求、测试或断言失败
2 指定的输出目录不存在
3 请求链疑似无限循环
4 在集合根目录之外调用了 bru
5 指定的输入文件不存在
6 指定的环境不存在
7 / 8 环境覆盖不是字符串/对象,或格式错误
9 请求了无效的输出格式
255 其他错误

对照退出码可以快速定位问题:报 4 说明挂载点不对(容器工作目录是 /bruno,集合必须映射到该目录);报 6 说明 --env 指定的环境名与集合中环境不匹配;报 9 说明 --format 传了 json/junit 以外的值。

限制与边界

  • 镜像入口固定为 bru,无法通过该镜像执行 bru 以外的命令;需要容器内其他操作时要另行处理。
  • 镜像以非 root 用户 node 运行,挂载的集合目录需对该用户可读(写入报告同样要求挂载目录可写)。
  • Alpine 与 Debian 变体内容一致,仅在基础镜像上有差异;SSL/glibc 问题切 Debian 变体时,记得 tag 也要换成 -debian 后缀形式。
  • 文档中所有示例都基于 Linux/macOS 风格的挂载语法;Windows CMD 需用 %cd% 写法。

进一步的 CLI 参数细节(递归、环境、变量覆盖、报告头跳过等)可参考 Bruno CLI readme 的选项表,镜像构建(自行 docker build 指定 BRUNO_VERSION)可分别参考 AlpineDebian 两个变体说明。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391