单元测试 left 函数:获取字符串左边部分
单元测试 left 函数:获取字符串左边部分
实验目的: 设计并测试一个名为 left 的函数,用于获取字符串的左边部分。
实验方法: 结合黑盒测试和白盒测试,确保函数的正确性和可靠性。
一、黑盒测试
-
等价类划分
根据函数的参数和返回值,可以将等价类划分为以下几种:
- des 为 NULL,返回 NULL。 - size 小于 count + 1,返回 NULL。 - src 为 NULL,返回 NULL。 - count 小于等于 0,返回空字符串。 - count 大于 src 的长度,返回 src。 - count 小于等于 src 的长度,返回 src 的前 count 个字符。
-
边界值分析
在等价类的基础上,需要对边界值进行测试,以保证函数在边界条件下的正确性。需要测试以下场景:
- des 的长度刚好为 count + 1。 - size 的值刚好为 count + 1。 - src 的长度刚好为 count。 - src 的长度刚好为 count + 1。
-
测试用例表格
根据等价类和边界值分析的结果,设计以下测试用例表格:
| 测试编号 | 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' |
-
错误猜测法
通过对函数源代码的分析,猜测可能存在的错误,并设计相应的测试用例进行验证。
根据函数的源代码,发现存在以下可能的错误:
- 如果 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;}
经过修改后,重新进行了黑盒测试和错误猜测法测试,发现函数在所有测试用例下均能正确输出。
三、白盒测试
在完成黑盒测试和代码修改后,进行白盒测试,进一步提高函数的测试覆盖率和可靠性。
-
语句覆盖
语句覆盖要求每一条语句至少被执行一次。通过设计一组包含所有语句的测试用例,可以达到语句覆盖的要求。
设计如下测试用例:
| 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' |
在执行该测试用例后,发现函数的所有语句均被执行了一次,达到了语句覆盖的要求。
-
条件覆盖
条件覆盖要求每个条件的 true 和 false 分支都至少被执行一次。通过设计一组包含所有条件的测试用例,可以达到条件覆盖的要求。
设计如下测试用例:
| 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' | | 2 | des | 3 | abc | 2 | NULL |
在执行上述测试用例后,发现两个条件的 true 和 false 分支均被执行了一次,达到了条件覆盖的要求。
-
分支覆盖
分支覆盖要求每个分支都至少被执行一次。通过设计一组包含所有分支的测试用例,可以达到分支覆盖的要求。
设计如下测试用例:
| 测试编号 | des | size | src | count | 期望输出 | | -------- | --- | ---- | ----- | ----- | -------- | | 1 | des | 5 | abc | 3 | 'abc' | | 2 | des | 3 | abc | 2 | NULL |
在执行上述测试用例后,发现函数的所有分支均被执行了一次,达到了分支覆盖的要求。
-
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 的要求。
-
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 的要求。
-
路径覆盖
路径覆盖要求覆盖函数的所有路径。通过设计一组包含所有路径的测试用例,可以达到路径覆盖的要求。
设计如下测试用例:
| 测试编号 | 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
原文地址: https://www.cveoy.top/t/topic/ojzj 著作权归作者所有。请勿转载和采集!