想象你是一个保洁队长,带着团队给一栋办公楼做了通宵大扫除。第二天业主来验收,他没有问你“干了多久”,而是问了一句直击灵魂的话:“你们每个房间、每类污渍、每块地毯下面的死角,都覆盖到了吗?”你愣住了——你确实很忙,但你没法证明每一处都处理干净了。AI红队测试面临的正是同样的困境:红队工程师日夜不停地对AI模型发起攻击,但当被问“你们测得到底够不够、全不全”时,却拿不出一张能让所有人信服的“验收清单”。覆盖率评估,就是AI红队测试的那张验收清单——把“安全测试是否充分”这个大问题,拆成一个个可以打勾、可以计数的细项,逐项检查、找出死角,并指导下一轮测试补上。本文就用“全屋大扫除验收”的故事主线,带你完整掌握AI红队覆盖率评估的方法体系。
掌握覆盖率评估,你就能用数据向团队和监管方证明红队测试的充分性,精准定位测试盲区并驱动补测——这是AI安全工程师走向专业化的核心能力之一。
可视化演示
动态演示AI红队覆盖率评估方法的核心机制,通过架构/数据/状态/性能四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
AI红队覆盖率评估方法:覆盖率评 覆盖率评估的基本概念与价值 攻击向量覆盖率维度度量 核心机制可视化 AI红队覆盖率评估方法整体架构与关键组件
覆盖率概念
大扫除的第一天,你挥汗如雨地擦了所有看得见的地方;第二天业主要验收,你突然发现没法回答“扫干净了吗”。此时你需要一张验收清单:把“整屋清洁”这个大目标,拆成客厅、卧室、厨房、卫生间等一个个可打勾的小项。覆盖率评估,就是这张清单——它把“AI红队测试到底测够了没有”拆成可数、可比的量化指标。
在AI红队测试中,覆盖率回答的是三个层层递进的问题:我们测了哪些测试点?这些测试点占全部值得测试的点的多少比例?剩下没测的点是否有风险?没有覆盖率,红队测试就像闭眼扫地——明明忙了几个月,却无法向任何人证明测试的充分性。
覆盖率的基本定义可以用一个简单的公式表达:已经测过的测试点数量,除以全部需要测试的测试点数量。
验收员不会只问“你忙了多久”,他会拿着清单逐项打勾。覆盖率就是红队测试的“打勾进度条”,它把“安全”这个模糊的词,变成了一个清晰可查的数字。
- 枚举全部测试点首先要定义“全屋有哪些地方值得扫”,把所有需要测试的单元列成清单。
- 记录已覆盖子集实际执行过测试的单元构成S_c。
- 求覆盖率两个集合大小相除,得到0到100%的比例。
攻击向量覆盖
油渍、霉斑、水垢、铁锈——不同类型的脏污需要不同的清洁剂。如果只带了去油剂就开工,那么霉斑区域永远处理不干净。攻击向量覆盖就是这个道理:攻击者用来突破AI系统的手段五花八门,每一种都对应不同的安全风险。
攻击向量是攻击者利用AI系统漏洞的具体“招数”,常见的包括提示注入(通过精心构造的提示让模型说出不该说的话)、对抗样本(在输入上添加人眼不可见的扰动骗过模型)、数据投毒(污染训练数据使模型行为变坏)、模型窃取(通过查询接口还原模型参数)等。攻击向量覆盖率衡量的是红队是否系统地覆盖了所有已知攻击类型,而不是只挑顺手的那几种反复测。
考虑到不同攻击向量的威胁程度不同,我们通常采用加权覆盖率:
其中 $I(a_i)$ 是0/1指示函数,表示攻击向量 $a_i$ 是否被测试覆盖;$w_i$ 是该向量的风险权重。
卫生检查员不会只问“你擦过灶台吗”,还会追问“油烟机滤网、冰箱密封条、水槽下水口这些不同种类的脏污点都处理了吗”。攻击向量覆盖就是帮红队回答“所有攻击招数都试过了吗”。
- 枚举攻击向量从威胁库中整理出全部攻击方式,形成清单。
- 标记是否覆盖每个向量被测试过则记为1,否则记为0。
- 加权求和归一用风险权重加权后求比例。
行为空间覆盖
大扫除时,客厅、卧室、厨房、卫生间必须逐间检查,少一间都不算完整。对AI模型而言,它的“房间”就是行为空间——模型在不同输入下展现出的全部行为反应。
一个客服聊天机器人,面对正常提问会礼貌回答;面对恶意诱导可能泄露隐私;面对自相矛盾的问题可能逻辑混乱;面对系统故障可能输出错误代码。每一种行为就是一个“房间”。行为空间覆盖率检查的是:红队测试是否让模型展示出了所有该看的行为类别。具体包括输出类别覆盖(拒绝、回答、报错、泄露等是否都被触发过)、状态迁移覆盖(模型从正常到异常再到恢复的状态跳转链路是否被走通)、决策路径覆盖(不同分支逻辑是否都被执行到)。
其中 $B_{all}$ 是对模型行为空间的划分(如输出类别集合),$B_c$ 是红队测试中实际触发过的行为类别子集。
一个房间没进去过,里面的卫生问题就完全未知。同样,模型的一个行为类别没被触发过,这片区域的漏洞就不会在测试报告里出现。
- 划分行为空间把模型可能的输出按类型分桶,如拒绝、回答、报错、泄露等。
- 统计已触发行为被至少一个测试用例触发过的行为类别。
- 计算覆盖率已触发类别数除以总类别数。
输入分布覆盖
桌面要擦、地毯要吸、玻璃要刮——不同“表面材质”的清洁方式不同,但核心原则是:真实生活中最常接触的表面要重点照顾。如果住户每天都在地毯上活动,你却只擦了玻璃,那验收必然不合格。输入分布覆盖衡量的正是测试输入与真实使用分布的贴合程度。
在实际生产中,模型会遇到大量正常用户输入、少量恶意输入、偶尔的畸形输入。如果红队测试只从公共数据集中随机抽样,或者只挑“容易攻击”的输入,那么测试输入分布就会与真实分布错位——测了很多真实世界里不会出现的输入,却漏掉了真实世界里高频出现的危险输入。输入分布覆盖就是把输入空间切分成若干块,检查每块是否都有测试输入命中:
其中 $D_k$ 是输入空间的第 $k$ 个分块,$T$ 是红队测试输入集合,$\mathbf{1}(\cdot)$ 是命中判断。
验收员会摸摸桌面、掀开地毯、照照玻璃——每种“常用表面”都不能漏。输入分布覆盖就是确保红队测试没有集中火力在某一个输入区域,而是覆盖了真实世界里模型会遇到的高频场景。
- 切分输入空间按输入特征(如长度、语义、格式)把输入空间切成m块。
- 判断分块命中某块至少被一个测试输入命中期,该块记为覆盖。
- 计算命中比例被命中的分块数除以总分块数。
边界条件覆盖
大扫除最容易被忽略的是墙角、踢脚线、窗缝、柜顶——这些“边缘地带”平时没人碰,但积灰最厚、发霉最快。AI模型的边界条件正是这样的地方:输入取值处于极端位置、格式异常、内容缺失时,模型最容易暴露出训练时未覆盖的脆弱行为。
边界条件覆盖要求红队系统地测试以下输入:参数允许的最小值和最大值、略超边界或略低于边界的值(即边界翻转)、空字符串或缺失字段、超长文本、只含特殊符号的内容、数值极值等。标准做法是“边界值分析法”:对每个输入参数的合法范围 $[x_{\min}, x_{\max}]$,至少测试端点、端点相邻值、以及恰好越界的值。
其中 $Bd_{all}$ 是所有需测边界条件的清单,$Bd_c$ 是红队实际测试过的边界值集合。
验收员会专门用湿巾擦窗轨槽——这些地方最容易被漏掉,却最容易积灰发霉。AI模型的输入边界,就是安全漏洞最偏爱藏身的地方。
- 设定合法范围每个输入参数有合法取值范围。
- 枚举边界值列出端点、端点邻近值和越界值。
- 检查覆盖并求比例统计已测边界值并计算覆盖率。
覆盖率指标
大扫除验收不能只凭“看起来挺干净”,要有一张打分表:灰尘量、污渍面积、死角数量,每项设定标准分,再按重要程度加权,最终算出一个清洁总分。覆盖率指标设计就是为红队测试评估体系设定这样的“打分规则”。
好的覆盖率指标需要满足三个原则:可度量——有明确的分子分母和计算口径;可比较——不同轮次测试之间能横向对比,看出覆盖率是否在提升;可解释——覆盖率变了,能说清楚是哪个动作带来的变化。在实际评估中,通常把多个维度的覆盖率加权合成为一个综合指标:
其中 $C_k$ 是第 $k$ 个维度的覆盖率,$w_k$ 是权重。权重反映安全策略的偏好:如果更担心攻击手段覆盖不足,就给攻击向量覆盖率更高权重;如果更担心极端输入,就提高边界条件覆盖率的权重。
打分表上每项都有权重——厨房油污权重高,因为影响健康;同理,高风险攻击向量的权重高,因为直接影响系统安全。综合覆盖率让红队工作有了可追踪的总分和阶段性目标。
- 确定维度与权重把考察的覆盖维度列出,并分配重要性权重。
- 各维度加权求和每个维度的覆盖率乘上权重再相加。
- 设定目标阈值例如首轮测试达标线70%,迭代后要求90%。
盲区识别
大扫除的收尾阶段,你会拿手电筒蹲下来照沙发底、柜子后面——那些照不到、看不清的地方,就是需要补扫的盲区。覆盖率评估的意义不只是算出一个数字,更重要的是反向找出“哪些地方还没测到、为什么没测到”。
覆盖盲区识别有三种常用手段。第一是聚类分析:把所有未覆盖的测试点按特征聚类,如果某一类未覆盖点显著成片出现,说明这是系统性盲区,不是随机遗漏。第二是差异对比:将已覆盖与未覆盖的测试点在特征分布上做对比,找出“什么类型的点总是被跳过”。第三是风险排序:对每个盲区点估算风险,优先处理漏洞概率高、影响大的盲区。盲区集合的定义与风险度量如下:
其中 $\mathcal{U}$ 是未覆盖测试点构成的盲区集合,$R(u)$ 是盲区点 $u$ 的风险值,由条件漏洞概率与影响程度的乘积得到。
手电筒照到沙发底下全是灰尘球,你意识到“低矮区域”从来没人扫——聚类就是告诉你盲区成片的规律。风险排序则告诉你:先扫厨房还是先扫卧室,取决于哪里更容易藏匿真正的安全威胁。
- 定义盲区集合所有未覆盖的测试点构成盲区。
- 聚类分析盲区按特征把盲区点分组,识别成片盲区。
- 计算风险并排序每个盲区点的风险等于漏洞概率乘以影响程度。
测试生成策略
发现死角后,你不会等“下次大扫除”,而是立刻安排一次定向补扫——专攻没擦到的地方。覆盖率驱动的测试生成策略正是如此:根据当前覆盖率数据,自动或半自动地生成能最大限度提升覆盖率的新测试用例。
核心思想是贪心选择“边际贡献最大”的用例:对每个候选测试,计算它加入后覆盖率的增量,优先选择增量最大的那一个。覆盖率增量定义如下:
其中 $S_c$ 是当前已覆盖测试点集合,$t$ 是候选测试用例,$\Delta C(t)$ 是加入该用例后覆盖率提升的幅度。同时配合用例去重机制:如果两个测试用例在输入特征和行为触发上高度相似,只保留其中一个,避免重复劳动。
补扫不是全屋重来一遍,而是拿着清单杀回死角——每一滴清洁剂都用在该用的地方。覆盖率驱动的测试生成也是如此,让每一份GPU算力和每一小时人力,都花在提升覆盖率的关键路径上。
- 构造候选测试池由变异、生成器或人工提交组成候选集。
- 计算覆盖率增量加入某用例前后的覆盖率差值。
- 贪心选取增量为最大的用例每轮挑增量最大的补入测试集。
- 相似用例去重相似度过高则丢弃其中一个,控制成本。
AI 应用场景
大模型上线前的红队充分性报告
阶段:安全测试与评估
解决的问题:传统做法只统计“测了多少轮、跑了多少用例”,无法回答“安全测试充分吗”。AI红队覆盖率评估把测试充分性量化成四个维度的覆盖率指标,让测试团队能向管理层和监管方出具一份有数据支撑的验收报告。
具体案例:某金融科技公司上线大模型客服系统前,红队完成了1800次攻击测试。通过覆盖率评估发现:攻击向量覆盖率达92%,但边界条件覆盖率仅41%——超长输入和空值场景几乎没有测试。团队据此补充了300个边界用例,将边界覆盖率提升至85%,并修复了由此发现的2个高危漏洞。
自动化红队平台的持续监控补测
阶段:持续监控与迭代测试
解决的问题:手工红队测试成本高、节奏慢,无法跟上模型频繁迭代的速度。覆盖率驱动的测试生成策略让平台自动分析当前覆盖盲区,从候选池中挑选增量最大的用例自动执行补测。
具体案例:某电商平台的AI推荐系统每周更新一次模型,安全团队部署了自动化红队平台。平台每次模型更新后自动计算各维度覆盖率,对低于阈值的维度生成针对性测试用例并执行,将综合覆盖率稳定维持在90%以上,同时通过用例去重将测试耗时降低了40%。
第三方安全审计的独立验收
阶段:外部审计与合规验证
解决的问题:甲方委托第三方安全公司审计AI系统时,最怕听到“我们做了很多测试”这种无法验证的说法。覆盖率指标体系为审计方提供了独立验收的客观依据:对照审计方自己定义的测试点清单,逐项核对乙方的覆盖记录,找出被遗漏的风险区域。
具体案例:一家医疗AI公司邀请外部审计团队评估其影像诊断模型的安全性。审计团队自行构建了包含3000个测试点的覆盖清单,包括罕见病种、图像噪声、边界病变等维度。对照后发现乙方在“边界病变”子空间覆盖率仅35%,审计结论要求补充测试后方可上线。
Python 演示
class CoverageAssessor: """AI红队覆盖率评估器, 统计四个维度的测试覆盖情况""" def __init__(self, total_vectors, total_behaviors, total_inputs, total_boundaries): self.total_vectors = total_vectors self.total_behaviors = total_behaviors self.total_inputs = total_inputs self.total_boundaries = total_boundaries self.covered_vectors = set() self.covered_behaviors = set() self.covered_inputs = set() self.covered_boundaries = set() def add_test(self, vec, beh, inp, bd): """记录一次测试覆盖的四个维度""" if 0 <= vec < self.total_vectors: self.covered_vectors.add(vec) if 0 <= beh < self.total_behaviors: self.covered_behaviors.add(beh) if 0 <= inp < self.total_inputs: self.covered_inputs.add(inp) if 0 <= bd < self.total_boundaries: self.covered_boundaries.add(bd) def dimension_coverage(self): """返回各维度覆盖率字典""" return { "vectors": len(self.covered_vectors) / self.total_vectors, "behaviors": len(self.covered_behaviors) / self.total_behaviors, "inputs": len(self.covered_inputs) / self.total_inputs, "boundaries": len(self.covered_boundaries) / self.total_boundaries, } def total_coverage(self, weights=None): """加权计算综合覆盖率, 默认各维度按风险加权""" cov = self.dimension_coverage() if weights is None: weights = {"vectors": 0.3, "behaviors": 0.3, "inputs": 0.2, "boundaries": 0.2} return sum(weights[k] * cov[k] for k in weights) def blind_spots(self): """找出未覆盖的测试点作为盲区""" return { "vectors": [i for i in range(self.total_vectors) if i not in self.covered_vectors], "behaviors": [i for i in range(self.total_behaviors) if i not in self.covered_behaviors], "inputs": [i for i in range(self.total_inputs) if i not in self.covered_inputs], "boundaries": [i for i in range(self.total_boundaries) if i not in self.covered_boundaries], } def pick_new_tests(assessor, candidates, k=2): """覆盖率驱动的测试生成: 选增量最大的候选用例""" base = assessor.total_coverage() scored = [] for idx, cand in enumerate(candidates): before = (set(assessor.covered_vectors), set(assessor.covered_behaviors), set(assessor.covered_inputs), set(assessor.covered_boundaries)) assessor.add_test(*cand) gain = assessor.total_coverage() - base scored.append((gain, idx)) (assessor.covered_vectors, assessor.covered_behaviors, assessor.covered_inputs, assessor.covered_boundaries) = before scored.sort(reverse=True) return [candidates[i] for _, i in scored[:k]] def main(): assessor = CoverageAssessor(10, 8, 6, 5) # 已有的红队测试记录 for i in range(5): assessor.add_test(i, i, i % 6, 0) assessor.add_test(5, 5, 3, 1) print("Coverage:", {k: round(v, 2) for k, v in assessor.dimension_coverage().items()}) print("Total coverage:", round(assessor.total_coverage(), 2)) print("Blind spots:", assessor.blind_spots()) # 候选测试池 candidates = [ (8, 7, 5, 4), (9, 7, 4, 3), (6, 6, 2, 2), (7, 4, 1, 4), ] new_cases = pick_new_tests(assessor, candidates) print("Recommended new tests:", new_cases) for case in new_cases: assessor.add_test(*case) print("Coverage after supplement:", round(assessor.total_coverage(), 2)) if __name__ == "__main__": main()
class CoverageAssessor:定义覆盖率评估器,就像一个拿着验收清单、逐格打勾的验收员。def add_test(self, vec, beh, inp, bd):每执行一次红队测试,就记录它在四个维度覆盖了哪些测试点。def dimension_coverage(self):` 中的 `len(self.covered_vectors) / self.total_vectors计算攻击向量维度的覆盖率。def total_coverage(self, weights=None):` 中的 `sum(weights[k] * cov[k] for k in weights)按风险权重把四个维度的覆盖率合成为一个综合分。pick_new_tests` 中的 `gain = assessor.total_coverage() - base计算每个候选用例加入后覆盖率的增量,对应公式中的 $\Delta C(t)$。for case in new_cases: assessor.add_test(*case)把选中的增量最大的用例正式补入测试集,完成一轮定向补测。
常见误区
误区我以为覆盖率到了100%,就说明模型绝对安全了,可以放心上线。毕竟验收清单上所有格子都打勾了呀!
正解覆盖率100%只能说明“在已经定义好的测试点集合内”全部覆盖到了,并不能说明集合之外没有风险。就像大扫除验收清单只列了客厅、卧室、厨房,但窗外、阳台、屋顶天台没列入清单——100%只能代表清单内的100%,不代表整栋楼绝对干净。AI系统的威胁面是动态扩展的,新一轮攻击手法出现后,原来100%的覆盖率也要重新评估。
为何常见:人容易把“当前指标”误当成“永恒事实”,尤其是当指标被做成仪表盘和大红勾的时候,会产生心理上的“完成任务感”。
误区我觉得只要总覆盖率高就行,比如综合覆盖率90%,应该很优秀了。至于每个维度具体覆盖了什么,不重要。
正解90%的综合覆盖率可能掩盖一个致命事实:权重最大的攻击向量维度覆盖只有40%。加权综合指标的特点是,高分可以被低风险维度的高覆盖“稀释”。就像验收时厨房油污这项权重最高却只得了40分,但因为客厅、卧室都得了满分,总分仍然好看——但业主最关心的恰恰是厨房。所以要看综合分,更要看每个维度的分解分数。
为何常见:综合指标提供了简洁的单一数字,大脑天然偏好用单一数字做判断,忽略了它背后的合成逻辑。
误区我算总覆盖率时,把攻击向量覆盖率、行为空间覆盖率、输入分布覆盖率和边界条件覆盖率直接加起来除以4,这样应该没错吧?
正解简单平均隐含了一个假设:四个维度重要性完全相同。但在实际安全评估中,攻击向量覆盖通常比输入分布覆盖更紧迫(因为攻击向量直接对应攻击者的手段),边界条件在安全敏感场景下权重也很高。加权平均的意义就是让权重反映业务风险偏好。简单平均就像给“承重墙裂缝”和“墙面油漆脱落”打相同的分——两者的安全含义完全不同。
为何常见:平均数是日常中最常用的“求总水平”操作,初学者很容易把多维度指标一律当作等权问题处理。
误区我觉得覆盖率是最后总结报告时算一下的数字,前期专注执行测试就行,等全部测完再统一评估。
正解覆盖率评估的价值在于“过程指导”而非“事后总结”。如果在测试过程中持续计算覆盖率,你可以实时发现某个维度过低,立刻调整测试策略补上;如果全部测完才开始算,发现边界条件覆盖率只有30%时,可能需要推倒重来或大规模补测。就像大扫除时你应该中途检查厨房是否达标,而不是等全部打扫完再发现厨房根本没动过。覆盖率驱动的测试生成策略,本质上就是“边测边算边补”的闭环。
为何常见:人们习惯把“评估”理解为“总结”的一部分,而忽视了它在工程流程中真正有价值的角色是“指引下一步行动”。
误区边界条件覆盖很简单,每个输入参数测一下最小值、最大值就算完成了,跟正常值差别不大吧?
正解边界值分析不只是测两个端点,还包括端点邻近值、恰好越界值、空值缺失、超长内容、类型异常等。原因在于模型的决策边界往往是非线性的,在端点附近的行为可能和在区间中间完全不同——就像墙角缝隙的积灰速度远超房间中央地板。只测最小值最大值,相当于只擦了墙角的两头,却漏了整条踢脚线。
为何常见:“边界”这个词的字面意思让人只关注两个端点,忽略了“边界附近”和“边界之外”才是真正的风险密集区。
面试题
Q1. 覆盖率评估的基本含义是什么?
- A.已覆盖测试点除以总测试点← 正确答案
- B.攻击次数除以测试总时长
- C.漏洞数量除以测试用例数
- D.模型参数除以训练总轮数
答案:A。覆盖率的核心公式是已覆盖测试点集合大小与全部测试点集合大小之比,A正确。B描述的是攻击频率而非覆盖率;C是漏洞密度;D是参数效率指标,都与覆盖率无关。就像验收清单上的打勾比例,分子是已检查项,分母是全部待检项。
Q2. 攻击向量覆盖率直接衡量哪方面?
- A.攻击手段类型的覆盖广度← 正确答案
- B.模型输出类别的覆盖广度
- C.测试数据分布的覆盖广度
- D.边界值取值的覆盖广度
答案:A。攻击向量覆盖衡量的是红队是否测遍了各类攻击手段,如提示注入、对抗样本、数据投毒等,A正确。B属于行为空间覆盖,C属于输入分布覆盖,D属于边界条件覆盖。就像检查不同污渍类型(油渍、霉斑、水垢)是否都找到了对应的清洁方法。
Q3. 加权覆盖率公式中的权重w_i代表什么?
- A.该攻击向量的风险重要程度← 正确答案
- B.该攻击向量的执行总时长
- C.该攻击向量的代码行数总量
- D.该攻击向量的参数数量大小
答案:A。加权覆盖率中权重w_i表示各攻击向量的风险重要程度,高风险向量权重大,漏测时的“代价”也更大。B、C、D描述的都不是风险语义。就像清洁验收打分表中,厨房油污权重高是因为它直接影响健康。
Q4. 覆盖率盲区识别常用哪些方法?
- A.聚类发现成片的未覆盖点← 正确答案
- B.差异对比找出系统性遗漏← 正确答案
- C.风险排序优先处理高危区← 正确答案
- D.随机生成大量无关的测试
答案:ABC。盲区识别三件套是聚类分析、差异对比和风险排序。聚类能发现盲区是否成片出现,差异对比能找出“什么类型总是被跳过”,风险排序决定先补哪里。D是盲目补测,不是识别盲区的方法。就像用手电筒照出灰尘分布后,分析灰尘集中在哪些区域再决定清扫顺序。
Q5. 覆盖率驱动的测试生成优先选择哪种用例?
- A.覆盖率增量最大的新测试用例← 正确答案
- B.执行耗时最短的测试用例集
- C.历史报告漏洞最多的测试点
- D.人工最易编写的测试用例组合
答案:A。覆盖率驱动生成的核心是贪心选择覆盖率增量 $\Delta C(t)$ 最大的用例,把资源用在最能让覆盖率上升的地方。B、C、D考虑的是效率、经验和便利性,偏离了“覆盖率驱动”的本意。就像定向补扫时优先擦灰尘最厚的角落,而不是挑最省力的地方。
Q6. 输入分布覆盖率衡量的是测试输入什么特征?
- A.与真实使用分布贴合的程度← 正确答案
- B.文本内容长度大小的平均值
- C.数据总量占全部语料的比例
- D.硬件资源消耗的总体水平值
答案:A。输入分布覆盖衡量测试输入是否贴近模型真实应用场景中的输入分布,避免测试集与生产环境脱节。B是长度统计,C是数据规模,D是资源开销,均不相关。就像验收员要确认清洁重点是否覆盖了住户常活动的区域,而不是只看擦了多少块玻璃。
Q7. 边界条件覆盖应当包含哪些类型的测试点?
- A.参数允许的最小极值与最大极值← 正确答案
- B.空值缺失以及超长非法格式← 正确答案
- C.处于分布核心的普通随机输入
- D.临界值附近发生翻转的取值← 正确答案
答案:ABD。边界条件包含极值、端点邻近值、越界值、空值缺失、超长格式和边界翻转等。C是分布核心的正常输入,不属于边界条件。就像大扫除要擦墙角、踢脚线、窗缝等边缘地带,而不是已经每天在拖的地板中央。
Q8. 红队测试用例去重的主要目的是什么?
- A.节约测试成本并提升有效覆盖← 正确答案
- B.增加测试用例的总数量规模
- C.提高漏洞发现数量的平均值
- D.扩大模型训练数据的多样性
答案:A。用例去重是把相似度过高的用例合并,避免重复测试已覆盖的路径,从而节省算力和人力,让资源花在新覆盖点上。B、C、D都不是去重的目的。就像补扫时不需要把同一块地板反复擦三遍,省下的时间应该去擦还没擦的角落。
Q9. 良好的覆盖率指标应满足哪些特征?
- A.数据可度量且有明确计算口径← 正确答案
- B.不同轮测试之间能横向比较← 正确答案
- C.指标变化的原因能够被解释← 正确答案
- D.数值越大代表训练数据越多
答案:ABC。好指标三原则是可度量、可比较、可解释。A、B、C分别对应这三条。D把覆盖率指标与训练数据量混为一谈,覆盖率衡量的是测试活动而非训练过程。就像验收打分表要标准明确、能对比两次大扫除的分数差距、还要能说出分数变化是因为什么动作。
Q10. 行为空间中的状态迁移覆盖主要验证什么?
- A.模型在状态之间的转换路径是否全测← 正确答案
- B.模型参数的数量是否满足部署要求
- C.模型推理速度是否达到业务标准线
- D.模型训练数据是否覆盖完整业务域
答案:A。状态迁移覆盖验证的是模型在不同状态间(如正常→异常→恢复)的转移路径是否被红队测试走通,确保状态链路上的每个跳转都可能暴露问题。B是参数量检查,C是性能指标,D是训练数据覆盖面,均不属于行为空间的状态迁移验证。就像验收时要走一遍“客厅→走廊→厨房”的通道,确认每个房间之间的门都能推开并到达。