minikube 测试指南:单元测试、集成测试与 Kubernetes 一致性测试实战
【免费下载链接】minikubeRun Kubernetes locally项目地址: https://gitcode.com/gh_mirrors/mi/minikube
导读
本文围绕 minikube 项目的测试体系展开,系统讲解从本地开发环境的单元测试(make test),到面向真实集群行为的集成测试(make integration),再到对任意集群运行 Kubernetes 官方一致性套件(sonobuoy)的完整流程。读完本文,你将掌握 minikube 各类测试的触发方式、常用参数(如TEST_ARGS、-minikube-start-args、-test.run、-test.parallel)、快速迭代单个测试的技巧,以及项目团队沉淀的测试编写哲学,并可从 test/integration/main_test.go 与 Makefile 的源码层面理解每条命令背后的真实行为。
前置条件
在运行 minikube 的任何测试之前,需要准备以下环境:
- Go 发行版:具体版本取决于当前 minikube 版本的依赖声明。以当前仓库为例,go.mod 顶部声明
go 1.26.0,而 Makefile 中的GO_VERSION ?= 1.26.5是官方构建使用的工具链版本(可通过make update-golang-version更新)。建议先阅读 go.mod 确认与仓库匹配的 Go 版本。 - Linux 上的 libvirt 开发库:单元测试需要 kvm2 驱动,因此 Linux 用户必须安装对应发行版的 libvirt 开发包:
# Debian 系 sudo apt-get install libvirt-dev # CentOS yum install libvirt-devel # Fedora dnf install libvirt-devel单元测试(Unit Tests)
minikube 的单元测试在代码合并前由 CI 强制运行。作为日常开发循环的一部分,只需在仓库根目录执行:
make test从源码看,Makefile 中test目标实际调用的是仓库根目录下的 test.sh 脚本:
test: ## Trigger minikube test MINIKUBE_LDFLAGS="${MINIKUBE_LDFLAGS}" ./test.shtest.sh 是一个多阶段检查脚本,支持通过TESTSUITE环境变量选择执行范围:
TESTSUITE=all(默认):依次执行make lint-ci、go mod download、go mod tidy(CI 模式下还会校验go.mod/go.sum是否有未提交的差异,并运行make generate-docs校验文档是否过期)、boilerplate 版权头检查(hack/boilerplate)、deploy/minikube/schema_check.go 的 schema 校验,以及核心的go test。TESTSUITE=lint:仅执行 lint 与依赖检查。TESTSUITE=unittest:仅执行 schema 校验与单元测试。TESTSUITE=lintall:lint 加 boilerplate 检查。
核心单元测试命令会对./cmd/... ./pkg/...两个包集合执行go test,并启用构建标签container_image_ostree_stub containers_image_openpgp、开启覆盖率统计(结果汇总到out/coverage.txt):
pkgs=$(go list -f '{{ if .TestGoFiles }}{{.ImportPath}}{{end}}' ./cmd/... ./pkg/... | xargs) go test -ldflags="$MINIKUBE_LDFLAGS" \ -tags "container_image_ostree_stub containers_image_openpgp" \ -covermode=count -coverprofile="${cov_tmp}" ${pkgs}如果想跳过 lint 等附加检查、直接只跑 Go 单元测试,也可以使用 Makefile 中的轻量目标make gotest(见 Makefile),它等价于对MINIKUBE_TEST_FILES := ./cmd/... ./pkg/...直接执行go test。此外 Makefile 还提供了out/unittest.json、out/unittest.html、out/coverage.html等目标,用于生成 JSON 格式的测试报告与 HTML 覆盖率报告,方便在 CI 中归档与查看。
集成测试(Integration Tests)
集成测试会真实拉起 minikube 集群并验证端到端行为,是验证驱动、网络、存储、插件等组件协同工作的关键手段。
基本用法
在 minikube 根目录先构建二进制,再运行测试:
make integration从 Makefile 可以看到该目标的全貌:
integration: out/minikube$(IS_EXE) ## Trigger minikube integration test, logs to ./out/testout_COMMIT.txt go test -ldflags="${MINIKUBE_LDFLAGS}" -v -test.timeout=90m \ $(INTEGRATION_TESTS_TO_RUN) --tags="$(MINIKUBE_INTEGRATION_BUILD_TAGS)" \ $(TEST_ARGS) 2>&1 | tee "./out/testout_$(COMMIT_SHORT).txt"几个关键点值得注意:
- 目标依赖
out/minikube,即会先构建二进制再跑测试; - 测试包为
INTEGRATION_TESTS_TO_RUN := ./test/integration,并携带构建标签integration; - 全局超时 90 分钟(
-test.timeout=90m),日志实时写入out/testout_<commit短哈希>.txt; - 所有自定义参数都通过
TEST_ARGS透传给go test。
因此,当你想针对非默认驱动运行某个特定测试时,可以这样做:
make integration TEST_ARGS="-minikube-start-args='--driver=vfkit --network=vmnet-shared' -test.run TestStartStop"-minikube-start-args的值会原样拼接到minikube start命令后面。需要注意两点(原文档强调的IMPORTANT事项,在 main_test.go 与 StartArgs 的实现中也能得到印证——参数值最终是按空格strings.Split(*startArgs, " ")拆分的):
- 向
-minikube-start-args传递多个 flag 时,必须对整个值加引号包裹; - flag 的值本身不能包含空格,因为该字符串后续会按空格切分。
在活跃集群上快速迭代单个测试
日常开发中,你往往只想反复验证某一个用例,而不是每次都重建集群。此时可以利用--cleanup=false让集群在测试结束后保留下来:
make integration TEST_ARGS="-test.run TestFunctional/parallel/MountCmd --profile=minikube --cleanup=false"上述命令的执行流程可以拆解为:
-test.run TestFunctional/parallel/MountCmd:利用 Go 测试框架的子测试选择语法,只运行TestFunctional下parallel组中的MountCmd用例。在 test/integration/functional_test.go 中可以看到,parallel组包含 ConfigCmd、DashboardCmd、MountCmd、ServiceCmd、AddonsCmd、PersistentVolumeClaim、TunnelCmd、SSHCmd、CpCmd、DockerEnv、PodmanEnv、ImageCommands 等二十余个用例;--profile=minikube:强制测试使用名为minikube的 profile(对应 main_test.go 中的forceProfileflag),而不是每次创建随机命名的临时 profile;--cleanup=false:测试结束后不删除集群,便于下次直接复用(对应 main_test.go 中的cleanupflag,默认值为true;CanCleanup 也以它为准)。
WARNING:--cleanup=false能反复执行的前提是——被测测试自身必须做好清理工作(如删除自己创建的资源、卸载镜像等),否则残留状态会污染下一次运行。这也是 functional_test.go 中cleanupUnwantedImages、Cleanup等机制存在的原因:正常情况下测试结束会主动清理镜像与集群资源。
关于集成测试可用的全部命令行 flag,可查阅 test/integration/main_test.go,除上文提到的外还包括:
| flag | 默认值 | 说明 |
|---|---|---|
-minikube-start-args | 空 | 追加到minikube start的参数 |
-profile | 空 | 强制使用指定 profile 运行测试 |
-cleanup | true | 失败/结束后是否清理集群 |
-gvisor | false | 是否运行 gvisor 集成测试(较慢) |
-postmortem-logs | true | 失败后是否展示日志 |
-timeout-multiplier | 1 | 测试超时的倍率系数 |
-binary | ../../out/minikube | minikube 二进制路径 |
-testdata-dir | testdata | 测试数据目录(相对test/integration) |
另外,TestMain 中还有一处值得了解的实现细节:setMaxParallelism()会根据机器核数自动调整并行度。因为每个minikube start最多会消耗 2 个核,默认并行上限被计算为floor(GOMAXPROCS / 1.75),Windows 上还会再减半,以避免并行度太高导致测试超时(见 setMaxParallelism)。
禁用并行
默认情况下集成测试会并行执行多个用例(充分利用多核),如果集群资源有限或某个用例存在干扰,可以强制串行:
make integration TEST_ARGS="-test.parallel=1"其他常用的集成测试目标
在 Makefile 中还有几个与集成测试相关的变体目标,按需选用:
make integration-versioned(Makefile):额外携带versioned构建标签,运行版本相关用例;make integration-functional-only/make functional(Makefile):只运行TestFunctional,超时缩短为 20 分钟;make integration-none-driver(Makefile):以--driver=none方式运行,适用于 Linux 本机直跑场景;make html_report(Makefile):基于上次运行的out/testout_<commit>.txt,通过test2json+ gopogh 生成 HTML 格式的测试报告并在浏览器打开,适合 CI 结束后的可视化分析。
测试哲学
原文档明确了 minikube 团队对测试代码的编写要求,这是集成测试(乃至整个仓库测试)的指导原则:
- 测试应该简单到仅凭检查就能确定正确("so simple as to be correct by inspection")——不要引入复杂的抽象或间接层;
- 读者只需要读测试主体就能理解测试——所有关键逻辑都应内联在测试函数中,无需跳转查询辅助代码;
- 自上而下的可读性比代码去重更重要——为了可读性可以接受少量重复,不必强行抽取公共函数。
之所以如此强调可读性,是因为测试通常带着怀疑的目光被阅读——它们往往只在出问题时才被打开。因此测试代码的首要目标是让排查者一眼看懂"这个用例在验证什么、怎么做、预期什么"。这一哲学在 test/integration/functional_test.go 中体现得淋漓尽致:TestFunctional的主体就是一张"测试名 + 校验函数"的清单(见 functional_test.go 的 serial 组与 L149-L191 的 parallel 组),自上而下逐条阅读即可掌握整组用例的意图。
一致性测试(Conformance Tests)
一致性测试(Kubernetes Conformance Tests)是 Kubernetes 官方针对任意集群运行的、覆盖大量 Kubernetes 特性的测试套件,用于验证集群实现是否符合 Kubernetes 规范。minikube 通过 hack/conformance_tests.sh 脚本,借助 sonobuoy 在 minikube 集群上执行官方一致性套件。
准备环境
- 安装 docker(这里使用 docker 驱动运行集群与 sonobuoy);
- 安装 kubectl;
- 克隆 minikube 仓库(
git clone https://gitcode.com/gh_mirrors/mi/minikube或从官方源克隆)。
编译最新 minikube 二进制
% cd <minikube dir> % makemake会在out/目录下生成当前源码对应的 minikube 可执行文件,供后续一致性测试使用。
触发测试并获取结果
% cd <minikube dir> ./hack/conformance_tests.sh out/minikube --driver=docker --container-runtime=docker --kubernetes-version=stable该脚本会使用指定的参数,在一个双节点的 minikube 集群上运行最新版本的 sonobuoy。结合 conformance_tests.sh 源码,其内部流程大致如下:
- 使用固定 profile
k8sconformance清理可能存在的旧集群; - 以
--wait=all --nodes=2启动双节点集群,并确认kubectl get pods --all-namespaces与minikube status正常; - 通过 GitHub API 拉取 sonobuoy 最新 release 的 Linux amd64 二进制并解压;
- 以官方认证模式运行一致性套件:
./sonobuoy run --plugin-env=e2e.E2E_EXTRA_ARGS="--ginkgo.v" --mode=certified-conformance --wait --alsologtostderr; - 用
sonobuoy retrieve取回结果 tar 包并解压到临时目录; - 读取
minikube version中的版本号,生成符合 CNCF 一致性认证格式的PRODUCT.yaml(声明 vendor、版本、仓库地址、联系方式等信息)与可复现说明README.md,连同 e2e 结果一并拷贝到当前目录下minikube-<version>文件夹中。
因此,跑完脚本后你会在仓库根目录得到类似minikube-v1.39.0的目录,其中包含一致性测试的原始结果与完整的复现说明,可用于向 CNCF 提交一致性认证或自行归档比对。
小结
- 日常快速验证:
make test(单元测试 + lint + 依赖与文档一致性检查),或make gotest只跑 Go 单元测试; - 端到端验证:
make integration,配合TEST_ARGS="-minikube-start-args=... -test.run ... --cleanup=false"精准定位与反复迭代单个用例; - 规范符合性验证:
./hack/conformance_tests.sh out/minikube --driver=docker ...在双节点集群上跑官方一致性套件。
测试相关代码均位于 test/integration(集成测试主体)、test.sh(单元测试入口)、hack/conformance_tests.sh(一致性测试脚本)与 Makefile(测试目标定义)中,遇到任何参数或行为疑问,都可直接回到源码核对。
【免费下载链接】minikubeRun Kubernetes locally项目地址: https://gitcode.com/gh_mirrors/mi/minikube
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考