2.3 单元与集成测试门禁


2.3 单元与集成测试门禁

本节摘要:单元测试验证最小代码单元;集成测试验证模块间交互。本节配置 pytest 覆盖率门禁、JUnit 报告、Testcontainers 集成测试,并将 SonarQube quality gate 接入 PR 流水线——测试是 CI 的核心「门」。

本节地图

阅读完本节,你应当能够:

  1. 解释测试金字塔在 CI 中的分层执行顺序
  2. 配置 pytest --cov-fail-under 覆盖率阈值
  3. 使用 Testcontainers 跑真实数据库集成测试
  4. 集成 SonarQube 阻断低质量 merge

一、测试金字塔在 CI 里的顺序

/ E2E \ ← CD 阶段,慢 / API \ / 集成测试 \ / 单元测试 \ ← CI 阶段,快 ───────────────

CI 阶段跑单元+部分集成;E2E 留给第3章 CD 预发环境。顺序不可颠倒——先 pytest 再 Selenium。

二、pytest 单元测试门禁

# tests/test_auth.py def test_login_returns_token(client): resp = client.post("/login", json={"user": "a", "pass": "b"}) assert resp.status_code == 200 assert "token" in resp.json()

CI 命令:

pytest --cov=app --cov-report=xml --cov-fail-under=80 -q
参数 作用
--cov-fail-under=80 低于 80% 覆盖率 exit 1
--cov-report=xml 供 SonarQube 消费
-q 减少日志体积

GitHub Actions:

- run: pip install pytest pytest-cov - run: pytest --cov=app --cov-fail-under=80

JUnit 报告(Java)

<!-- pom.xml surefire --> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine>@{argLine} -Xmx1024m</argLine> </configuration> </plugin>

Jenkins JUnit 插件解析 target/surefire-reports/*.xml,PR 上显示「Tests: 847, Failures: 0」。

三、集成测试与 Testcontainers

import pytest from testcontainers.postgres import PostgresContainer @pytest.fixture(scope="module") def db(): with PostgresContainer("postgres:15") as pg: yield pg.get_connection_url() def test_user_crud(db): # 真实 PostgreSQL,非 mock ...

CI 需 Docker-in-Docker 或 sibling docker socket。GitLab CI:

integration-test: services: [docker:dind] script: [pytest tests/integration -m "not slow"]

静态分析与 SonarQube

- run: mvn sonar:sonar -Dsonar.qualitygate.wait=true
Sonar 指标 典型阈值
Coverage ≥ 80% on new code
Duplicated Lines < 3%
Blocker Issues 0
Security Hotspots reviewed

⚠️ 常见坑:Flaky test——偶发失败让团队习惯「重跑就好」,quality gate 形同虚设。 flaky 测试要么修要么 quarantine,不能 ignore。

💡 关键直觉:Google 测试博客强调:不可靠的测试比没有测试更坏——它训练团队忽略红灯。

集成测试 vs 单元测试

类型 速度 隔离 CI 阶段
单元 毫秒 mock 外部 必跑
集成 秒~分 真实 DB/消息队列 必跑
E2E 分钟~十分 全链路 CD 预发

Jenkins 并行测试 stage

stage('Test') { parallel { stage('Unit') { steps { sh 'pytest tests/unit' } } stage('Integration') { steps { sh 'pytest tests/integration' } } } }

并行缩短 wall time,但共享 runner 资源——CPU 核数不足时反而更慢。

Newman API 测试(Postman)

newman run collection.json -e staging.postman_environment.json \ --bail --reporters cli,junit

接口测试比 E2E 快,适合 CI 后期或 CD staging gate。

四、测试策略与 CI 工具链(SOURCE 2.4–2.6 合并)

静态分析与代码质量

SonarQube 在 CI 跑 mvn sonar:sonar,检查 bug、vulnerability、code smell、duplication。Quality Gate 示例:新代码 coverage ≥ 80%、0 Blocker。ESLint/Prettier 在前端 PR 强制格式化——npm run lint 失败即不可 merge。

Checkstyle、SpotBugs 是 Java 静态分析补充;golangci-lint 聚合 Go 多种 linter。原则:能静态发现的不要留到运行时

构件管理 Nexus/Artifactory

仓库 内容 CI 动作
maven-snapshots 开发分支 SNAPSHOT deploy on main
maven-releases tag 版本 deploy on tag v*
docker-hosted 镜像 push after build
pypi-hosted Python wheel twine upload

制品保留策略:snapshot 30 天自动清理,release 永久——磁盘与合规的平衡。

CI 工具链工作流(SOURCE 2.6.4)

开发者提交 → SCM Webhook → CI 拉代码 → 构建工具编译 → 测试框架执行 → 收集报告 → 成功则发布制品 → Slack/邮件通知 → 开发者修复或继续——九步闭环。任何一步失败,后续不执行(fail fast)。

Flaky test 治理流程

  1. 检测:同一 test 7 天内 fail > 2 次且 pass > 5 次
  2. 隔离:移入 quarantine job,不阻断 merge
  3. 修复:owner 7 天内 root cause
  4. 回归:修好后移回主 job

没有治理流程的团队,最终会养成「重跑直到绿」的文化——quality gate 失效。

契约测试(Pact)

微服务间 API 契约由 consumer 定义、provider 验证——CI 阶段拦截 breaking change:

pact-broker can-i-deploy --pacticipant payment --version $GIT_SHA --to staging

比全链路 E2E 快一个数量级,适合 service mesh 架构。

要点串联

  • 测试金字塔 决定 CI stage 顺序:快测在前
  • pytest --cov-fail-under 量化门禁
  • Testcontainers 集成测试用真依赖
  • SonarQube quality gate 阻断低质量代码
  • Flaky test 必须修或隔离,不能习惯性重跑
  • 并行 stage 换 wall time,注意资源
  • Newman 适合 API 层 CD 前验证

第3章进入持续交付:制品如何在多环境管道中晋级。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U