51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 17096|回复: 22
打印 上一主题 下一主题

[讨论] 也是一道面试题:C/C++ 单元测试用例的设计

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2004-7-1 15:38:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家知道printf这个函数吧。

问题就是如何测试这个函数。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏

该用户从未签到

2#
发表于 2004-7-18 19:19:01 | 只看该作者
我也想知道,我最近一直在想如何测试一个没有返回值的函数,如:

public void  foo(){
System.out.println("This is foo method");
}
回复 支持 反对

使用道具 举报

该用户从未签到

3#
发表于 2004-7-18 22:09:19 | 只看该作者
现把你的printf的函数源码给出来,否则如何做单元测试?单元测试如果没有代码,测试是很难保证全面的。
回复 支持 反对

使用道具 举报

该用户从未签到

4#
发表于 2004-7-19 05:49:03 | 只看该作者
站长帮我吧,我想测一个返回值是void的函数,因为没有期望值可以做比较,所以无法预知里面的代码运行时有没有bug,能不能教我一种方法怎么去测试这种函数。
回复 支持 反对

使用道具 举报

该用户从未签到

5#
发表于 2004-7-19 05:59:08 | 只看该作者
给个具体的例子吧,要测试下面一个函数,该怎么测试:

//用户的一个帐户将要透支,就从该用户的其它帐户把不够的钱转移到这个帐户里
public void performOverdraftProtection(Account account,  float withdrawalAmount)  throws InsufficientBalanceException {
        float transferAmountNeeded
            = withdrawalAmount - account.getAvailableBalance();
        Customer customer = account.getCustomer();
        Collection overdraftAccounts
            = customer.getOverdraftAccounts();
        for (Iterator iter = overdraftAccounts.iterator();
             iter.hasNext(); ) {
            Account overdraftAccount = (Account)iter.next();
            if (overdraftAccount == account) {
                continue;
            }
            if (transferAmountNeeded <
                overdraftAccount.getAvailableBalance()) {
                overdraftAccount.debit(transferAmountNeeded);
                account.credit(transferAmountNeeded);
                return;
            }
        }
        throw new InsufficientBalanceException(
                               "Insufficient funds in overdraft accounts");
    }

[ Last edited by lhtia on 2004-7-19 at 06:00 ]
回复 支持 反对

使用道具 举报

该用户从未签到

6#
发表于 2004-7-19 13:40:08 | 只看该作者
这个函数本身就存在问题。
1、没有对函数的参数float withdrawalAmount参数合法性检查,如果参数非法,函数应该返回某个特定的返回值
2、float transferAmountNeeded
            = withdrawalAmount - account.getAvailableBalance();
上面的代码中,没有对transferAmountNeeded的合法性检查,如果得到的是负数,该函数应该返回某个特定的返回值
3、 if (transferAmountNeeded <
                overdraftAccount.getAvailableBalance()) {
                overdraftAccount.debit(transferAmountNeeded);
                account.credit(transferAmountNeeded);
                return;
            }
按照编程规范,if与else必须要配套使用,在if和else中必然会有返回值

如果上述三个地方做了正确的处理,该函数应该是有返回值的。
回复 支持 反对

使用道具 举报

该用户从未签到

7#
发表于 2004-7-19 20:04:19 | 只看该作者
谢谢站长详细的解答,太感谢了。

这个函数本身是存在一些问题,不过,这个函数是没有返回值的,它的功能在于,如果能找到这么一个帐户能把钱转移到将要透支的那个帐户里,那么就实现:
                overdraftAccount.debit(transferAmountNeeded);
                account.credit(transferAmountNeeded);
如果找不到这么一个帐户,就意味着将要透支的那个帐户就不能取那些钱了,这时就:throw new InsufficientBalanceException(
                               "Insufficient funds in overdraft accounts");

所以这个单元功能实现在于改变全局变量,或抛出一个Exception。现在我的问题是,如何把这两种可能与期望值对照起来,告诉测试员是不是一致,有没有bug。

如果函数有返回值的话,那就好办了,直接在测试驱动里调用这个函数,把结果与期望值比较就可以了。但是要测试void函数,该怎么去确定期望值呢,如上述的,如果抛出了Exception,那测试驱动里如何编代码去确定这个期望值,又如何比较呢。。。

我写的有点多了,不知道有没有解释明白。
回复 支持 反对

使用道具 举报

该用户从未签到

8#
发表于 2004-7-19 22:26:39 | 只看该作者
看来只能通过添加测试代码的方式了。
可以定义一个全局变量 int g_iExceptionFlag = TRUE;
然后在 InsufficientBalanceException("Insufficient funds in overdraft accounts");的处理中,增加代码g_iExceptionFlag = FALSE;然后,通过判断g_iExceptionFlag 如果等于TRUE,那么就测试通过,如果等于FALSE则测试不通过。

不知是否合适,仅供参考。
回复 支持 反对

使用道具 举报

该用户从未签到

9#
发表于 2004-7-20 05:12:40 | 只看该作者
多谢站长了,看样子有时候还是不得不添加一些代码来帮助测试。
回复 支持 反对

使用道具 举报

该用户从未签到

10#
发表于 2004-7-20 09:56:18 | 只看该作者
测试过程中,添加测试代码是很常见的事情,不过要注意添加的测试代码要可控,否则会影响测试效果。
回复 支持 反对

使用道具 举报

该用户从未签到

11#
发表于 2004-7-30 08:36:13 | 只看该作者
1、如果transferAmountNeeded算出来为负数, 那么overdraftAccount.debit(transferAmountNeeded);时, 会不会把当前帐户的钱转移到其他的帐户?
2、如果一个帐户要透支50元, 而其他的6个帐号每个只有10元, 那么钱就没有办法透支了?--》是否跟需求相符合呢?
3、overdraftAccount.debit(transferAmountNeeded);
     account.credit(transferAmountNeeded);
     如果第一句执行通过,而第二句执行错误的时候,会不会一个帐号的钱被靠除,而被透支帐号的钱又没有加入呢?--》不知事务处理是怎么处理的?
4、输入的帐号不存在呢?
5、可以用winrunner自动化的测试工具, 通过数据库的对比来验证代码的执行是否正常?
回复 支持 反对

使用道具 举报

该用户从未签到

12#
发表于 2004-8-5 17:34:17 | 只看该作者
你首先要求面试官:请给出printf函数的详细设计文档,否则我没法设计用例。就这么简单。
回复 支持 反对

使用道具 举报

该用户从未签到

13#
发表于 2004-8-5 22:26:44 | 只看该作者
呵呵,这个回答够狠。
我会先问面试官是做黑盒还是白盒。:)
回复 支持 反对

使用道具 举报

该用户从未签到

14#
发表于 2004-12-3 11:46:37 | 只看该作者

To:lhtia

除非是特别小的功能,可以返回Viod。只要是稍有规模的代码都应该有执行状态的标志,看看微软MFC的设计就很清楚了。这是设计和开发人员的问题了,呵呵。

如果是通过异常处理来表示程序的执行状态,你可以适度的扩大测试范围,把异常处理作为一种输出与Void函数合并成一个黑盒子,我觉得会很有效。
回复 支持 反对

使用道具 举报

该用户从未签到

15#
发表于 2005-10-19 10:35:24 | 只看该作者

To lhtia

呵呵,好像晚了点,不过希望能对其他人有帮助,我正好做过类似的junit测试,
抛开这个方法存在的问题,
首先要先设定一个用户,写多个测试方法使他的账户里存在不同的情况,
1.如果是正常系的测试,就要调用完这个方法后,比较这个用户账户里剩下的钱数,是不是等于原钱数-透支钱数,这个就不用写了吧?
2.这个如果是异常系的测试,可以捕获异常,得到抛出的异常字符串来比较,具体如下:
public void testMethod{
  //此处声明测试类的对象  eg;   
   try{
         eg.performOverdraftProtection(Account account,  float withdrawalAmount);
         fail();
        }catch(Exceptinon ex){
        String str = ex.getMessage();
        assertEquals("Insufficient funds in overdraft accounts",str);
       }
}
回复 支持 反对

使用道具 举报

该用户从未签到

16#
发表于 2006-2-19 22:23:38 | 只看该作者
只有看的份
回复 支持 反对

使用道具 举报

该用户从未签到

17#
发表于 2006-2-22 21:52:42 | 只看该作者
受益非浅啊:)
回复 支持 反对

使用道具 举报

该用户从未签到

18#
发表于 2006-2-27 17:43:40 | 只看该作者
是不是疯了,测试Printf函数就那么简单的么,起码测试几千个用例,我同事侧过的,光这个就测了一周多,这面试题出的够绝的
回复 支持 反对

使用道具 举报

该用户从未签到

19#
发表于 2006-3-8 09:11:40 | 只看该作者
呵呵,有点意思,学习学习。

面试官要真考我这个,我可答不上来
回复 支持 反对

使用道具 举报

该用户从未签到

20#
发表于 2006-9-3 14:00:21 | 只看该作者
看看
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-4-28 08:29 , Processed in 0.077605 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表