maconel 发表于 2008-12-8 16:10:35

异步函数如何进行单元测试

最近准备开始在团队内开展单元测试,但有些问题一直困扰着我。

一般的单元测试教程,都喜欢用add这样的函数来做例子,可实际工作中,大部分函数都不是这么简单的。
例如这样一个函数A,他将一个数据加入队列,然后就返回,一个专门的线程将队列中的数据一一处理,同通过回调通知。那么这个函数A需要被测试吗,该如何测试呢,只检验是否放入队列就可以了吗,这样一个异步处理的流程,有什么好的方法对其进行测试呢。这样的例子有很多,比如发送网络数据,也是类似情况。

请教诸位,这种情况该怎么办。

lanbiers 发表于 2008-12-8 18:03:49

我觉得函数A也该进行测试,因为也存在着测试点,比如加入队列是否成功? 如果发送网络数据,那么连接是否有异常等?
一般来说对这样有可能产生异常的点都要进行单元测试~

当然,这样的测试也可以和回调函数一起测试,所以拆开测或一起测,取决于你的设计是耦合还是松散的~

VisualUnit 发表于 2008-12-8 18:38:57

我在我们公司的技术支持记录中看到过这个问题,可能就是楼主吧?当时技术支持没有回答,说要想一下。
举个例子:
int A(arg)
{
    AddToList(arg); //将数据加入队列
    return 0;
}
//这个函数只是加入队列,如果中间没有什么计算,则没必要测试,如果有计算,并有条件判断,可以进行“控制测试”,即判断在某种状态下是否做了某种动作,例如,只有在某个条件成立时才加入队列,实际上就是判断在某种状态下是否调用了某个子函数,VU2有这种功能,要自动判断调用次数也可以。

//处理对列的函数
void DoList()
{
}
这个是业务核心,测试时其实根本就不同管它是不是异步的,只需要测试队列在各种状态下(空、一个数据、多个数据、满)它否做了正常的处理就可以了。测试时直接设定队列中的数据,不需要由A函数设定。

//回调通知
接收通知的函数如果要做比较复杂的计算,当然也要测试。同样,不必考虑是否异步,只要将通知视为一般输入就可以了。

也就是说,完全可以将各个函数视为独立的单元,只要测各自的功能就行了,由谁调用、什么时候调用,都可以看作是集成,单元测试是可以不考虑的,留待系统测试时再做就是了。

上面说的是比较简单的情形。如果A是这样,就复杂一些:
int A(arg)
{
    AddToList(arg); //将数据加入队列
    //
   WaitFor.....(阻塞,等待另一个线程完成计算,再继续)

   //然后从队列中取得经过计算的数据作处理
    XXXXXX
}

这种情形,我建议简化处理,把XXXXX处的大量代码移到一个独立的函数中进行测试,A就不用测试了。如果一定要测试A,也可以做到,例如用VU2,可以这样:
AddToList和WaitFor都使用底层模拟,不要实际执行,队列的数据在用例的输入部分直接设定,然后就可以像普通函数一样测试了。

楼主也可以做一个DEMO工程,我来测试看看。

maconel 发表于 2008-12-8 18:50:01

谢谢VisualUnit的回答,我了解了。
你们公司的记录,也是我问的。

muerte 发表于 2008-12-12 16:43:15

原帖由 VisualUnit 于 2008-12-8 18:38 发表 http://bbs.51testing.com/images/common/back.gif
我在我们公司的技术支持记录中看到过这个问题,可能就是楼主吧?当时技术支持没有回答,说要想一下。
举个例子:
int A(arg)
{
    AddToList(arg); //将数据加入队列
    return 0;
}
//这个函数只是加入队列 ...


不错,单元测试,其实不用考虑的太多函数,如果考虑太多,影响测试
单元测试,基本上做到这样5件事情:
**** 入口函数的测试
**** 出错处理
**** 局部数据结构测试
**** 独立路径测试
**** 边界条件测试

love00wanggang 发表于 2008-12-31 18:10:55

int A(arg)
{
    AddToList(arg); //将数据加入队列
    return 0;
}

对这个简单的函数需不需要测试,要看实际情况而定,如果进行测试的话,在before_test A前把当前队列里的东西全记下来,添加完了后,再对队列进行检查,检查加入的值是不是有缺损,或者不正确,等等

muerte 发表于 2009-1-6 09:55:20

原帖由 love00wanggang 于 2008-12-31 18:10 发表 http://bbs.51testing.com/images/common/back.gif
int A(arg)
{
    AddToList(arg); //将数据加入队列
    return 0;
}

对这个简单的函数需不需要测试,要看实际情况而定,如果进行测试的话,在before_test A前把当前队列里的东西全记下来,添加完了后,再对 ...
如果以这个函数为例子,重点要是AddToList(arg); 这个函数,不可能把所有的东西都测试到,
页: [1]
查看完整版本: 异步函数如何进行单元测试