Skip to content

Latest commit

 

History

History
173 lines (115 loc) · 11.2 KB

2_6_白盒测试技术详解.md

File metadata and controls

173 lines (115 loc) · 11.2 KB

§ 2.6 - 白盒测试技术详解

一、概念

白盒测试 (亦称程序员测试、结构测试、逻辑驱动测试):指的是需要完全了解软件的结构与处理过程,按照软件的内部逻辑来测试软件,以检验软件中的每条路径能否按照规格说明文档中的规定或要求正常执行的一种测试技术。

白盒测试是针对被测试软件的 “内部工作方式” 来开展测试工作的,测试工程师根据软件的内部结构设计测试用例。白盒测试着重于检查软件的内部结构、逻辑、循环路径中存在的错误与缺陷。

白盒测试技术分类

注:白盒测试技术中的 “边界值测试” 一般用于检查程序代码中的数组是否越界、变量是否溢出等错误。

二、逻辑驱动覆盖测试

逻辑驱动覆盖主要分为以下几种(按强弱顺序排行):

  1. 条件组合覆盖(最强)
  2. 判定 - 条件覆盖
  3. 条件覆盖
  4. 判定覆盖
  5. 语句覆盖(最弱)

示例

/*
    程序功能:学习白盒测试技术中的逻辑驱动覆盖测试方法。
    作者:Ling Gao
    日期:2020 年 4 月 15 日
    学校:湖南理工学院
    院系:信息科学与工程学院
*/
#include <iostream>

int main(int argc, char *argv[])
{
    float a;
    float b;
    float x;
	
    std::cin >> a >> b >> x;
    if (a > 1 && b == 0)
        x /= a;
    if (a == 2 || x > 1)
        x += 1;
    std::cout << x << std::endl;
	
    return 0;
}

注:这是一段用来演示 “逻辑驱动覆盖测试” 方法的代码,并没有实际的功能。

为了更加直观的开展软件测试工作,可以先将程序代码转换为流程图形式

1️⃣ 语句覆盖(最弱)

语句覆盖测试:指的是制定足够多的软件测试用例,使得软件中的每一个代码语句至少都能被执行一次的软件测试方法。这是一种效果较差的逻辑驱动覆盖测试方法。

以上述的代码块为例,当使用测试输入数据为 “a = 2,b = 0,x = 4” 作为测试用例时,程序中的所有语句恰好都可以被执行一次,软件的预期输出为 “x = 3”。在流程图中,本次测试工作的程序执行路径如下图的红色线条所示:

可以看到,语句覆盖测试虽然可以覆盖软件中的所有代码语句,但是无法覆盖到所有的代码分支,图中蓝色线条分支是未被测试到的。此时,如果软件代码中存在 “误将 AND 条件写为了 OR”“误将 x > 1 写为了 x >= 1” 一类的分支语句错误的话,是无法被语句覆盖测试所发现的。这也是认为 “语句覆盖测试是一种效果较差的测试方法” 的原因之一。

2️⃣ 判定覆盖(较弱)

判定覆盖测试:指的是制定足够多的软件测试用例,使得软件中的每一个分支至少都能被执行一次的软件测试方法。这是一种比 “语句覆盖测试” 效果稍强一些的逻辑驱动覆盖测试方法。

以上述的代码块为例,当使用下面的一组输入数据来编写软件测试用例时,程序中的所有分支恰好都可以被执行一次:

输入数据 预期结果
测试用例 1:a = 3,b = 0,x = 1 输出:x = 0.33
测试用例 2:a = 3,b = 2,x = 0 输出:x = 1

测试用例 1 的程序执行路径如下图的红色线条所示;测试用例 2 的程序执行路径如下图的蓝色线条所示:

判定覆盖测试的覆盖率虽然高于语句覆盖测试,但是仍然不是非常充分。例如,下方绿色线条所表示的程序执行路径,在刚刚编写的 “判定覆盖” 测试用例中是未能被测试到的:

3️⃣ 条件覆盖(中等)

条件覆盖测试:指的是制定足够多的软件测试用例,使得软件中的每一个判定条件都获得各种可能的取值的软件测试方法。这是一种效果更强一些的逻辑驱动覆盖测试方法。

以上述的代码块为例,程序中的两个判定条件有如下的几种取值范围

取值范围

当使用下面的一组输入数据来编写软件测试用例时,程序中每一个判定条件恰好都可以获得所有可能的取值

输入数据 预期结果
测试用例 1:a = 2,b = 1,x = 4 输出:x = 5
测试用例 2:a = -1,b = 0,x = 1 输出:x = 1

测试用例 1 的程序执行路径如下图的红色线条所示;测试用例 2 的程序执行路径如下图的蓝色线条所示:

可以看到,条件覆盖测试虽然可以覆盖软件中判断条件所有可能的取值范围,但是依旧无法覆盖所有的程序执行路径。条件覆盖测试也是一种并不非常充分的逻辑驱动覆盖测试方法。

4️⃣ 判定 - 条件覆盖(较强)

判定 - 条件覆盖:顾名思义,指的是综合判定覆盖与条件覆盖,制定足够多的软件测试用例,使得软件判定中的每一个条件都获得各种可能的取值,同时使得软件中的每一个分支至少都能被执行一次的软件测试方法。

以上述的代码块为例,当使用下面的一组输入数据来编写软件测试用例时,可以同时符合判定覆盖条件覆盖

输入数据 预期结果
测试用例 1:a = 2,b = 0,x = 4 输出:x = 3
测试用例 2:a = 1,b = 1,x = 1 输出:x = 1

测试用例 1 的程序执行路径如下图的红色线条所示;测试用例 2 的程序执行路径如下图的蓝色线条所示:

判定 - 条件覆盖测试的覆盖率虽然更高,但是依旧不充分。例如,下方绿色线条所表示的程序执行路径,在刚刚编写的 “判定 - 条件覆盖” 测试用例中是未能被测试到的:

5️⃣ 条件组合覆盖(最强)

条件组合覆盖:指的是制定足够多的软件测试用例,使得软件中的所有条件的各种组合都能被至少执行一次的软件测试方法。这是效果最强仍不完美的逻辑驱动覆盖测试方法。

以上述的代码块为例,可以将程序中的每个判定条件都进行拆分,绘制为下方新的流程图:

软件测试工程师可以制定足够多的软件测试用例,使得软件中的所有条件的各种组合都能被至少执行一次(此处不再展示测试用例)。对比上述其他四种逻辑驱动覆盖测试方法的特点,可以发现:条件组合覆盖也是不完美的。但是,条件组合覆盖测试方法足以应对绝大多数的情况,没有必要再设计更加详细的逻辑驱动覆盖测试方法,到此为止即可。

在实际的软件测试工作中,通常不必直接使用条件组合覆盖测试方法,因为会大幅度的增加测试工程师的工作量。一般情况下,大多数的软件测试工作只需使用语句覆盖判定覆盖这两种逻辑驱动覆盖测试方法。

三、测试题

针对以下程序段,对于变量 c 的取值,至少需要制定 ( 3 ) 个测试用例才能够满足语句覆盖要求。

c = ((u8_t *) q -> payload) [i];
switch (c)
{
    case SLIP_END:
    {
        sio_send(SLIP_ESC, netif -> state);
        sio_send(SLIP_ESC_END, netif -> state);
        break;
    }
    case SLIP_ESC:
    {
        sio_send(SLIP_ESC, netif -> state);
        sio_send(SLIP_ESC_ESC, netif -> state);
        break;
    }
    default:
    {
        sio_send(c, netif -> state);
        break;
    }
}

注:本题选取自中国计算机技术与软件专业技术资格(水平)考试中的 “软件评测师” 考试部分。


回到顶部

下一章节:§ 2.7 - 软件缺陷详解

回到主页