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

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阶段:建议补充全组合测试
  • 故障分析时:需生成特定组合的衍生用例
相关推荐
程序员杰哥11 小时前
Postman接口测试: postman设置接口关联,实现参数化
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
A_Tai233333320 小时前
测试用例的设计
测试用例
试着1 天前
【新技术】微软 Azure Test Impact Analyzer (TIA) 全面解析
测试工具·microsoft·azure·测试覆盖率
测试界茜茜1 天前
16:00开始面试,16:08就出来了,问的问题有点变态。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展
程序员小远1 天前
接口测试和单元测试详解
自动化测试·软件测试·python·测试工具·单元测试·测试用例·接口测试
waves浪游1 天前
自动化测试实战篇
测试用例·bug·测试
猿周LV2 天前
JMeter 安装及使用 [软件测试工具]
java·测试工具·jmeter·单元测试·压力测试
浪裡遊3 天前
Linux常用指令
linux·运维·服务器·chrome·功能测试
天才测试猿3 天前
软件测试之功能测试详解
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例