本篇主要介绍下测试时遇到的关于函数返回码的bug。
函数的返回值往往作为操作是否成功的标志,在函数内部,可能出现许多异常场景,针对每种异常场景,需要返回不同的值,以便上层调用函数处理。
被调函数是否能够在不同场景下返回对应的返回码;调用函数能否根据不同返回码正确处理,也是白盒测试时需要重点关注的内容。
下面就以上两个场景分别列举1个测试时发现的问题。
返回码Bug1:
Bug描述: 异常情况下返回了代表正确场景的returncode。
变量ret存储函数返回码,初值为QCONF_OK,代表未发生异常/错误的正确场景。函数内部发生异常时,未给ret变量重新赋值,导致最后返回ret时,值仍然为QCONF_OK。上层调用时会根据被调函数的返回值分别进行处理,这样调用函数处就会全部转到正常逻辑处理分支,即便在出现异常的情况下。出现这个问题,还是不太容易排查。
解决方法
每个异常分支,分别给ret赋予不同的值,方便上层调用处根据ret的值针对性处理。
返回码Bug2:
Bug描述: 调用处对被调函数返回码判断错误,导致分支不可达。
以上代码中获取被调函数的返回值,存储到ret变量中。后面接着判断ret值如果为-1,则重试。这里是想判断被调函数是否处理失败。而反观被调函数会发现,所有分支下,返回值都不会为-1。因此,调用处的语句块永远不会被执行。被调函数所有可能的返回码如下:
出现这个错误的原因在于代码不规范,对于返回码的赋值,有时使用宏,有时直接使用数字,这里想当然的认为被调函数在处理失败时应该返回-1.
解决方法
将判断条件改成if(QCONF_OK != ret)代表被调函数可能出现的所有非正常情况。
总结
针对以上出现的情况,做了一个简单的总结如下:
检查规则
容易出bug的点
建议
确保函数内所有分支下的返回码都正确。
-
正确分支:返回正确的返回码。
-
异常分支:根据不同的异常情况分别返回不同的异常码。
可能函数开头给存储返回码的变量赋了初值。当函数内包含循环,并且循环体内有continue、break,或者嵌套的分支比较多时,可能导致在某些情况下,忘记了对该变量赋值,最后直接返回了该变量。
1、统一的约定:函数内存储返回码的变量初始化时,行为必须一致;(比如:都要求初始化为表示正确值的返回码)
2、对于函数内的每个错误的分支、以及循环break后跳至的点,一直到return处,有对变量赋值。
调用处的处理:
对被调函数返回码进行判断,并根据返回值进行相应的处理。
1、保证被调用函数包含各种错误通路,并返回相应的返回码;
2、返回码统一用宏,不要直接使用数字,宏命名能做到见名知意;
3、调用处分情况对返回码进行判断;
4、对被调用函数进行修改涉及到返回码时,同时对调用处进行修改。
回顾:
Q
转载自 360质量效能