第1页

Test Oracle(测试预言)


第2页

自动驾驶汽车——如何测试?

测试问题: 相同输入,结果可能不同,很难构造测试预言。

  • 汽车因雨中行驶以及太阳方位问题,无法识别路标甚至行人;
  • 摄像头在灰暗天空下无法识别白色汽车;
  • 当公交车汇入车流时,系统误判其会停车。

→ 致命碰撞事故

深度神经网络被用于自动驾驶。


第3页

两个基本问题(Two Fundamental Problems)

充分性准则(Adequacy Criteria)
测试预言(Test Oracle)
  ├── 无测试预言(No test oracle)
  └── 无自动化测试预言(No automated test oracle)

第4页

无测试预言(No Test Oracle)

某些类型的应用程序特别难以测试,因为不存在"测试预言":

  • 机器学习、离散事件仿真、优化、科学计算……等

即使没有预言,也可以通过检测软件是否违反某些属性来发现缺陷。


第5页

机器学习与大数据(Machine Learning & Big Data)

(本页为示意图/场景图)


第6页

仿真与医疗健康(Simulation & Health Care)

(本页为示意图/场景图)


第7页

示例1:Sin(x) 函数

测试用例输入预期输出
测试用例130°0.5
测试用例229.999°(难以确定)

第8页

示例2:两节点间最短距离

(图中节点编号1~7)

测试用例输入预期输出
测试用例1上图,节点1 → 节点42
测试用例2上图,图中圈出的两节点(难以确定)

第9页

蜕变测试(Metamorphic Testing)

核心思想:

  • 若新测试用例输出 f(t(x)) 符合预期,不一定代表结果正确;
  • 但若 f(t(x)) 不符合预期,则 f(x)f(t(x)) 中至少有一个是错误的。
原始测试用例:  x  →[f]→ f(x)
                         ↑ 伪预言
转换函数 t
                         ↓ 伪预言
新测试用例:  t(x) →[f]→ f(t(x))

转换函数基于函数 f 的蜕变属性构造。

参考文献:T.Y. Chen, S.C. Cheung, S.M. Yiu,《蜕变测试:一种生成后续测试用例的新方法》,技术报告 HKUST-CS98-01,香港,1998。


第10页

示例1——蜕变测试:Sin(x) 函数

蜕变关系(MR): Sin(x) = Sin(x + 2π)

项目内容
测试用例
原始输入29.999°
新输入29.999° + 2π
验证MR是否成立Sin(29.999°) = Sin(29.999° + 2π)? (待验证)

第11页

示例2——蜕变测试:两节点间最短距离

设函数 ShortestDis(x, y),其中 x 为起始节点,y 为终止节点。

蜕变关系(MR): ShortestDis(x, y) = ShortestDis(y, x)

项目内容
原始输入x1 为起始节点,y1 为终止节点
新输入y1 为起始节点,x1 为终止节点
验证MR是否成立ShortestDis(x1, y1) = ShortestDis(y1, x1)?(待验证)

第12页

随堂测验(Quiz)

请使用蜕变测试,为以下两个示例定义新的蜕变关系(MR):

  • 示例1: Sin(x) 函数
  • 示例2: 两节点间最短距离函数 ShortestDis(x, y),其中 x 为起始节点,y 为终止节点。

第13页

示例3:统计计算程序 CSta

public static void CSta (int[] numbers) {
    int length = numbers.length;
    double var, mean, sum, varsum;
    sum = 0.0;
    for (int i = 0; i < length; i++) {
        sum += numbers[i];
    }
    mean = sum / (double) length;
    varsum = 0.0;
    for (int i = 0; i < length; i++) {
        varsum = varsum + ((numbers[i] - mean) * (numbers[i] - mean));
    }
    var = varsum / (length - 1.0);
 
    System.out.println("length:   " + length);
    System.out.println("mean:     " + mean);
    System.out.println("variance: " + var);
}

该程序计算整数数组的长度、均值和方差


第14页

随堂测验(Quiz)

(与第13页相同的 CSta 代码)

问题:请为该程序设计蜕变关系(MR)?


第15页

蜕变关系(Metamorphic Relation)示例

MR 1:对称输入,均值为零

项目内容
测试输入[a, -a, b, -b]
结论mean = 0

MR 2:所有元素加1,均值也加1

项目内容
测试输入1[a, b, c, d] → 均值为 mean1
测试输入2[a+1, b+1, c+1, d+1] → 均值为 mean2
结论mean2 = mean1 + 1

第16页

无自动化测试预言(No Automated Test Oracle)

某些类型的应用程序特别难以测试,因为不存在自动化的"测试预言":

  • 多媒体应用、人机交互……等

第17页

测试输入 → 测试输出

预期输出:更美观!(more beautiful!)

(本页展示图像处理场景,输入一张图片,期望输出经过处理后更美观的图片,但"更美观"难以自动判断)


第18页

一种解决方案(One Solution)

当不存在自动化预言时,应降低人工检查测试结果的成本


第19页

自动化测试流程

自动化测试数据生成

自动化测试执行

自动化测试输出收集

(人工判断)更美观?

(说明:前三个步骤可自动化,最终的"是否更美观"仍需人工判断,目标是最小化人工介入的成本)


第20页

课后作业:蜕变测试——自动驾驶汽车

两种图像变换方式:

变换类型说明
线性变换调整图像的亮度和对比度
卷积变换对图像进行模糊处理,或添加雨/雾效果

蜕变关系设计(角度变化可适当松弛):

  • MSE_orig:原始图像与原始输出之间的均方误差;
  • λ:可调节的参数;
  • 左侧:经变换后的输出与原始输出之差的平方。

作业要求: 应用蜕变测试对自动驾驶汽车进行测试。


第21页

测试用例集约简(Test Suite Reduction)

(本页为章节标题页)


第22页

测试用例集约简——最小子集

覆盖矩阵(行为需求 r1r6,列为测试用例 t1t5):

测试用例r1r2r3r4r5r6
t1111100
t2001110
t3001101
t4000011
t5110010

所有最小子集(覆盖全部需求的最小测试用例组合):

  • {t1, t2, t3}
  • {t1, t4}
  • {t1, t3, t5}
  • {t2, t4, t5}

第23页

贪心算法用于测试用例集约简(Greedy)

覆盖矩阵同上。

贪心算法执行过程: 每次选择覆盖最多未覆盖需求的测试用例。

步骤选择说明
第1步t1覆盖 r1, r2, r3, r4(共4个)
第2步t2 或 t4继续覆盖剩余需求
第3步

贪心算法结果: {t1, t4}


第24页

附加贪心算法(Additional Greedy)

覆盖矩阵同上。

附加贪心算法执行过程: 每次选择覆盖最多新增未覆盖需求的测试用例(避免重复覆盖)。

步骤选择新增覆盖需求
第1步t1r1, r2, r3, r4
第2步t4r5, r6

附加贪心算法结果: {t1, t4}


第25页

随堂测验:附加贪心算法(Quiz: Additional Greedy)

覆盖矩阵同上。

问题: 若第1步选择失败(Fail),请用附加贪心算法重新执行,给出最终结果。

(提示:尝试从不同的初始测试用例出发,观察结果是否仍为最优子集)


第26页

复杂度分析(Complexity)

测试用例集约简问题 ≈ 最小基数命中集问题(Minimum Cardinality Hitting Set)

两者在计算复杂度上等价,属于 NP 难问题,因此贪心算法是常用的近似求解方法。


第27页

讨论(Discussion)

冗余真的无用吗?(Is redundancy useless?)

(引导思考:测试用例中的冗余是否在某些情况下仍有价值,例如提升故障检测的鲁棒性)


第28页

故障邻近性(Failure Proximity)

流程图:

测试数据 → 转换(Transform)→ 映射函数(Mapping Function)→ 机器学习(Machine Learning)

                                                            聚类采样(Cluster Sampling)

                                                               故障(Faults)

思路:通过将测试数据映射到特征空间,利用聚类分析使相似行为的测试用例聚集,从每个簇中采样,从而减少冗余同时保留故障检测能力。


第29页

软件行为学习(Software Behavior Learning)

整体流程:

软件(Software)

行为特征提取(Behavior Features)

距离计算(Distances)

聚类(Clustering)

采样(Sampling)

测试数据(Test Data)→ 分析(Analysis)

第30页

距离计算(Distance)

覆盖矩阵同前:

测试用例r1r2r3r4r5r6
t1111100
t2001110
t3001101
t4000011
t5110010

示例: t1 与 t2 之间的汉明距离(Hamming Distance)= 4

(两个向量中对应位置不同的元素个数,即 r1、r2、r5、r6 四个位置不同)