单元测试的自动用例生成方法
自动生成用例是所有测试人员的期盼,好消息是这种技术早就有了,坏消息是完全自动生成的用例作用很小。完全自动生成用例的方法主要有两种:根据输入自动生成、根据路径自动生成。
一.根据输入自动生成
一般是根据参数生成,这是一种简单的技术:任何数据类型都可以分解为基本数据类型,预先为各种基本数据类型设定一些值,组合一下就可以生成了,如函数int func(int arg, const char *argv);,可以按以下方法生成用例集:
1) 定义参数取值:
int类型可以定义一些值,如最小值,最大值,0,1,-1;
char*类型也可以定义一些值,如””, “abcde”。
2) 分析函数原形,生成用例代码模板,如:
CASE_BEGIN()
int arg = @arg@;
constchar *argv = @argv@;
int ret = func(arg, argv);
TEST_ASSERT(ret == @ret@);
CASE_END()
3) 将参数的各种取值循环组合,分别替换模板中的相应内容,即可生成用例集。
这里的关键是输出应该是什么才对?工具是不知道的,一种办法是先随便填一个值,执行后,再填上实际输出的值,然后由用户判断和修改。
二. 根据路径自动生成
这种方法分析代码的执行路径,然后生成可以覆盖这些路径的用例。技术上还不成熟,其中内部输入是一个难点,例如函数:
int WorkTime(int *pWorkTime)
{
int success = 0; //取环境温度是否成功
int temperature; //环境温度
//temperature的值无法在外部设定,这是一种内部输入
success = GetTemperature(&temperature);
if(!success)
return 0;
//计算温度差,mExpectTemperature是成员变量
int TempDiff = temperature - mExpectTemperature;
if(TempDiff <= 0)
return 0;
if(pWorkTime == 0)
return 0;
//为了简化问题,这里假设温差一度,需运行60秒
*pWorkTime = TempDiff * 60;
return 1;
}
当路径依赖于内部输入时,就很难弄了,不幸的是,这种情形是很普遍的。