长期以来,我所接触的软件开发人员很少有人能在开发的过程中进行测试工作。大部分的项目都是在最终验收的时候编写测试文档,有些项目甚至没有测试文档。现在情况有了改变。我们一直提倡UML、RUP、软件工程、CMM,目的只有一个,提高软件编写的质量。举一个极端的例子:如果你是一个超级程序设计师,一个传奇般的人物(你可以一边喝咖啡,一边听着音乐,同时编写这操作系统中关于进程调度的模块,而且两天时间内就完成了!)。我真得承认,有这样的人(那个编写UNIX中的vi编辑器的家伙就是这种人)。然而非常遗憾的是这些神仙们并没有留下任何关于如何修成正果的README,所以我们这些凡人--在同一时间只能将注意力集中到若干点(据科学统计,我并不太相信,一般的人只能同时考虑最多7个左右的问题,高手可以达到12个左右),而不能既纵览全局又了解细节--只能期望于其他的方式来保证我们所编写的软件质量。
为了说明我们这些凡人是如何的笨。有一个聪明人提出了软件熵(software entropy)的概念:一个程序从设计很好的状态开始,随着新的功能不断地加入,程序逐渐地失去了原有的结构,最终变成了一团乱麻。你可能会争辩,在这个例子中,设计很好的状态实际上并不好,如果好的话,就不会发生你所说的情况。是的,看来你变聪明了,可惜你还应该注意到两个问题:1)我们不能指望在恐龙纪元(大概是十年前)设计的结构到了现在也能适用吧;2)拥有签字权的客户代表可不理会加入一个新功能是否会对软件的结构有什么影响,即便有影响也是程序设计人员需要考虑的问题。如果你拒绝加入这个你认为致命的新功能,那么你很可能就失去了你的住房贷款和面包(对中国工程师来说也许是米饭或面条,要看你是南方人还是北方人)。
另外,需要说明的是我看过的一些讲解测试的书都没有我写的这么有人情味(不好意思...)。我希望看到这篇文章的兄弟姐妹能很容易地接受测试的概念,并付诸实施。所以有些地方写的有些夸张,欢迎对测试有深入理解的兄弟姐妹能体察民情,并不吝赐教。
好了,我们现在言归正传。要测试,就要明白测试的目的。我认为测试的目的很简单也极具吸引力:写出高质量的软件并解决软件熵这一问题。想象一下,如果你写的软件和Richard Stallman(GNU、FSF的头儿)写的一样有水准的话,是不是很有成就感?如果你一直保持这种高水准,我保证你的薪水也会有所变动。
测试也分类,白箱测试、黑箱测试、单元测试、集成测试、功能测试...。我们先不管有多少分类,如何分类。先看那些对我们有用的分类,关于其他的测试,有兴趣的人可参阅其他资料。白箱测试是指在知道被测试的软件如何(How)完成功能和完成什么样(What)的功能的条件下所作的测试。一般是由开发人员完成。因为开发人员最了解自己编写的软件。本文也是以白箱测试为主。黑箱测试则是指在知道被测试的软件完成什么样(What)的功能的条件下所作的测试。一般是由测试人员完成。黑箱测试不是我们的重点。本文主要集中在单元测试上,单元测试是一种白箱测试。目的是验证一个或若干个类是否按所设计的那样正常工作。集成测试则是验证所有的类是否能互相配合,协同完成特定的任务,目前我们暂不关心它。下面我所提到的测试,除非特别说明,一般都是指单元测试。
需要强调的是:测试是一个持续的过程。也就是说测试贯穿与开发的整个过程中,单元测试尤其适合于迭代增量式(iterative and incremental)的开发过程。Martin Fowler(有点儿像引用孔夫子的话)甚至认为:“在你不知道如何测试代码之前,就不应该编写程序。而一旦你完成了程序,测试代码也应该完成。除非测试成功,你不能认为你编写出了可以工作的程序。”我并不指望所有的开发人员都能有如此高的觉悟,这种层次也不是一蹴而就的。但我们一旦了解测试的目的和好处,自然会坚持在开发过程中引入测试。因为我们是测试新手,我们也不理会那些复杂的测试原理,先说一说最简单的:测试就是比较预期的结果是否与实际执行的结果一致。如果一致则通过,否则失败。
我们目前所能做的就是尽量降低所付出的代价:我们编写的测试代码要能被维护人员容易的读取,我们编写测试代码要有一定的规范。最好IDE工具可以支持这些规范。好了,你所需要的就是JUnit。一个Open Source的项目。用其主页上的话来说就是:“ JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。用于Java开发人员编写单元测试之用。”所谓框架就是Erich Gamma 和 Kent Beck 定下了一些条条框框,你编写的测试代码必须遵循这个条条框框:继承某个类,实现某个接口。其实也就是我们前面所说的规范。好在JUnit目前得到了大多数软件工程师的认可。遵循JUnit我们会得到很多的支持。回归测试就是你不断地对所编写的代码进行测试:编写一些,测试一些,调试一些,然后循环这一过程,你会不断地重复先前的测试,哪怕你正编写其他的类,由于软件熵的存在,你可能在编写第五个类的时候发现,第五个类的某个操作会导致第二个类的测试失败。通过回归测试我们抓住了这条大Bug。
JUnit就是对程序代码进行单元测试的一种Java框架。通过每次修改程序之后测试代码,程序员就可以保证代码的的少量变动不会破坏整个系统。要不是有Junit这样的自动化测试工具,代码的的反复测试简直会把人累死而且还可能不准确。现在好了,测试过程可以频繁进行而且还是自动的,所以你可以令程序错误降低到最少。它写的是单元测试(Unit Test):软件工程里的白盒测试,就是测试某个类的某个方法的功能。XP 中推崇的 test first design 就是基于以上的技术。
如果你要写一段代码:
1. 先用 junit 写测试,然后再写代码
2. 写完代码,运行测试,测试失败
3. 修改代码,运行测试,直到测试成功
如果以后对程序进行修改,优化 ( refactoring ),只要再运行测试代码,如果所有的测试都成功,则代码修改完成。
先写测试,再写代码的好处:
从技术上强制你先考虑一个类的功能,也就是这个类提供给外部的接口,而不至于太早陷入它的细节。这是面向对象提倡的一种设计原则。好的测试其实就是一个好的文档,这个类使用者往往可以通过查看这个类的测试代码了解它的功能。特别的,如果你拿到别人的一个程序,对他写测试是最好的了解这个程序的功能的方法。 xp的原则是 make it simple,不是很推荐另外写文档,因为项目在开发过程中往往处于变动中,如果在早期写文档,以后代码变动后还得同步文档,多了一个工作,而且由于项目时间紧往往文档写的不全或与代码不一致,与其这样,不如不写。而如果在项目结束后再写文档,开发人员往往已经忘记当时写代码时的种种考虑,况且有下一个项目的压力,管理人员也不愿意再为旧的项目写文档,导致以后维护的问题。没有人能保证需求不变动,以往项目往往对需求的变动大为头疼,害怕这个改动会带来其他地方的错误。为此,除了设计好的结构以分割项目外(松耦合),但如果有了测试,并已经建立了一个好的测试框架,对于需求的变动,修改完代码后,只要重新运行测试代码,如果测试通过,也就保证了修改的成功,如果测试中出现错误,也会马上发现错在哪里,修改相应的部分,再运行测试,直至测试完全通过。
软件公司里往往存在开发部门和测试部门之间的矛盾:由于开发和测试分为两个部门,多了一层沟通的成本和时间,沟通往往会产生错误的发生。而且极易形成一个怪圈:开发人员为了赶任务,写了烂烂的代码,就把它扔给测试人员,然后写其他的任务,测试当然是失败的,又把代码拿回去重写,而且在国内往往一个软件公司技术最差的部门就是测试部门(好的人都跑去写代码了),测试就成了一个很头疼的问题。这种怪圈的根源是责任不清,根据 xp 中的规定:写这个代码的人必须为自己的代码写测试,而且只有测试通过,才算完成这个任务(这里的测试包括所有的测试,如果测试时发现由于你的程序导致别的模块的测试失败,你有责任通知相关人员修改直至集成测试通过),这样就可以避免这类问题的发生。
分享到:
相关推荐
《读书方法 稻盛和夫 极限编程》这个主题融合了两个看似不同但实则相辅相成的概念:稻盛和夫的读书智慧与极限编程在IT领域的实践。稻盛和夫,日本著名的企业家和哲学家,以其独特的经营哲学和深入的读书方法闻名,他...
极限编程软件(APK)实施准则衍生自其核心思想,包括快速反馈、假设简单性、提倡更改等。快速反馈准则强调反馈的及时性,使开发人员能够集中精力在主要的Android软件功能上。假设简单性准则关注如何以最简单的设计...
"敏捷型软件开发方法与极限编程概述" 本文将对敏捷型软件开发方法与极限编程进行概述,探讨它们的优点和适用场景。 敏捷型软件开发方法是一种以灵活、适应变化为核心思想的软件开发方式。它强调在快速迭代中不断...
**极限编程(Extreme ...总之,Java极限编程结合了敏捷开发的思想和Java语言的优势,为开发团队提供了一套高效、灵活且质量可控的开发流程。通过不断实践和学习,开发者可以更好地掌握这一方法,提升项目成功率。
极限编程的核心思想在于早期发现和解决问题,降低复杂性,通过短迭代周期和频繁交付,快速响应用户需求变化,提高软件开发效率和质量。这种方法适用于需求经常变化或不确定性的项目,通过快速反馈和适应性调整,帮助...
极限编程(eXtreme Programming, XP)是敏捷开发方法的一种,由Kent Beck在1998年提出。XP的核心理念在于强调团队协作、快速反馈和适应变化。它由一系列相互关联的实践组成,旨在提高软件开发的效率和质量。 1. ...
内容简介 · · · · · · 在这本新书《实现模式》里面, Kent Beck将自己多年形成的编程习惯以及阅读既有代码...长期以来,他一直致力于挑战软件工程教条,推动模式、测试驱动开发以及极限编程等思想的应用和传播。
极限编程(简称XP)是一种软件开发的纪律,强调简单性、沟通、反馈和勇气四大价值观。XP将焦点放在客户、管理者及程序员的角色上,并赋予这些角色相应的权利与责任。 #### 圈子的生活(Circle of Life) 在极限...
7. 极限编程(XP):作为敏捷开发的一种实践,极限编程强调简单的设计、持续集成、测试驱动开发等原则,以减少风险和提高软件质量。 8. 软件质量保证(SQA):SQA是确保软件产品符合预定质量标准的过程,包括质量...
后来,Kent Beck、Ward Cunningham和Ron Jeffries在推广极限编程(XP)时,将其纳入关键实践。XP的成功推广使得成对编程逐渐被广泛接受和应用。 成对编程有多个好处。在企业层面上,它促进了团队成员间的交流和知识...
- 极限编程(XP):介绍XP的核心思想以及如何将其中的要点与Python编程结合,创造出“好玩的编程”(Playful Programming)。 - 程序设计的柔术:将日本武术柔术的思想应用到编程中,倡导在编程中保持灵活性,顺势...
敏捷方法,帮你整理思路,通过ACP考试,涵盖XP极限编程实践,Scrum框架角色、物件、精益开发、看板实践
极限编程是一种软件开发方法论,强调应对变化的能力,它通过一系列实践,如持续集成、小型发布、重构等,来提高软件质量和响应变化的能力。熟练掌握测试驱动开发,对于采用XP开发过程有着极大的帮助。 即使采用的...
HALCON采用了面向对象的编程思想,允许用户以直观的方式处理图像和数据。 - **组织架构**:HALCON通过清晰的模块化设计将复杂的视觉处理任务分解为多个简单步骤,每个步骤都可以通过特定的函数来实现。 - **数据...
- 极限学习机的核心思想是随机初始化隐藏层节点权重和偏置,然后通过单次训练计算输出层权重,避免了传统反向传播算法的多次迭代过程。 - ELM模型由输入层、隐藏层和输出层构成,其中隐藏层节点的激活函数通常选择...
6. **解析极限编程 拥抱变化**:极限编程(XP)是一种敏捷开发方法,重视客户满意度、团队沟通和反馈循环。书中涵盖了故事卡、结对编程、持续集成、测试先行和简单设计等XP实践,旨在提高软件质量和开发效率。 通过...