You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bazel与Docker Compose运行客户端SDK集成测试?

Bazel下SDK集成测试的Docker方案选型与实践

一、sh_test + docker-compose 完全可行

用sh_test触发docker-compose拉起服务端和测试容器的方案完全能跑通,核心逻辑很直接:

  • 写个shell脚本,搞定镜像拉取/构建、启动容器栈、等服务就绪、跑测试、最后清资源这一套流程
  • 把脚本挂到Bazel的sh_test规则里,同时把SDK测试二进制、docker-compose.yml设为依赖,确保Bazel能把这些文件丢到测试沙箱里

但要注意几个关键细节:

  • 强制清资源:不管测试过没过,都要执行docker-compose down -v --remove-orphans,不然残留的容器会搞砸下一次测试
  • 服务就绪检查:别上来就跑测试,用curl或nc轮询服务端的健康检查接口,确认服务起来了再执行测试
  • 依赖路径:Bazel的测试沙箱路径是临时的,脚本里要注意用相对路径或者$TEST_SRCDIR环境变量找依赖文件

示例sh_test规则:

sh_test(
    name = "sdk_integration_test",
    srcs = ["run_integration_test.sh"],
    data = [
        ":gtest_binary",
        "docker-compose.yml",
    ],
    tags = ["docker"], # 标记需要Docker环境,方便CI过滤
)

示例脚本片段(run_integration_test.sh):

#!/bin/bash
set -euo pipefail

# 切换到测试沙箱的工作目录
cd "$TEST_SRCDIR/your_workspace_name/sdk"

# 启动容器栈
docker-compose up -d

# 等待服务端就绪,最多等30秒
count=0
until curl -s http://localhost:8080/health; do
    sleep 1
    count=$((count+1))
    if [ $count -gt 30 ]; then
        echo "服务端启动超时"
        exit 1
    fi
done

# 执行测试(如果测试二进制在容器里,就用docker exec;如果在宿主机,直接跑)
docker exec sdk-test-container ./gtest_binary

# 不管成功失败,退出前清资源
trap "docker-compose down -v --remove-orphans" EXIT INT TERM

二、更优方案:用Bazel官方的rules_docker

比起sh_test + docker-compose,官方的rules_docker和Bazel的构建体系深度集成,适合长期维护的项目,优势很明显:

  • 一站式构建测试:不需要额外写Dockerfile和docker-compose.yml,所有镜像定义、测试逻辑都在Starlark里统一管理
  • 自动依赖同步:只要SDK或服务端代码变了,Bazel会自动重新构建镜像,不用手动同步版本
  • 隔离性更好:用container_test规则跑测试,容器之间的网络是隔离的,不会干扰宿主机或其他测试
  • 缓存省时间:Bazel的增量构建会缓存镜像层,重复构建快很多

示例配置思路:

  1. 构建服务端镜像:
load("@io_bazel_rules_docker//container:container.bzl", "container_image")

container_image(
    name = "server_image",
    base = "@ubuntu_latest//image", # 提前用docker_pull拉取基础镜像
    cmd = ["/usr/bin/server"],
    files = [":server_binary"], # 依赖服务端二进制
)
  1. 构建测试镜像(包含SDK的gtest二进制):
container_image(
    name = "test_image",
    base = "@ubuntu_latest//image",
    cmd = ["./gtest_binary"],
    files = [":gtest_binary"], # 依赖SDK测试二进制
    env = {"SERVER_ADDR": "server:8080"}, # 直接通过环境变量指定服务端地址,不用硬编码
)
  1. 用container_test启动两个容器并跑测试:
load("@io_bazel_rules_docker//container:container.bzl", "container_test")

container_test(
    name = "sdk_integration_test",
    images = {
        "server:latest": ":server_image",
        "test:latest": ":test_image",
    },
    network = "bridge", # 让两个容器在同一网络里通信
    test_image = "test:latest", # 指定跑测试的容器
    timeout = "300s",
)

三、选型建议

  • 临时测试、小型项目:直接上sh_test + docker-compose,不用学新规则,快得很
  • 长期维护的大型项目:优先用rules_docker,减少维护成本,测试更可靠,构建也更快

内容的提问来源于stack exchange,提问作者Howard Yu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:05:46