车载测试用例开发-如何平衡用例覆盖度和测试效率的方法论

1 摘要

在进行车载测试用例编写时,会遇到多个条件导致用例排列组合爆炸的情况,但是为了产品测试质量,我们又不得不保证用例设计的需求覆盖度,这样又会使得测试周期非常长。我们如何平衡效率和测试质量?本文进行了一些思考。

2 需求分析

2.1 需求规格矩阵

条件类型 逻辑表达式 时序约束 输出行为 安全等级
使能条件 a ∧ b ∧ c - - ASIL B
阶段1触发 d ∨ e t₀时刻 输出g ASIL A
阶段2触发 (d∨e) ∧ f t₁=t₀+Δt (Δt≥10ms) 追加输出h,i ASIL C
退出条件 j ∨ k ∨ l 任意时刻 立即停止g,h,i ASIL D

以上需求描述:

  • 使能条件a&b&c全部满足时,如果触发条件d | e满足,则执行输出g,并记录时间t0;
  • t0时间后10ms,如果触发条件f满足,则执行输出h、j;
  • 以上任意时刻,退出条件j |k | l满足时,立即停止输出g、h、i;

3 用例设计

3.1 正交表设计(L₁₆(2¹⁵)扩展时序+退出条件)

以下是根据时序需求优化的正交表法测试用例设计,严格遵循ISO 26262和ASPICE标准,包含完整用例集及方法论标注:

用例ID a b c d e f j k l Δt 预期输出序列 优先级 导出方法 测试要点
1 1 1 1 1 1 1 0 0 0 15ms g→h,i 冒烟 需求分析 全条件复合触发
2 1 1 1 1 0 0 0 0 0 - g 需求分析 仅阶段1触发
3 1 1 1 0 1 1 0 0 0 10ms g→h,i 需求分析 e替代d触发
4 1 1 0 1 1 0 0 0 0 - 无输出 等价类划分 使能条件不成立
5 1 0 1 0 1 1 0 0 0 - 无输出 等价类划分 单使能条件失效
6 0 1 1 1 0 1 0 0 0 - 无输出 等价类划分 使能条件a缺失
7 1 1 1 1 0 1 1 0 0 20ms g→h,i→立即停止 安全需求分析 退出条件j触发
8 1 1 1 0 0 1 0 1 0 5ms g→h,i→立即停止 时序约束分析 最小Δt边界+退出条件k
  • 关键扩展用例(时序+故障注入)
用例ID 测试场景 输入序列 预期输出 优先级 导出方法
9 Δt=9ms(违反最小值) d=1→f=1(9ms后) g(h,i不输出) 边界值分析
10 f先于d∨e触发 f=1→d=1(10ms后) 无输出 错误猜测
11 退出在阶段1触发后 d=1→j=1(5ms)→f=1 g→立即停止 冒烟 状态转换测试
12 重复触发3次 (d=1→f=1)×3(Δt=15ms) 重复输出g→h,i 压力测试

3.2 正交表筛选原则详解

  1. 两两组合覆盖

    • 因素对:共C(9,2)=36对(a~l的二元组合)

    • 覆盖策略

      python 复制代码
      # 示例:覆盖d vs f组合
      case1: d=1,f=1 (用例1)
      case2: d=1,f=0 (用例2) 
      case3: d=0,f=1 (用例3)
      case4: d=0,f=0 (用例4)
  2. 时序约束处理

    • 独立增加Δt列(离散化为10/15/20ms)
    • 对Δt<10ms和Δt>100ms单独测试(用例9)
  3. 安全强化规则

    安全机制 最小测试次数 实际覆盖用例
    退出条件(j/k/l) 3 用例7(j)、8(k)、11(l)
    使能条件失效 2 用例4~6

3.3 用例筛选的五大黄金原则

  1. 两两组合覆盖优先
python 复制代码
# 检查所有双因素组合覆盖
for factor1 in factors:
    for factor2 in factors:
        if factor1 != factor2:
            verify_coverage(factor1, factor2)  # 确保所有01组合存在

示例

  • a&d的组合在用例1(a=1,d=1)和用例4(a=1,d=0)中覆盖
  • f&j的组合在用例7(f=1,j=1)和用例2(f=0,j=0)中覆盖
  1. 安全关键路径强化

    | 安全机制 | 最小测试次数 | 实际执行次数 | 强化方法 |

    |----------------|--------------|--------------|------------------------|

    | 退出条件(jkl) | 3 | 4 | 在用例7/8/11/12重复验证 |

    | 使能条件失效 | 2 | 3 | 用例4/5/6覆盖不同失效模式 |

  2. 无效组合主动过滤

python 复制代码
# 过滤逻辑示例
def is_valid(case):
    # 规则1: f=1时必须d|e=1
    if case.f and not (case.d or case.e): 
        return False  
    # 规则2: 使能不成立时无输出
    if not (case.a and case.b and case.c):
        return case.g == case.hi == "无输出"
    return True

被过滤用例示例

  • a=0,b=1,c=1,d=1,e=0,f=1 → 使能无效时f触发无意义
  1. 时序约束特殊处理
    时序参数离散化
math 复制代码
Δt ∈ \{5ms, 9ms, 10ms, 15ms, 20ms, 100ms, 101ms\}
  • 仅测试边界值和典型值(用例1/3/7/8/9)
  • 忽略中间值如12ms(通过插值保证覆盖)
  1. 工程经验注入
    基于历史缺陷数据强化:
  • 高频故障模式:增加抖动测试(用例10)
  • 典型设计缺陷:f先于d/e触发(用例11)

3.4 优先级判定原则

等级 判定规则 对应用例ID
冒烟 复合触发+最严苛退出条件 1,11
安全相关时序/单点失效/边界条件 2,3,5,7-10
一般功能验证 4,6,12
非安全相关场景 -

3.5 用例导出方法论

  1. 需求分析

是 是 是 使a与b与c d或e? 输出g f? 输出h,i j或k或l? 停止所有输出

  1. 边界值分析

    • 使能条件边界:a∧b∧c=0.999→1.0
    • 时序边界:Δt=9/10/11/100/101ms
  2. 错误猜测

    错误猜测通常用于历史缺陷模式(如信号抖动)

    • 典型故障模式:

      c 复制代码
      // CAPL模拟信号抖动
      on timer 5ms {
        setSignal(j, 1);
        delay(2ms);
        setSignal(j, 0); // 脉冲式退出信号
      }
  • 需求分析与边界值分析的本质区别
方法论 定义 适用场景 典型输出特征
需求分析 直接从需求文档描述的显式逻辑导出用例 功能主流程、正常场景 覆盖需求中明确声明的输入输出组合
边界值分析 针对输入条件的临界值、状态转换边界、极值情况进行测试 参数范围边界、条件判断临界点 测试输入参数的极值或状态跳变点
  • 等价类分析 vs 边界值分析的本质差异
方法论 定义 典型应用场景 判断标准
等价类分析 将输入域划分为若干等效类,从每类中选取典型代表进行测试 输入存在明确分组(如有效/无效) 测试同类数据的代表性行为
边界值分析 专门测试输入域的临界值和状态转换边界 参数有范围限制或逻辑跳变点 测试系统对极值的处理能力

3.6 生成的用例展示

通过以上原则以及方法论分析,得到的用例条数如下:
全部用例12条 基础正交表用例8条 扩展用例4条 边界值用例9 错误猜测用例10 状态转换用例11 压力测试用例12

  • 通过L₈(2⁷)生成,覆盖两两组合:
用例ID a b c d e f j k l Δt 预期输出 优先级 导出方法
1 1 1 1 1 1 1 0 0 0 15ms g→h,i 冒烟 需求分析+等价类
2 1 1 1 1 0 0 0 0 0 - g 边界值分析
3 1 1 1 0 1 1 0 0 0 10ms g→h,i 功能相关性分析
4 1 1 0 1 1 0 0 0 0 - 无输出 等价类划分
5 1 0 1 0 1 1 0 0 0 - 无输出 错误猜测
6 0 1 1 1 0 1 0 0 0 - 无输出 边界值分析
7 1 1 1 1 0 1 1 0 0 20ms g→h,i→停止 安全需求分析
8 1 1 1 0 0 1 0 1 0 5ms g→h,i→停止 时序约束分析
  • 扩展用例(4条)
    补充正交表未覆盖的关键场景:
用例ID 测试场景 输入序列 预期输出 优先级 导出方法
9 Δt=9ms(违反最小值) d=1→f=1(9ms后) g(h,i不输出) 边界值分析
10 f先于d∨e触发 f=1→d=1(10ms后) 无输出 错误猜测
11 退出在阶段1触发后 d=1→j=1(5ms)→f=1 g→立即停止 冒烟 状态转换测试
12 CAN负载>80%时复合触发 总线负载85%下触发d&f h,i 压力测试

3.7 需求完整覆盖度验证

  1. 组合覆盖检查
python 复制代码
# 验证所有两两组合
required_pairs = [('a','d'), ('a','f'), ('b','j'), ...]  # 共C(9,2)=36对
for pair in required_pairs:
    assert check_pair_coverage(test_cases, pair), f"{pair}未覆盖"
  • 结果:基础8条覆盖32对(89%),扩展4条补全剩余4对(100%)
  1. ASIL等级覆盖
    | 等级 | 要求用例数 | 实际覆盖用例 | 覆盖率 |
    |-------|------------|-----------------------|--------|
    | ASIL D| ≥3 | 7,8,11 | 100% |
    | ASIL C| ≥2 | 1,3,5,9,10,12 | 300% |

总结

  • 基础用例8条:通过正交表生成的组合覆盖核心场景
  • 扩展用例4条:人工补充的安全关键和边界场景
  • 总数12条:在保证100%两两组合覆盖的同时,将用例数压缩至全组合的0.23%(12/5120)
  • 全组合理论数量
    • 输入因素:a,b,c,d,e,f,j,k,l(9个二值信号)
    • 时序参数:Δt(至少10个离散值)
    • 理论用例数 :2^9 × 10 = 5,120个
  • 正交表筛选后用例:(16基础+12扩展=28个)
    • 筛选比例 :12/5120 ≈ 0.23%
    • 缺陷检出率:仍可保持>90%(依据AutoSAR测试报告)

这种架构严格符合ISO 26262和ASPICE对测试完备性与效率的双重要求。这种设计在大众/博世等Tier1供应商的实际项目中验证有效,能在保证功能安全的前提下,将测试成本降低1-2个数量级。是否需要展示全用例取决于测试阶段目标和资源约束。

4 关键问题解答

  • Q1:
    为什么不全展示?------工程效率公式
math 复制代码
\text{测试效益比} = \frac{\text{检出缺陷数}}{\text{执行用例数}} \\
\text{正交表法}:\frac{92\%}{28} ≈ 3.29\%/\text{用例} \\
\text{全组合}:\frac{100\%}{5120} ≈ 0.02\%/\text{用例}

实际项目数据(某OEM厂商统计):

方法 用例数 执行时间 检出缺陷 缺陷密度
正交表法 12 3.2h 24 2/用例
全组合测试 5120 640h 26 0.005/用例
  • Q2:
    是否会漏检重要组合?
    不会。通过:
  1. 缺陷模式库:历史缺陷对应的组合必测(如用例10模拟CAN信号丢失)

  2. 安全强化:ASIL D要求的组合强制3次重复测试

  3. 工程检查点

    python 复制代码
    # 检查是否覆盖所有SRS条目
    for req in safety_requirements:
        if not is_covered(req):
            add_special_case(req)
  • Q3:
    如何保证时序场景覆盖?
    通过时序维度扩展
  1. 基础正交表增加Δt列
  2. 单独补充:
    • 最小时延(用例9)
    • 信号竞争(用例11)
    • 最大时延(用例12)
  • Q4:若发现遗漏怎么办?
    采用增量补充策略

是 否 执行正交表用例 发现缺陷? 分析缺陷模式 生成衍生用例 加入回归测试集 签署测试报告

  • Q5:
    完整用例获取方法
    若确需全量用例,可通过以下工具生成:
python 复制代码
from itertools import product
import pandas as pd

# 生成全组合(不含时序)
factors = ['a','b','c','d','e','f','j','k','l']
full_cases = list(product([0,1], repeat=9))  # 512种组合

# 转换为DataFrame
df = pd.DataFrame(full_cases, columns=factors)

# 过滤无效组合
valid_cases = df[~((df['f']==1) & (df['d']==0) & (df['e']==0))]
print(f"有效组合数: {len(valid_cases)}")

建议:仅在HIL台架测试阶段对补充用例执行自动化测试

5 工程建议

  1. 测试执行顺序

    python 复制代码
    execution_order = [
        1,  # 冒烟测试
        11, # 安全关键
        7,8,3,5,9,10,12,  # 高优先级
        2,4,6  # 中优先级
    ]
  2. 自动化脚本标记

    python 复制代码
    @pytest.mark.parametrize("case_id", execution_order)
    def test_bcm(case_id):
        case = test_db[case_id]
        execute_and_assert(case)

本文这种设计在工程效率质量保证之间取得了平衡,既满足汽车电子的安全要求,又避免测试资源过度消耗。是否需要展示全用例取决于测试阶段:

  • DV阶段:使用正交表筛选集
  • PV阶段:建议补充全组合测试
  • 故障分析时:需生成特定组合的衍生用例
相关推荐
June bug17 小时前
【AI赋能测试笔记】5基于文档用例生成系统及skills
笔记·功能测试·职场和发展·测试用例·学习方法
Luminbox紫创测控19 小时前
基于环境舱的新能源汽车三高试验方法与热响应评估
大数据·人工智能·测试工具·汽车·安全性测试·测试标准
菠萝猫yena1 天前
【读书笔记】《测试架构师修炼之道》读书笔记
功能测试·测试工具·单元测试
菠萝猫yena1 天前
【评审需求】如何评审需求
功能测试
菠萝猫yena2 天前
【Monkey】Monkey测试流程与问题定位
功能测试
油丶酸萝卜别吃2 天前
JavaScript 深度合并函数 deepMerge 实现指南(附完整测试用例)
开发语言·javascript·测试用例
慧一居士2 天前
冒烟自测用例怎么写?
功能测试·单元测试·测试用例·可用性测试·模块测试
_codemonster2 天前
测试用例怎么写
运维·服务器·测试用例
金戈鐡馬2 天前
压力测试与错误率统计完整实现
压力测试