测试工程与 DevOps / SRE 的边界:三方协作的真实工作流

系列专栏:测试工程师每日一博 · Day 19

上一篇:Day 18 · 测试工程师的成长地图:从初级到资深,这五年学什么

这是系列第二次跳脱"测试自己",回答"测试跟邻居职能怎么分地盘"。Day 18 谈"向上成长",Day 19 谈"向左右协作"。

目标:不画独占地盘,只把交叉地带的协作工程化------让三方协作靠 YAML / 接口 / playbook,而不是人情。

一、为什么必须有这一篇

工业里一个反复出现的撕裂:"这个监控告警是谁的活?"

  • 测试说:"我已经把 CI 红线拉好了,告警是 SRE 的";
  • SRE 说:"告警来了只是数据,测试才知道哪些是真事故";
  • DevOps 说:"我搭了告警管道,具体怎么用是你们俩的事"。

三个职能互相推活,质量漏洞就出现在缝隙里。这一篇来把这些缝隙填上。

1.1 三职能的定位差异

先给三个职能一张定位卡,所有人必须读到一致:

职能 核心使命 时间维度 成功的标志
测试工程 把质量风险量化为业务决策 编码前到上线前 "应该发现但没发现的缺陷"= 0
DevOps 让代码从开发到上线跑得快且稳 提交到部署 部署频率↑、变更失败率↓、恢复时间↓(DORA)
SRE 让系统在生产里可靠 上线后持续 SLO 达成率↑、错误预算未耗尽

注意"时间维度"那一列------三职能的核心战场时间轴互不重叠,但有交叉地带。Day 19 主要解决"交叉地带怎么分"。

1.2 工业里三个常见误解

讲清三职能定位之前,先撕掉三个反复出现的误解:

  1. "DevOps 就是写 CI / CD 脚本的" ------ 错。DevOps 的本质是「让交付管道短而稳」,脚本只是表面动作。资深 DevOps 工程师花更多时间在 DORA 指标的优化(部署频率、变更失败率、平均恢复时间)上,而不是写 YAML;
  2. "SRE 就是运维的升级版" ------ 错。SRE 的核心是「用工程方式解决运维问题」,从告警规则、SLO 设计到混沌实验都是工程行为。把它当"高级运维"等于浪费 SRE 一半的能力;
  3. "测试 = QA = 手工验收员" ------ 错。这一份误解最毒。测试工程的核心是把「质量」量化、可决策(回扣 Day 18 §6.2.1 质量策略)。把它压成"点鼠标的人",你只用了测试工程师 5% 的能力。

撕掉这三个误解,后面的协作才能聊------不能把"邻居"看扁了再谈协作,那是单边独白

二、地盘分割矩阵

把工业里常见的 12 项关键工程动作,按"谁主谁辅谁不参与"分割:

工程动作 测试 DevOps SRE
单元测试 --- ---
集成 / 契约测试 --- ---
E2E 测试 辅(提供 flaky 隔离环境) 辅(给线上数据样本)
CI 流水线 辅(测试 stage) 辅(给预生产 SLO 卡)
CD 流水线 辅(灰度门控) 辅(灰度观察 SLO)
性能压测 辅(跑脚本) 辅(给生产分布数据)
监控告警规则 辅(写"测试红灯"规则) 辅(管道维护)
SLO / SLI 定义 辅(给"测试覆盖转 SLI"映射) ---
上线发布按钮 辅(给"测试绿灯") 辅(给"SLO 绿灯")
回滚 辅(给"应回滚信号") 辅(执行机制) (决定回)
故障复盘 辅(写红灯 case + 系统漏洞) 辅(postmortem 平台) (主持)
容灾 / 混沌实验 辅(设计用例) 辅(基础设施)

读法:粗体是该动作的主责人,辅是该动作的协作角色,空是不参与

可以一眼看出:没有任何一行只有一个职能单独干 。所有 12 项都至少两个职能协作。这就是为什么"地盘大战"无解 ------ 地盘本来就不是独占的,是分工的

三、CI / CD 里的协作:测试 vs DevOps

最常见的协作场景。DevOps 主战场,测试是强势协作者。

3.1 阶段划分

text 复制代码
开发者 push PR
    │
    ↓
[Step 1] Pre-commit hook(lint / type check / format)
    │                DevOps 主 / 测试不参与
    ↓
[Step 2] PR check(单测 + 覆盖率 + Pact verify)
    │                测试 主 / DevOps 提供运行环境
    ↓
[Step 3] Merge to main → 集成测试 + 安全扫描 + 镜像构建
    │                DevOps 主 / 测试辅(集成测试)
    ↓
[Step 4] Deploy to staging
    │                DevOps 主 / 测试不参与
    ↓
[Step 5] E2E 回归 + 性能基线
    │                测试 主 / DevOps 提供 flaky 隔离 runner
    ↓
[Step 6] 部署生产(灰度 5% → 25% → 50% → 100%)
    │                DevOps 主 / 测试 + SRE 给绿灯
    ↓
[Step 7] 发布后观察窗(1h,看 SLO)
                     SRE 主 / 测试不参与

每一步都有清晰的 "主 / 辅" 标签。没标签的步骤,就是漏点------比如 Step 6 灰度阶段,如果测试没给"基于回归的绿灯标准",DevOps 会把"测试通过"理解为"自动化全绿",但实际可能是"自动化 200 个用例都没跑这个 canary 流量"。

3.2 一个常见冲突的解法

冲突:DevOps 想把 PR check 时间压到 5 分钟内,测试想跑全覆盖

错误解法:互相吵架(DevOps 说"测试太慢",测试说"质量不能让步")。

正确解法:用 Day 7 的时间门控分层------

  • PR check 只跑 ≤ 5 分钟的快速子集(主单测 + 关键契约);
  • 每夜跑全集(全 E2E + 性能基线);
  • 不让"全集绿"成为合并的硬性依赖,而是"次日修复"的节奏。

这套分层是 Day 7 已给过的工程动作。三方协作的冲突 → 用工程方式化解,不要用人情协商

四、生产可观测性:测试 vs SRE

SRE 主战场,测试悄悄来"加测试红灯"。

4.1 监控规则里测试工程师该写的

回扣 Day 12 §4 SLO + burn rate 告警,SRE 通常负责的是"基础设施告警"(CPU、内存、QPS、5xx 率)。但测试工程师可以加一类规则:

yaml 复制代码
# alerts/testing-rules.yaml --- 测试工程师写的,不属于 SRE base alerts
groups:
  - name: testing_gates
    rules:
      # 规则 1:已被 @Tag("prod_incident") 标记的 case 在回归里挂了
      # 高优告警,因为这代表历史故障复现
      - alert: ProdIncidentRegressionFailed
        expr: ci_test_failures{tag="prod_incident"} > 0
        for: 5m
        labels: {severity: critical}
        annotations:
          summary: "生产故障附件用例回归失败,可能复发历史事故"

      # 规则 2:契约测试 provider verify 红灯
      # 高优,因为 provider 部署可能被 consumer 跳版本而破坏
      - alert: PactProviderVerifyFailed
        expr: pact_verify_status{side="provider"} == 0
        for: 10m
        labels: {severity: high}

这两条规则特别:测试工程师写的告警,挂在 SRE 的告警系统里。SRE 的 oncall 看到红灯时知道是"测试视角的事故预警",不会跟"CPU 80%"那类阈值告警混在一起。

4.2 SLO 共同定义

回扣 Day 15 §3,SLO 不能只 SRE 一人写。测试工程师要贡献:

  • 可用性目标:基于"测试覆盖的失败模式"反推哪些 SLI 必须达成;
  • 延迟 SLI:基于"压测容量曲线"(Day 15 §5)给 P99 阈值给数据;
  • 错误预算:基于"质量策略"(Day 18 §6.2.1)给消耗优先级。

也就是说,测试是 SLO 的输入侧,SRE 是 SLO 的执行侧。两边都不写就是空契约。

python 复制代码
# slo-definition.yaml 三方共建(Day 18 §6.2.1 + Day 15 + 这一节)
slo:
  - name: order-api-availability
    target: 0.999
    # 由 SRE 写:基于生产 SLI 历史数据派生
    rationale_sre: "过去 90 天 5xx 率中位数 0.02%,目标 0.1%"
    # 由测试写:哪些测试红线对应这条 SLO
    rationale_test: "对应 @Tag('order_api_availability') 50 条回归 case"
    # 由 DevOps 写:部署频率对该 SLO 的影响
    rationale_devops: "每周 3 次部署,每次 0.03% 部署失败预算份额"
    window: 30d

rationale_sre / rationale_test / rationale_devops 三行字段是约定。每条 SLO 后面跟三个理由,三方对齐。这也是把"地盘"化为"协作"的工程动作。

五、上线 / 回滚决策:三方都参与

最热点的协作场景。出问题时三方看法往往不一致:

决策点 测试的看法 DevOps 的看法 SRE 的看法
何时该回滚 回归 case 持续 flaky 部署成功率 < 95% burn rate > 4x
谁按按钮 不主动按 部署者主按 oncall 主按(P0)
回滚后干啥 跑 smoke test 验恢复 看部署日志没拖尾 看 SLO 回到基线
谁主导复盘 测试补红灯 DevOps 改部署流程 SRE 写时间线

注意"谁按按钮"那一行------按钮的主人是按场景分:

  • 部署中失败(部署成功率低)→ DevOps 按钮(部署者);
  • 部署后 8 小时内出问题 → SRE 按钮(oncall P0);
  • 上线一周后复发历史故障 → 测试发现后报告,DevOps 按钮。

提前把"哪种场景谁按钮"写到 release playbook 里,比事后推活强 10 倍

六、典型的"三不管"地带

工业里反复出现的责任真空:

6.1 "孤儿"测试基础设施

谁维护 selenium grid / k6 cluster / Testcontainers 镜像?

  • 测试:我用,但不维护基础设施;
  • DevOps:这是测试用的,我不管;
  • SRE:不在我生产 KPI 里。

结果:跑了一年后镜像没人升级,有一天安全扫描扫出 CVE,所有人慌了。

解法 :把它当成"二级生产系统",挂 SRE 的 SLA(<= 4h 响应),但投资改造由测试主导

6.2 测试监控的数据源

测试告警需要 PR 历史 / CI 结果 / 测试覆盖率 ------ 这些数据归谁管?

  • DevOps:维护 CI,但数据出口不在职责里;
  • SRE:看的是生产指标不是 CI 指标;
  • 测试:用数据,但不维护存储。

结果:测试告警系统拼凑,数据延迟严重。

解法:DevOps 负责"数据出口"(webhook / API),测试负责"消费 + 告警规则"。

6.3 性能压测的"专属"环境

性能压测(Day 15)需要专属环境,不能跟 staging 共用。

  • 测试:我用;
  • DevOps:维护 staging,不为压测单独起;
  • SRE:还是不在我生产 KPI 里。

解法:把性能环境写成 IaC(terraform),由 DevOps 主导维护,测试只是消费者。

七、协作的工程动作:CI 友好信号

协作不能只靠"我说你听"。测试工程师应该把信号发给两边:

7.1 给 DevOps 的信号(测试质量红线)

yaml 复制代码
# ci-quality-gate.yaml
test_quality:
  min_coverage: 0.7
  max_flaky_rate: 0.02
  pact_verify: required
  perf_baseline_drift_max: 0.15   # 性能回退不能 > 15%
  fallback_action: block_merge    # 不达标 → DevOps 流水线拒绝合并

这个 YAML 由测试工程师维护,但DevOps 的 CI 工程必须读取。这就是"测试质量"翻译为"DevOps 流水线行为"的接口。

7.2 给 SRE 的信号(质量红线映射 SLO)

python 复制代码
def coverage_to_slo_risk(coverage: dict, slo_targets: dict) -> dict:
    """
    测试覆盖率 → SLO 风险评估
    回扣 Day 18 §6.2.1:让 SRE 的告警决策能"考虑"测试盲点
    """
    risky_areas = []
    for slo, target in slo_targets.items():
        # 该 SLO 关联的代码路径覆盖率
        cov = coverage.get(slo_to_path[slo], 0)
        if cov < 0.5:
            risky_areas.append({
                "slo": slo,
                "coverage": cov,
                "risk": "高",   # 测试盲区 → 这条 SLO 不"知道"会发生啥
                "recommendation": "建议把 burn rate 告警阈值从 4x 降到 2x",
            })
    return risky_areas

SRE 看到"建议阈值降一档"的输入,会比看到"测试覆盖率 60%"有用 10 倍。翻译永远是协作的桥

八、回扣系列

Day 在 Day 19 它对应
Day 1-7 §3 CI 协作(测试 vs DevOps)
Day 8 §3 TDD 红绿是 PR check 的核心
Day 9 §7.2 Pact verify 必进 DevOps 门
Day 10 §6.1 flaky runner 维护真空
Day 11 §3.1 PR check 是左移的执行点
Day 12 §4 SLO + burn rate(SRE 主)
Day 13 §7.2 LLM 报告解读成"信号"
Day 14 §6.3 压测专属环境(IaC)
Day 15 §4.2 SLO 三方共建(test 输入侧)
Day 16 §5 上线 / 回滚决策三方
Day 17 §3 PR review 协作(测试 + 开发 + DevOps)
Day 18 §1.1 三职能定位卡的成熟度

12 条回扣,跟 Day 16 / Day 17 同样级别的总调用。这是合情合理的------想讲清楚"地盘",必须把前 18 天的工具 / 流程 / 闭环全部重新调一次。

九、协作反模式

反模式 表现 后果
"Venn 图思维" 试图画出独占地盘 漏掉交叉地带
"我用你不管" 测试用 = 测试维护 测试基础设施腐烂
"数据出口"模糊 谁出口 PR / CI 数据不明确 测试告警延迟
监控规则只 SRE 写 测试红灯不在告警系统里 故障复发率高
部署门控不互联 DevOps 不知道测试质量红线 低质量合入
"StackSize 大讨论" 在层级深度上推诿 工程动作无主责

十、原则三句话

  1. 没有"独占地盘",只有"分工协作" ------ 12 项关键动作至少两个职能协作;
  2. 协作靠"工程接口" ------YAML / 文件 / API,不要靠人情协商;
  3. 测试给 DevOps / SRE 的价值,是"翻译" ------ 把质量风险翻译为 CI 行为 / SLO 输入。

十一、思考题

留给今晚:

  1. 你团队的 CI 流水线,测试 / DevOps / SRE 各自主哪几个 stage?有没有重叠或真空?
  2. 灰度发布时,谁会按"暂停 / 回滚"按钮?这个决策有 release playbook 文档吗?
  3. 你的 CI 质量门控 YAML(§7.1)是谁维护?DevOps 知道它的存在吗?
  4. 上一次故障复盘(Day 16 §4.2 时间线),时间线由谁拼起来?是 SRE 独力 + 测试 / DevOps 在旁边看吗?

十二、TL;DR

  • 三职能定位:测试(质量风险量化) / DevOps(代码到部署快稳) / SRE(生产可靠);
  • 12 项关键动作 的地盘分割矩阵 --- 没有任何一项是单职能独占;
  • CI 五阶段 + 部署两阶段 + 故障五阶段 都需要三方协主;
  • 三个 "三不管" 地带(测试基础设施 / 测试数据出口 / 性能压测环境)需要明确归属;
  • 协作靠工程接口:ci-quality-gate.yaml / SLO rationale_* / coverage_to_slo_risk 接口。

下一篇:Day 20 · 测试工程师的 OKR 与度量:把"质量"翻译为可量化指标

这是系列第 20 篇里程碑。把这一系列所有的工程动作收束为"测试团队 OKR 的指标体系" ---

defect density、testability score、flaky rate、mean time to detect、contract coverage,

让"质量"成为驱动决策的数字,而不是团队内部的形容词。下篇见 👋

相关推荐
幸福在路上wellbeing1 小时前
AI 智能体开发 · Day 2 详细学习手册
人工智能·学习
网络安全零基础教程1 小时前
零基础转行网安,前两个月具体该学什么工具
网络·学习·安全·web安全·网络安全
南清的coding日记2 小时前
7.29 Agent八股学习+小程序学习
学习
kdxiaojie2 小时前
Linux 驱动研究 —— V4L2 (14)
linux·运维·笔记·学习
承渊政道2 小时前
Linux系统学习【掌握Ext系列⽂件系统的相关内容】
linux·运维·学习·文件系统·存储结构·inode
未知违规用户2 小时前
大模型项目: 学习FastAPI 服务器开发
服务器·人工智能·python·学习·fastapi
幸福在路上wellbeing2 小时前
AI 智能体开发 · Day 3 详细学习手册
人工智能·学习·oracle
编程圈子5 小时前
操作系统学习19:缺页异常 #PF 与按需分页
学习
MartinYeung514 小时前
[论文学习]自主性如何重塑个性化对LLM智能体隐私关切与信任的影响
人工智能·学习