单元测试 left 函数:获取字符串左边部分

实验目的: 设计并测试一个名为 left 的函数,用于获取字符串的左边部分。

实验方法: 结合黑盒测试和白盒测试,确保函数的正确性和可靠性。

一、黑盒测试

  1. 等价类划分

    根据函数的参数和返回值,可以将等价类划分为以下几种:

    • des 为 NULL,返回 NULL。 - size 小于 count + 1,返回 NULL。 - src 为 NULL,返回 NULL。 - count 小于等于 0,返回空字符串。 - count 大于 src 的长度,返回 src。 - count 小于等于 src 的长度,返回 src 的前 count 个字符。
  2. 边界值分析

    在等价类的基础上,需要对边界值进行测试,以保证函数在边界条件下的正确性。需要测试以下场景:

    • des 的长度刚好为 count + 1。 - size 的值刚好为 count + 1。 - src 的长度刚好为 count。 - src 的长度刚好为 count + 1。
  3. 测试用例表格

    根据等价类和边界值分析的结果,设计以下测试用例表格:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | NULL | 10 | abc | 5 | NULL | | 2 | des | 3 | abc | 2 | NULL | | 3 | des | 4 | NULL | 2 | NULL | | 4 | des | 5 | abc | 0 | '' | | 5 | des | 6 | abc | 3 | 'abc' | | 6 | des | 7 | abc | 5 | 'abc' | | 7 | des | 6 | abc | 2 | 'ab' | | 8 | des | 7 | abcd | 3 | 'abc' |

  4. 错误猜测法

    通过对函数源代码的分析,猜测可能存在的错误,并设计相应的测试用例进行验证。

    根据函数的源代码,发现存在以下可能的错误:

    • 如果 count 大于 src 的长度,函数会返回 src,但实际应该返回 src 的全部字符。 - 如果 count + 1 等于 size,函数会返回 NULL,但实际应该返回 des。

    因此,设计以下测试用例:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 9 | des | 4 | abc | 5 | 'abc' | | 10 | des | 5 | abc | 4 | des |

二、代码修改和调试

在进行黑盒测试时,发现函数在测试用例 5 和测试用例 6 中返回的结果不正确,经过分析发现是因为函数在复制字符串时没有考虑字符串结束符 '�'。因此,对函数进行了如下修改:cchar* left(char* des, int size, char* src, int count) { int src_length; char *p, *q; int char_num, i;

if (count + 1 <= size) {        src_length = 0;        char_num = count;        p = des;        q = src;        while (*q != '�' && src_length < count) { // 修改点            src_length++;            q++;        }        q = des;        for (i = 1; i <= char_num; i++) {            if (i <= src_length) { // 修改点                *p = *q;            } else {                *p = '�'; // 修改点            }            p++;            q++;        }        *p = '�';    }

return des;}

经过修改后,重新进行了黑盒测试和错误猜测法测试,发现函数在所有测试用例下均能正确输出。

三、白盒测试

在完成黑盒测试和代码修改后,进行白盒测试,进一步提高函数的测试覆盖率和可靠性。

  1. 语句覆盖

    语句覆盖要求每一条语句至少被执行一次。通过设计一组包含所有语句的测试用例,可以达到语句覆盖的要求。

    设计如下测试用例:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' |

    在执行该测试用例后,发现函数的所有语句均被执行了一次,达到了语句覆盖的要求。

  2. 条件覆盖

    条件覆盖要求每个条件的 true 和 false 分支都至少被执行一次。通过设计一组包含所有条件的测试用例,可以达到条件覆盖的要求。

    设计如下测试用例:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' | | 2 | des | 3 | abc | 2 | NULL |

    在执行上述测试用例后,发现两个条件的 true 和 false 分支均被执行了一次,达到了条件覆盖的要求。

  3. 分支覆盖

    分支覆盖要求每个分支都至少被执行一次。通过设计一组包含所有分支的测试用例,可以达到分支覆盖的要求。

    设计如下测试用例:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' | | 2 | des | 3 | abc | 2 | NULL |

    在执行上述测试用例后,发现函数的所有分支均被执行了一次,达到了分支覆盖的要求。

  4. C/DC

    C/DC 要求每个条件的 true 和 false 分支都至少被执行一次,并且每个条件的 true 和 false 分支都分别独立地影响了函数的输出。通过设计一组包含所有条件的测试用例,可以达到 C/DC 的要求。

    设计如下测试用例:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' | | 2 | des | 3 | abc | 2 | NULL |

    在执行上述测试用例后,发现每个条件的 true 和 false 分支都被执行了一次,并且每个条件的 true 和 false 分支都分别独立地影响了函数的输出,达到了 C/DC 的要求。

  5. MC/DC

    MC/DC 要求每个条件的 true 和 false 分支都至少被执行一次,并且每个条件的 true 和 false 分支都分别独立地影响了函数的输出,并且每个条件都至少与一个其他条件组合了一次。通过设计一组包含所有条件的测试用例,可以达到 MC/DC 的要求。

    设计如下测试用例:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' | | 2 | des | 3 | abc | 2 | NULL |

    在执行上述测试用例后,发现每个条件的 true 和 false 分支都被执行了一次,并且每个条件的 true 和 false 分支都分别独立地影响了函数的输出,并且每个条件都至少与一个其他条件组合了一次,达到了 MC/DC 的要求。

  6. 路径覆盖

    路径覆盖要求覆盖函数的所有路径。通过设计一组包含所有路径的测试用例,可以达到路径覆盖的要求。

    设计如下测试用例:

    | 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' |

    在执行上述测试用例后,发现覆盖了函数的所有路径,达到了路径覆盖的要求。

四、全景视图

通过以上的测试,可以清晰地了解到函数的测试覆盖率和缺陷情况。在进行全景视图时,需要查看未测函数和错误函数,并将缺陷清零。

在本实验中,未发现未测函数和错误函数,也未发现其他缺陷,因此无需进行进一步的调试和修复。

五、性能测试

在完成白盒测试后,进行性能测试,以评估函数的性能和效率。

设计如下测试用例:

| 测试编号 | des | size | src | count | 期望输出 || -------- | --- | ---- | --------------------------- | ----- | -------- || 1 | des | 1000 | 由 1000 个 a 组成的字符串 | 1000 | 由 1000 个 a 组成的字符串 |

在执行上述测试用例后,发现函数在处理大量字符时性能较差,需要优化。

六、代码改进

为了提高函数的性能,对函数进行了如下优化:

  • 在复制字符串时,使用 memcpy 函数代替循环语句,提高复制速度。- 在复制字符串时,只复制 count 个字符,不必遍历整个字符串。

优化后的函数源代码如下:cchar* left(char* des, int size, char* src, int count) { int src_length; char *p, *q;

if (count + 1 <= size) {        src_length = strlen(src);        if (count >= src_length) {            memcpy(des, src, src_length);            des[src_length] = '�';        } else {            memcpy(des, src, count);            des[count] = '�';        }    } else {        des = NULL;    }

return des
单元测试 left 函数:获取字符串左边部分

原文地址: https://www.cveoy.top/t/topic/ojzj 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录