前置知识: Python

静态测试与同行评审

10 min入门

不运行代码就能发现缺陷:评审类型分级(临时/走查/技术评审/审查)、静态分析工具与评审度量。

知识点地图

  • 知识类别:静态测试——测试基础中的「不运行程序」分支(ISTQB Foundation 4.0 第 3 章),含同行评审四个类型与静态分析工具。
  • 解决什么问题:团队默认「测试 = 写用例跑起来」,漏掉了缺陷修复成本曲线的另一端——评审与静态分析在代码运行前就能发现缺陷,成本只有线上修复的零头。
  • 什么时候用到:设计 PR 评审流程与分级标准;决定哪类问题进评审、哪类交给工具;评估「代码评审到底该看什么」;上线前走查关键方案文档。

前置:测试概念与原则 1.4 节首次提出静态/动态之分,本文展开。与软件工程侧评审的分工:代码评审清单与技术评审面向「怎么评审好代码与设计」,本文面向「评审作为测试活动」——类型、角色、度量与门禁。

1. 心智模型:缺陷不必等到运行才存在

缺陷(defect)与失效(failure)的区别是静态测试的立论基础:缺陷是工作产品里的错误(一行写反的 if、需求文档里自相矛盾的两段),失效是运行时暴露的错误行为。代码不运行,缺陷依然存在于代码里——所以评审能「在不运行的情况下发现缺陷」,而且:

  • 需求与设计文档只能静态测试(它们没有「运行」一说),却是一切下游缺陷的源头;
  • 研究共识是缺陷发现越早修复成本越低:评审里一句话改掉的设计问题,到了线上就是事故 + 回滚 + 复盘。

三个场景理解「静态比动态早一步」:

  • 场景 A:评审发现需求文档写了「会员免运费」但没写「偏远地区除外」——上游一句话,避免下游三个团队按各自理解实现再返工。
  • 场景 B:静态分析扫出 password 变量硬编码——运行测试完全正常(功能没错),但缺陷已经在那。
  • 场景 C:评审中作者口头解释了「这个魔法数字 86400 是一天的秒数」——注释顺手补上,可读性缺陷不等到三个月后有人猜错。

2. 评审的四个类型:从轻到重

ISTQB 按正式程度分四级,区别在角色分工与流程约束,而不在「认真程度」:

类型正式度角色典型场景产出
临时评审(informal)无流程无固定角色同桌随口看一段代码、结对口头意见
走查(walkthrough)轻作者主导,向评审者讲解新人讲解方案、团队走查支付回滚文档会议记录
技术评审(technical review)中技术专家主导讨论一致性架构决策、接口协议评审评审意见清单
审查(inspection)高主持人/作者/记录员/评审者/计时员,规则驱动安全关键代码、合规交付物缺陷清单 + 度量数据
  • 选型口诀:问题的「出错代价」决定正式度。改文案用临时评审;核心支付链路的方案文档用走查;跨团队接口协议用技术评审;金融合规代码用审查。反过来「所有 PR 都开审查会」会把团队拖死——四个类型是档位不是台阶。
  • 走查与审查的辨别易错点:走查的作者是主讲(目的是让评审者理解与发现问题),审查的主持人中立、作者只回答提问(目的是按检查单系统挖掘)。混用的症状是「审查会开成了作者答辩会」。

工程场景(上线前走查支付回滚方案文档):大促前一周,支付团队开 45 分钟走查会:作者按「触发条件 → 回滚步骤 → 数据补偿 → 责任人」讲一遍,每个评审者领一个视角(DBA 盯数据补偿、SRE 盯触发条件阈值、业务盯资损口径)。走查发现的三个问题里有一个致命——回滚脚本假设了旧表结构,而本周迁移已经改了它。这份走查记录就是后来事故预案的直接前身。

3. 一次 PR 评审:三类问题的分流

真实 PR 评审里的问题混杂三种性质,分流处理才不会把评审变成格式吵架:

问题类型例子处理方式
风格类变量命名、缩进、导入顺序交给工具:linter/formatter 自动修,评审里不讨论
缺陷类空指针分支、边界条件、并发问题评审核心职责:必须逐条指出并给出理由
设计类模块边界、抽象层次、依赖方向评审 + 讨论:重大时另开技术评审,PR 里标记跟进

分流带来的两条工程实践:

  1. 评审前自动门禁:linter、类型检查、单测不过不进入人工评审——人的注意力只花在工具做不了的事上(缺陷与设计)。
  2. 评审意见分级:blocking(缺陷必须改)、nit(风格建议,作者自决)、question(讨论后再定)。新人评审常见失败是所有意见一个声调,作者无法分辨哪条不改不能合。

4. 静态分析工具:把「风格与已知模式」交给机器

静态分析工具不运行代码、按规则扫描源码或 AST。与安全测试的分工:

工具层关注点代表归属
Linter/格式化风格与低级错误ESLint、gofmt、ktlint质量门禁
通用静态分析复杂度、重复、坏味道SonarQube质量门禁
SAST(安全静态分析)可被利用的漏洞模式(注入、XSS、硬编码密钥)Semgrep、CodeQL、Checkmarx安全测试,见安全测试
  • 分工的关键差别:通用静态分析说「这段代码复杂、这段重复」;SAST 说「这个输入流没经过净化就进了 SQL 拼接」。质量门禁里的静态分析盯可维护性,SAST 盯可利用性——同一份代码两种问题域,工具不同、门禁阈值也不同。
  • 误报治理是静态分析落地的第一敌人:一刀切全量开规则,几百条误报让团队学会「无视告警」。正确路径是从高置信规则集起步、基线模式(存量问题冻结不新增)、按目录分级阈值。
  • 易错点:静态分析不能替代评审——它看不出「这个业务逻辑不该在退款接口里出现」,规则匹配的是模式不是意图。

5. 评审度量:评审过程本身也要被测量

两个核心指标(ISTQB 列举的评审度量中最常用的):

  • 缺陷密度:单位规模发现的缺陷数(如每 KLOC 缺陷数、每页文档问题数)。用于横向比较不同模块/文档的质量水位——支付模块评审缺陷密度显著高于工具模块,说明前者需要更重的评审档位。
  • 评审效率:单位投入发现的缺陷数(缺陷数 / 评审人时)。用于改进过程——走查 2 小时发现 3 个缺陷,改用带检查单的审查后同样投入发现 9 个,说明这类交付物适合审查。

度量使用的两条纪律:

  1. 度量过程,不考核个人:评审发现缺陷数排名会立刻制造「少提意见=和气」的反向激励;度量对象是评审类型与交付物类型,不是人。
  2. 配套跟踪缺陷逃逸:评审漏掉、测试才发现的问题记回评审改进项——检查单就是这么长出来的。

6. 与动态测试的边界

静态测试的盲区恰好是动态测试的主场,两者是互补不是替代:

问题静态能发现吗说明
语法错误、硬编码密钥、空分支能规则可匹配
文档自相矛盾能(只能静态)文档无「运行」
复杂度与坏味道能指标可量化
运行时竞态、超时、内存泄漏不能需要真实执行
集成点契约不匹配部分类型系统可查部分,运行时行为要测

动手实践

任务(背景取自 GZ034 软件测试赛题任务 3「测试文档」的结构):为一份《测试计划》文档设计一次 45 分钟走查:

  1. 列走查角色分工(作者、主持人、三个视角评审者);
  2. 为三个视角各写 3 条检查单条目(提示:范围视角——「测什么」有没有漏模块;度量视角——进退出准则是否可判定;资源视角——环境与人员是否闭环);
  3. 设计走查记录表字段(问题、位置、严重级、责任人与截止时间);
  4. 写出「这份文档该用走查而不是审查」的理由各一条。
参考要点(先自己写,再展开对照)
  • 角色分工:作者主讲(按文档目录顺序);主持人控时并汇总问题;评审者按视角提前 30 分钟通读并带问题入场。
  • 检查单示例(范围视角):每个功能模块是否都有对应测试项;非功能(性能/安全)是否被提及或显式排除;回归范围是否声明。度量视角:进入准则是否可验证(如「冒烟 100% 通过」而非「基本稳定」);退出准则是否含遗留缺陷处置规则。资源视角:环境账号与数据准备是否有责任人;测试与开发人力比例是否写明。
  • 记录表字段:编号、位置(章节/页)、问题描述、严重级(致命/严重/一般/建议)、处理决定(修改/澄清/搁置)、责任人与截止时间。
  • 用走查的理由:测试计划的可理解性比逐字正确性更重要,作者讲解能高效传递上下文;文档非安全关键交付物,审查的高流程成本不划算。(反过来说,若这是监管报送文档,审查的规则驱动与度量留档就是必选——同一文档不同代价不同档位。)

常见陷阱

  1. 评审变成风格吵架:风格问题没在进入评审前被工具拦掉;先门禁后评审。
  2. 所有 PR 一个档位:改文案和改支付核心用同样流程,要么重要么漏;按出错代价选类型。
  3. 审查会开成作者答辩:主持人缺位、作者主导全场;审查的中立主持是角色不是虚职。
  4. 度量考核个人:评审意见数变成绩效,团队学会沉默;度量只对过程改进负责。
  5. 静态分析一刀切全规则:误报洪水教会团队无视告警;高置信起步 + 基线冻结。

相关阅读

参考与致谢

  • ISTQB Certified Tester Foundation Level Syllabus v4.0 第 3 章 Static Testing(ISTQB 开放大纲,引用其分类框架;本文表述与示例均为原创重写):https://www.istqb.org/
  • 评审类型与角色定义遵循 ISTQB v4.0 术语表(informal review / walkthrough / technical review / inspection)。