`
taowen
  • 浏览: 192204 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

测试写到什么程度算足够?

阅读更多
100%的测试覆盖率
这是一个很显而易见的答案。但是我不认为这是正确的答案。下面是一个小例子:
private int[] map = new int[] {
  1, 3, 5, 8};
public int oddNumber(int index) {
  return map[index - 1];
}

写一个简单的测试
@Test
public void first_odd_number_should_be_one() {
  assertEquals(1, oddNumber(1));
}

这个测试是不是覆盖了100%的代码呢?我认为是覆盖了的。但是是不是真的测试了所有的执行路径呢?显然没有。oddNumber(4)应该是7,但是这个程序会返回8。我们改一个写法:
public int oddNumber(int index) {
  switch(index) {
    case 1: return 1;
    case 2:return 3;
    case 3: return 5;
    case 4: return 8;
  }
  throw new UnsupportedOperationException();
}

换了一种写法之后,测试覆盖率立马就下去了。差别就在于,在第二种写法把执行路径对应到了字面的静态路径上了。所以说,测试应该覆盖是否完全的标准,应该是以动态路径为准,而不是以静态路径为准。同时,也提醒我们,想要靠最后根据测试覆盖率来补测试,是不能让你做到TDD时同等程度的自信的。
在TWU上学的时候,老师给了一个简单的准则:
代码增一行太多,减一行太少
当然,老师是用英文教课的,我是把意思用中文翻译了一下。这句话是说,代码不能多不能少,以恰好让所有测试通过为最佳。为了验证这个道理,据老师说,ThoughtWorks UK有一个开发人员写了一个工具用来“删代码”。如果有一行代码是能够删掉之后还能让所有测试都通过的,那么就删掉它。我觉得,这个准则很有务实,也很有用。同时,也回答了另外一个问题,是不是要给所有的类写对应的测试类来覆盖其所有的行为?我认为没有根据这个准则,答案应该是没有必要。只要你的测试覆盖了这个类的所有执行路径就可以了。至于这个测试是不是针对这个类独立进行测试的,是单元测试还是功能测试,是黑盒测试还是白盒测试,都不重要。重要的是,你删掉这个类中一行或者几行,都会让所有测试中至少一个测试失败。这就能说明,你的测试是写到位了。
当然,再加一些怀疑和批评的态度。对于上面那个放之四海皆准的准则,有一个例外:那就是这个准则只关心程序的正确性,但是我要说程序的行为是由正确性和效率共同组成的。举一个空泛的例子:
if (a) {
 doSomethingUnderConditionA();
} else if (b) {
 doSomethingUnderConditionB();
}

条件A和B可能在匹配的集合上是包含关系,也就是说一个是另外一个的强条件。假设A是更强的条件,那么在条件更强的情况下,我们往往可以给一个更有效率的解。但是有可能,如果没有条件A这个分支,所有情况都走条件B的分支,解仍然是正确的。所有说,A的存在不影响程序的正确性,只影响了程序在特定条件下的效率。那么,在这种情况下,就不能说代码增一行太多了。
分享到:
评论
24 楼 123456 2006-12-27  
不错。
23 楼 凤舞凰扬 2006-12-26  
RyanPoy 写道
真是寒自己一个。在测试先行的今天,我们公司还是要求我们写main()来进行测试。

   兄弟,好的测试,不在乎你用的是Junit还是main,更重要的是你对测试的认同感,重视度,还有懂得怎么去测试。
    自然,懂得使用好的工具是一个优秀的工程师也需要具备的。
22 楼 凤舞凰扬 2006-12-26  
   许久没有上来了,最近忙着给新入职的同事做培训,刚刚好,涉及到单元测试这个话题。
   首先,我将楼主的范围人为限制在单元测试下吧,这样容易讨论,也估计是楼主想讨论的。
   我们应该弄清楚什么是足够。在不同条件约束下,对于足够的理解是不同的。不过,我们至少可以说或者清楚,在一般商业系统的开发下,单元测试的足够标准其实是可以确定的。可以这么说,足够就是你需要做更深入或者详细测试从而发现问题的成本大于你的限制成本时,那么,我们认为它就是足够的了。简单讲,就是你需要做单元测试所花费的人力和时间成本高于在这阶段发现问题的价值时,那么单元测试就足够了。或者,也可以说,当你的任务计划不允许你做进一步测试,或者你已覆盖了一定比例的测试路径时,测试是足够的了。那么,这种比例是多少?这种成本的估算又是怎么来,这就要看具体的企业与系统目标,还有项目机会了。有的人也许提出质疑,但是谁都不能否认,做高精密控制系统、要求严格的金融商业系统、操作系统、广泛使用的公用基础组件以及普通的MIS和网站,它的要求是绝对不同的。
   TDD从来就没有错,但是,这种实践的一个不得不面对的问题是,它忽略了设计与实现的复杂性。实现一个逻辑,和穷举验证这个逻辑的确定性所带来的工作量相差是巨大的。每本推崇TDD的书似乎都很喜欢拿add或者div方法做sample。但是实际的业务方法又是何其复杂,试图在设计之初就去穷举测试路径是不现实的。
   那么,我们是否有可操作的实践那?当然有!一般说来,一个单元测试用例需要覆盖主要路径,分别就通过测试(1-3测试条件)、失败测试(1-2测试条件)、异常测试(1-2次测试条件)、错误测试(1次主要的测试条件)基本可以说,单元测试的工作是足够的,并且带来工作量的影响也是可以接受的。当然,另外一个问题就是测试数据的多样性。
  

   另外,对于dongbin的关于XP的理解,个人是不太认同的。首先来说,TDD与Pair Programming只是XP的实践之一,并非它的Principles或者是Core Values。不是说没有TDD和Pair Programming,XP就变了位,XP的核心思想在于沟通和敏捷。在我们学习和使用任何一种经验技术时,最忌讳的就是全盘照搬或者否定。TDD和Pair Programming在中国的实践并不好,自然有其原因的。我们需要做的是尽量找出其问题或者说冲突所在。
21 楼 RyanPoy 2006-12-08  
真是寒自己一个。在测试先行的今天,我们公司还是要求我们写main()来进行测试。
20 楼 firebody 2006-11-26  
足够的定义:

 
  1)贴近需求的测试
  2)如果逻辑比较复杂,可能需要考虑多一些边界情况。


毕竟开发功能的人员不可能全力以赴地进行测试来保证功能针对每一个输入情况的准确反馈。
更何况,一些特殊的输入情况的反馈也需要需求的深入分析。 功能质量的全面测试有QA来保证。

对于开发人员来说,重要的是他写测试的目的是什么:
测试对于功能实现开发者来说,有几点需要保证:

1)保证需求的实现 在测试里面得到反映

2) 保证对重构提供的足够的支持



19 楼 cookoo 2006-11-26  
Unit test测试的是你预期发生的事,即使程序路径被100%覆盖到,其实还有一部分你没有预期到的情况并没有被测试到。对安全性要求高的应用可以用随机值测试来检测意外情况。
18 楼 superq 2006-11-25  
这里有篇文章讨论的是类似的问题<br/>
<br/>
<a href='http://www.developerdotstar.com/mag/articles/test_smarter_not_harder.html'>Test Smarter, Not Harder</a><br/>
<br/>
从统计学的角度看,就算测试没有覆盖全部的路径,你也可以对自己的产品质量有足够的信心。那篇文章分析了在不同的要求下,多少测试才是足够的。
17 楼 dongbin 2006-11-24  
抛出异常的爱 写道
lingate 写道
抛出异常的爱 写道
Tin 写道
taowen 写道
说实话,没有TDD也可以XP。
如果任务真的很简单,干嘛要放两个人在同一件的事情上?

嗯,说得好呀。这是自我解放,做事可以Pragmatic,从心。制度应该给不动脑子的人

测试的入手点的确是需要动脑子保证的,同样的场景可能有很多种测试的思路,所以如你所说这应该是由写测试的人决定,而不能通过另外一个测试保证。TDD让你从开始考虑验收的检查点,从一开始就在让思路清晰。


质量?与简单不简单没有直接关系
我们认为简单的东西出错的机会要比难的东西出错机会要高的多
不信可以看我们组的bug表...

一个制度如果是为了让人不动脑子那么这个制度就是个好制度....
从心?去画画,去写诗,
不要作工人..程序员...和我组员...

我想大家所说的简单是指架构简单化,而你所说的简单是指那些重复的,常常不能引起别人注意的东西(这里面带着许多个人特征,比如代码习惯,使用工具等),简单确实不能完全避免错误,但对于发现错误却是很有帮助的。测试能在一定程度上减少错误,其中也包含了许多的简单的错误。也由于编写测试需要从使用角度来分析编写,也从另一个角度促进了架构的简单化。但这里并不意味着做工人(蓝领也是好样的,只是大家兴趣缺缺),因为从某种角度来说,简化架构才是最难的。


测试就如同小学作算数题目
每写完一题就用逆运算进行验算一下
不能保证一定会把错找到但大大减少了人为错误
很多男生从不验算....
认为太简单不会作错....
但是能得一百分的很少


简化架构...那是重构要作的事吧
作测试只会把架构作的更复杂...
由于重用变多了代码会被化简
理解TDD的人都知道,测试和重构是TDD中不可分的。用很Ugly的方式通过测试,然后用refactoring 来简化设计。这个过程是自然而然的,并不需要刻意分为两部分。

两者也缺一不可。
16 楼 抛出异常的爱 2006-11-24  
lingate 写道
抛出异常的爱 写道
Tin 写道
taowen 写道
说实话,没有TDD也可以XP。
如果任务真的很简单,干嘛要放两个人在同一件的事情上?

嗯,说得好呀。这是自我解放,做事可以Pragmatic,从心。制度应该给不动脑子的人

测试的入手点的确是需要动脑子保证的,同样的场景可能有很多种测试的思路,所以如你所说这应该是由写测试的人决定,而不能通过另外一个测试保证。TDD让你从开始考虑验收的检查点,从一开始就在让思路清晰。


质量?与简单不简单没有直接关系
我们认为简单的东西出错的机会要比难的东西出错机会要高的多
不信可以看我们组的bug表...

一个制度如果是为了让人不动脑子那么这个制度就是个好制度....
从心?去画画,去写诗,
不要作工人..程序员...和我组员...

我想大家所说的简单是指架构简单化,而你所说的简单是指那些重复的,常常不能引起别人注意的东西(这里面带着许多个人特征,比如代码习惯,使用工具等),简单确实不能完全避免错误,但对于发现错误却是很有帮助的。测试能在一定程度上减少错误,其中也包含了许多的简单的错误。也由于编写测试需要从使用角度来分析编写,也从另一个角度促进了架构的简单化。但这里并不意味着做工人(蓝领也是好样的,只是大家兴趣缺缺),因为从某种角度来说,简化架构才是最难的。


测试就如同小学作算数题目
每写完一题就用逆运算进行验算一下
不能保证一定会把错找到但大大减少了人为错误
很多男生从不验算....
认为太简单不会作错....
但是能得一百分的很少


简化架构...那是重构要作的事吧
作测试只会把架构作的更复杂...
由于重用变多了代码会被化简
15 楼 lingate 2006-11-23  
抛出异常的爱 写道
Tin 写道
taowen 写道
说实话,没有TDD也可以XP。
如果任务真的很简单,干嘛要放两个人在同一件的事情上?

嗯,说得好呀。这是自我解放,做事可以Pragmatic,从心。制度应该给不动脑子的人

测试的入手点的确是需要动脑子保证的,同样的场景可能有很多种测试的思路,所以如你所说这应该是由写测试的人决定,而不能通过另外一个测试保证。TDD让你从开始考虑验收的检查点,从一开始就在让思路清晰。


质量?与简单不简单没有直接关系
我们认为简单的东西出错的机会要比难的东西出错机会要高的多
不信可以看我们组的bug表...

一个制度如果是为了让人不动脑子那么这个制度就是个好制度....
从心?去画画,去写诗,
不要作工人..程序员...和我组员...

我想大家所说的简单是指架构简单化,而你所说的简单是指那些重复的,常常不能引起别人注意的东西(这里面带着许多个人特征,比如代码习惯,使用工具等),简单确实不能完全避免错误,但对于发现错误却是很有帮助的。测试能在一定程度上减少错误,其中也包含了许多的简单的错误。也由于编写测试需要从使用角度来分析编写,也从另一个角度促进了架构的简单化。但这里并不意味着做工人(蓝领也是好样的,只是大家兴趣缺缺),因为从某种角度来说,简化架构才是最难的。
14 楼 lingate 2006-11-23  
我认为对于一个类来说,测试如果能重现所有的使用方式,再加上契约的测试,应该就算是一个完整的测试了。
13 楼 giscat 2006-11-22  
测试不是目的,
只是一种手段,
不管怎么玩,
得把软件质量搞上去
把开发维护成本搞下来,


12 楼 zhoujian 2006-11-21  
kan kan
11 楼 dongbin 2006-11-21  
抛出异常的爱 写道
Tin 写道
taowen 写道
说实话,没有TDD也可以XP。
如果任务真的很简单,干嘛要放两个人在同一件的事情上?

嗯,说得好呀。这是自我解放,做事可以Pragmatic,从心。制度应该给不动脑子的人

测试的入手点的确是需要动脑子保证的,同样的场景可能有很多种测试的思路,所以如你所说这应该是由写测试的人决定,而不能通过另外一个测试保证。TDD让你从开始考虑验收的检查点,从一开始就在让思路清晰。


质量?与简单不简单没有直接关系
我们认为简单的东西出错的机会要比难的东西出错机会要高的多
不信可以看我们组的bug表...

一个制度如果是为了让人不动脑子那么这个制度就是个好制度....
从心?去画画,去写诗,
不要作工人..程序员...和我组员...
简单性和质量的关系很多书已经说过了。

就我这种比较笨的人而言,稍微复杂一点的东西我都理解不了,不把它弄简单怎么办?

10 楼 抛出异常的爱 2006-11-20  
Tin 写道
taowen 写道
说实话,没有TDD也可以XP。
如果任务真的很简单,干嘛要放两个人在同一件的事情上?

嗯,说得好呀。这是自我解放,做事可以Pragmatic,从心。制度应该给不动脑子的人

测试的入手点的确是需要动脑子保证的,同样的场景可能有很多种测试的思路,所以如你所说这应该是由写测试的人决定,而不能通过另外一个测试保证。TDD让你从开始考虑验收的检查点,从一开始就在让思路清晰。


质量?与简单不简单没有直接关系
我们认为简单的东西出错的机会要比难的东西出错机会要高的多
不信可以看我们组的bug表...

一个制度如果是为了让人不动脑子那么这个制度就是个好制度....
从心?去画画,去写诗,
不要作工人..程序员...和我组员...
9 楼 Tin 2006-11-20  
taowen 写道
说实话,没有TDD也可以XP。
如果任务真的很简单,干嘛要放两个人在同一件的事情上?

嗯,说得好呀。这是自我解放,做事可以Pragmatic,从心。制度应该给不动脑子的人。

测试的入手点的确是需要动脑子保证的,同样的场景可能有很多种测试的思路,所以如你所说这应该是由写测试的人决定,而不能通过另外一个测试保证。TDD让你从开始考虑验收的检查点,从一开始就在让思路清晰。
8 楼 dongbin 2006-11-20  
taowen 写道
说实话,没有TDD也可以XP。但是XP做惯了的人,一定会在可能的情况下,尽量选择TDD的开发方式。曾经有人告诉我一位前辈在没法写测试的情况下是如何写代码的。他会把所有的任务给一个个的列出来,相当于写一个不可运行的测试,然后一个个的打钩,做起来一样有条不紊的。
结对编程也是一样的。我也不认为不结对就不可以做XP了。如果任务真的很简单,干嘛要放两个人在同一件的事情上?


有道理。

我的意思是,没有TDD和结对,是让人觉得很不舒服的XP,效率会大打折扣,只能说是一种妥协的XP。

也许我的观点过于理想化了,但是我还是想追求最高效率的开发过程。
7 楼 dongbin 2006-11-20  
Tin 写道
代码增一行太多,减一行太少是很难。
因为那样要写一个正确、健壮、有效的测试,这太难了。不是说不要对你的测试进行测试么?
这样,对于自动删程序判断是否还可以通过测试这种方式来说,没有自动化的测试保证是不可以的。但是如果是手动,凭人脑……那么就……

所以,是不是说测试应该保证主干正确性,或者像Rod说的那样代码覆盖率不能说明一切。对于稀的测试path,应该尽量凭经验,没法强求吧。


“没有自动化的测试保证是不可以的”,所以所有测试都要自动化啊!

测试难写,正是因为现实问题的复杂。而解决现实问题正是发挥我们聪明才智的时候。

测试难写,还强迫我们写出易于测试的程序,你要先问一下自己,是这个问题难测试,还是你的代码难以测试。

写测试是很难,幸运的是,程序员是聪明的,而重复的手动测试却不是聪明人愿意做的。
6 楼 taowen 2006-11-20  
说实话,没有TDD也可以XP。但是XP做惯了的人,一定会在可能的情况下,尽量选择TDD的开发方式。曾经有人告诉我一位前辈在没法写测试的情况下是如何写代码的。他会把所有的任务给一个个的列出来,相当于写一个不可运行的测试,然后一个个的打钩,做起来一样有条不紊的。
结对编程也是一样的。我也不认为不结对就不可以做XP了。如果任务真的很简单,干嘛要放两个人在同一件的事情上?
5 楼 taowen 2006-11-20  
Tin 写道
代码增一行太多,减一行太少是很难。
因为那样要写一个正确、健壮、有效的测试,这太难了。不是说不要对你的测试进行测试么?
这样,对于自动删程序判断是否还可以通过测试这种方式来说,没有自动化的测试保证是不可以的。但是如果是手动,凭人脑……那么就……

所以,是不是说测试应该保证主干正确性,或者像Rod说的那样代码覆盖率不能说明一切。对于稀的测试path,应该尽量凭经验,没法强求吧。

测试的正确性之所以不用另外一个测试来保证,是因为测试自身没有复杂的逻辑,其正确性就是靠你的人脑。测试不正确,不是测试代码的不正确,而是你的想法错了。
很少运行到的路径是不是要测试就看自己的权衡了。在时间和质量之间的权衡。这种权衡当然也是要符合敏捷的原则的,就是总是选择诸多选择中投入最少,收益最高的那个。

相关推荐

    软件测试的有效方法(第3版 英文版)WorkPaper

    另外,管理层是否对测试理论、过程和工具有足够的了解,以便有效地管理测试计划和执行,并理解测试结果?这要求管理层不仅要提供资源,还要具备相应的专业知识,才能做出正确的决策。 ### 测试过程的应用 测试过程...

    按照业务流和数据流写测试用例

     作为一个完整的详细设计书,它应该写清楚数据的增删改查,当然很多详细设计书没有写到这种程度,可是我们换个角度想,开发人员也是在这种不是很详细的设计下进行开发的,他们要根据式样的理解,写出满足条件的SQL...

    测试用例设计参考文档

    测试用例的数量和深度直接影响了测试的质量和覆盖率,从而影响到软件的可靠性。 测试用例的重要性在于它们为测试活动提供了基础,确保测试的全面性和一致性。每个需求至少应有两个测试用例:一个是正向测试用例,...

    软件/系统测试记录模板

    测试记录模板的设计应尽可能简洁明了,同时包含足够的信息,以支持高效的缺陷管理和问题解决流程。通过规范化的记录,测试团队能够更有效地协作,提高软件和系统的整体质量。在实践中,不断优化和调整模板,使其适应...

    软件测试经典面试题

    2. **测试驱动开发(TDD)**:先写测试用例再编写代码,确保代码质量。 3. **边界值分析**:测试边界条件下的行为,如数组的首尾元素。 4. **错误推测**:根据经验预测容易出错的地方,并针对性地设计测试用例。 5. **...

    menu测试模板

    - **测试目标**:明确测试的目的是什么,例如验证菜单功能的正确性或优化用户体验。 - **测试环境**:列出测试所需的硬件、软件和网络条件。 - **测试步骤**:详述如何执行每个测试用例,包括操作步骤和预期结果。 -...

    华为——测试用例模板

    8. **优先级和关联性**:测试用例的重要程度和与其他用例的关系,帮助确定测试顺序。 9. **负责人**:指定负责执行该测试用例的人员。 10. **状态**:如新建、待执行、执行中、通过、失败等,表示用例的生命周期...

    测试用例和测试报告管理

    测试用例的设计和管理直接影响到测试的效率和有效性,而测试报告则为项目的各方提供了一个评估软件质量的依据。 首先,测试用例设计的基础是基于对软件需求的全面了解,这通常以软件需求分析文档为蓝本。测试用例...

    软件测试 面试题大全

    - **白盒测试**:基于对代码结构的理解来设计测试用例,确保每个逻辑路径都被测试到。 - **黑盒测试**:只关注接口行为,不考虑内部实现细节。 - **边界值测试**:重点测试边界值和异常情况,以发现潜在的错误。 - *...

    软件测试的有效方法(第3版)英文版

    - **政策制定的重要性**:明确组织对软件测试的态度和支持程度。 - **关键问题**: - 组织是否有明确的软件测试政策? - 测试策略是否已经建立? - 是否有支持该策略所需的软件过程和工具? **知识点2:测试策略...

    软件测试规范

    1.什么是软件测试 .................................................................................................................................. 2 2.软件测试的目标 ....................................

    如何写有效的软件测试Bug报告

    - **影响评估**:分析该缺陷对用户及测试过程的影响程度。 - **辅助调试**:提供可能有助于开发人员调试的信息,如截图、日志等。 - **证据支持**:提供证据证明问题的存在,增强报告的可信度。 #### 四、案例分析 ...

    网上购物系统测试计划书

    - **硬件配置**: 测试服务器的具体硬件配置未给出,通常需要足够的CPU、内存、存储空间等。 - **人员**: 包括测试审核人3名和测试实施人员30名。 - **工具**: - 缺陷管理工具: Mantis,用于记录和跟踪缺陷。 - ...

    软件测试报告 和试题

    综合以上内容,我们可以了解到软件测试涉及的广泛知识,包括测试文档编写、测试策略制定、测试工具应用以及如何针对不同类型的系统进行有效的测试。这些资料对于学习和实践软件测试的人来说是宝贵的资源,能够提升...

    软件测试-测试覆盖率

    测试覆盖率是衡量软件测试有效性的重要指标,它反映了测试用例对程序代码执行程度的覆盖。在软件测试过程中,测试覆盖率通常包括逻辑覆盖率和功能覆盖率两个主要方面。 1. 逻辑覆盖率(Code Coverage): - 语句...

    测试你的C语言掌握程度

    ### 测试你的C语言掌握程度 #### C语言基础与字符串操作 **字符串处理函数:** - **`strlen()`**:该函数用于计算一个字符串的实际长度(不包括结尾的空字符`\0`)。例如,对于字符串"hello",其长度为5。 - **`...

    软件测试认证ISEB 试题

    这些标准通常在测试规划阶段制定,包括了测试目标的实现程度、遗留缺陷的数量等。因此,选项A“测试规划”是最合适的答案。 #### 四、定义测试预期结果 **题目**: 以下哪一项定义了测试的预期结果? - A.测试用例...

    XXX项目软件测试计划模板

    测试环境的设定是保证测试有效性的基础,它包括硬件、软件、网络环境等,应与实际运行环境一致,以最大程度地模拟真实情况。 测试方案详细描述了测试范围,包括本次改动点可能影响的领域。测试内容应涵盖功能、性能...

    报表测试的 注意事项

    - **数据的多样性**:考虑到报表可能会涉及多种业务场景,因此测试数据也应该涵盖多种业务类型和状态,以确保测试的全面性。 #### 结论 报表测试不仅仅是简单的功能验证,它涉及到对业务流程的深入理解和对数据...

Global site tag (gtag.js) - Google Analytics