2010年12月15日


本文已经首发于
InfoQ中文站,版权所有,原文为《XXX》,如需转载,请务必附带本声明,谢谢。

InfoQ中文站是一个面向中高端技术人员的在线独立社区,为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如QCon 、线下技术交流活动QClub、免费迷你书下载如《架构师》等。​

 

在与不少测试从业人员讨论到敏捷的时候,被问得最多的大约是两个问题:“到底什么是敏捷软件测试?”,“敏捷软件开发还需要测试工程师吗?”。前一个问题是对于敏捷测试本身定义的疑问,第二个问题则是对敏捷开发将测试工程师排除在外的担心。其实,在探寻这两个问题答案的过程中,我们可以更清晰的了解敏捷软件开发中测试的工作定义,测试价值观,以及敏捷开发中开发与测试工程师的配合。鉴于这两个问题的意义,在本敏捷测试专栏的第一篇文章中,本人尝试从自己的实践出发,尽可能清楚的回答这两个问题。

确实,相对于敏捷开发红遍大江南北的状况而言,对敏捷测试的讨论则低调得多。敏捷联盟定义了敏捷的4个价值声明,以及伴随的12条支持原则,这12条原则中没有一条单独提到测试。这是不是意味着测试在敏捷开发中并不重要呢?实际上,如果仔细研读敏捷的12个原则,以及各种不同的敏捷实践,就会发现,测试在敏捷开发中占有非常重要的地位。无论是原则中的“频繁交付”,还是对“可工作的软件”的度量,或是敏捷开发实践中的“测试驱动开发”,“行为驱动开发”,都离不开测试的支持。在本人看来,敏捷开发中不把测试单独拿出来描述的原因,恰恰是因为在敏捷开发中,测试不再是一个单独的、和开发独立的过程,而是变成了驱动开发、衡量产出的主要的手段,成为了敏捷开发中所有工程师在工作时必须时刻考虑和实践的一个部分。简而言之,敏捷软件测试更多的是一种理念,而非过程。

既然是这样,为什么我们还要在这个专栏中专门来讨论“敏捷软件测试”?本人接触过不少软件开发和测试工程师,他们所处的组织有的正在努力向敏捷开发转型,有的已经实践了一段实践的敏捷开发,但由于由来已久的工作习惯,他们中的绝大多数并不能自觉的认识到测试在敏捷开发中的关键作用,而是有意无意的将测试仍然看作是与开发截然分开的“下一个阶段”,导致在实践敏捷开发的过程中遇到种种问题:要么是忽略了代码质量,导致在频繁的迭代过程中,每一个迭代的问题层出不穷;或是沿用原有的方法安排对系统的系统测试,导致测试团队疲于奔命,却总也赶不上开发所要求的进度。在这种情况下,专门来讨论敏捷软件开发中的测试,也就是敏捷软件测试的话题,对这些工程师应该会有一些帮助。

那么,到底什么是敏捷软件测试?很难给敏捷测试下一个精确、完善的定义,在本人看来,接纳了敏捷的核心价值观(沟通,简单,反馈,勇气,尊重),在敏捷软件开发过程中开展的测试就可以被称作是敏捷软件测试。因此,敏捷软件测试并不是一个与敏捷软件开发同一层次的划分,而是敏捷软件开发中的一部分,与传统的测试不同,敏捷软件测试并不是一个独立的过程,相反,它与整个敏捷开发中的其他活动交织在一起,处处都能看到它的影子。由于敏捷软件测试并不倾向于一个单独的过程定义,本人拟从敏捷软件测试与传统测试观点的比较、敏捷软件测试中采用的方法、测试工程师在敏捷软件测试过程中的工作等方面来阐述之。在这篇文章中,我们主要从宏观的角度来描述敏捷软件测试,而在本专栏的后续文章中,我们将对敏捷软件测试中采用的方法、工程师在敏捷软件测试中的工作内容等进行进一步的描述。

敏捷软件测试是建立在敏捷核心价值观的基础上,为了更生动的描述其与传统软件测试的区别,本人从自己的实践经验出发,尝试给出包含了本人认为包含了敏捷测试关键要素的“敏捷测试检查表”:

项目

检查点

注释

团队

  • 测试工程师是否与开发工程师建立了紧密联系?
  • 测试工程师是否与客户建立和紧密联系?
  • 是否参加每日站立会议?是否与开发工程师可以展开随时的,面对面的,对等的讨论?
  • 是否保持和客户的良好沟通?是否和客户一起维护良好定义的验收测试?

反馈

  • 项目是否建立了合适的验收测试?
  • 是否项目中每个人都能随时了解当前工作与可交付产品的距离?
  • 是否建立了针对开发质量的度量标准?
  • 开发工程师是否能够快速得到对提交代码的反馈?
  • 使用Dashboard、燃尽图等方式展示当前工作与可交付产品之间的距离
  • 建立单元测试覆盖率等度量指标
  • 使用持续集成或频繁的构建让开发工程师快速得到提交代码的质量反馈

质量文化

  • 是否建立了开发与测试工程师共享质量目标的原则?
  • 团队是否注重开发质量,并在工作中尽可能保证高的开发/代码质量?
  • 共享质量目标意味着质量责任由所有工程师共同承担
  • 不仅关注最终的产出,不断对代码进行重构,保证代码质量

开发测试

  • 是否进行了充分的开发测试?
  • 是否设立了持续集成环境,并以持续集成的结果作为能够继续提交代码和发布的条件?
  • 是否建立了足够多的自动化测试,以及在设计时关注自动化测试的要求?
  • 开发测试应该建立一定的测试覆盖率标准,例如,在单元测试这个级别上,建立60%或80%的覆盖率要求
  • 通过使用TDD、BDD等技术,保证产品和代码的可测试性
  • 建立足够多的自动化测试,保证测试能够满足快速迭代的要求

检查表提到了“团队”、“反馈”、“质量文化”和“开发测试”四个方面的内容,在本人看来,这四个方面体现的就是敏捷软件测试与传统软件测试的最大的不同。传统软件测试关注的是通过尽可能完备的“覆盖”去发现尽可能多的问题,把测试和开发当成是两个独立的过程,测试是对开发阶段产生成果的验证而敏捷软件测试则建立了一种不同的质量文化:测试的目的是为了保证产品快速发布,也就是对生产率本身的提高。基于“验证”的出发点必然会要求测试与开发的独立,以及尽可能“客观”和“完备”的度量产品质量;而基于“生产率”的出发点则要求建立敏捷的团队,要求测试与开发尽可能紧密,要求建立具有高度可测试性的软件,以及基于这些的高度自动化测试。

在检查表列出的所有项目中,“质量文化”是基础,“团队”是敏捷软件测试得以实施的条件,“反馈”和“开发测试”则是敏捷软件测试的具体方法。当然,你可以可以从敏捷的核心价值观来阶段这些项目:“团队”关注的是沟通尊重;“反馈”直接对应于反馈;“质量文化”基于勇气(承担质量责任的勇气)与尊重;而“开发测试”则是反馈简单的具体体现。

另一个在本文最初提出来的问题是:“敏捷软件开发还需要测试工程师吗?”,对这个问题,业界有不同的观点。有人认为需要,因为总有一些是需要测试工程师的技能完成的工作;当然,也有人认为不需要,因为敏捷开发中的测试注重开发测试与自动化测试,开发工程师就可以自己搞定与测试相关的工作。在实践中,那些大规模实践敏捷开发的公司(例如Google),倾向于在组织中设置数量较少的测试工程师,在项目中分配较少的测试资源,甚至对某些项目,完全不使用测试工程师。

就我的个人实践经验,对大部分的项目,尤其是为明确的客户开发的项目,需要在敏捷开发团队中设置专职的测试工程师,因为:

  1. 测试与开发具有不同的思维方式:测试更注重全面的验证和检查一个系统,而开发工程师往往很难在大的范围内建立这样的思维方式。因此,无论是从系统的层面验证产品,或是从应用系统的角度发现值得测试和验证的点(access point),专职的测试工程师都更有效。
  2. 专职的测试工程师能够更关注于测试基础,建立测试需要的基础架构:由于测试工程师具有更好的对测试的理解,通常他们能够更多的考虑测试的需求而开发适合项目的测试基础架构(自动化测试框架),而开发工程师可以使用这些框架来建立面向功能或代码的测试。
但是,不得不说的是,敏捷开发对开发和测试工程师都提出了更要的要求,尤其是对测试工程师而言,传统的只能“精确模拟用户操作”的测试工程师,因为不能为产品带来生产率的提升,在敏捷开发的团队中,很难有所作为。在本专栏的后续文章中,我们会进一步讨论测试工程师在敏捷软件开发中的工作和任务。 

posted @ 2010-12-15 17:02 关河 阅读(2254) 评论(5) 编辑

2010年11月15日

上周六在杭州的《互联网软件测试大会》上做演讲的时候提到可测试性的话题,顺手举了一个例子:“B类存在对A类的依赖,A类是一个Singleton类,B类使用到了A类中的一个需要被mock的函数,这种情况下如何处理?” 本来,这是《修改代码的艺术》上曾经提到的一个典型模式,该书中有非常详细的描述。但今天收到某位听众的邮件,问这个问题应该怎么回答。

 

正好好久没有写过blog了,于是顺手写了一段简单的代码来说明这个问题。

 

问题:

类Singleton是一个单件类,该类实现了一个名为getUserName()的函数,getUserName函数需要连接到数据库并从数据库中取出用户名称。类DependsOnSingleton类是被测类,该类中的sayHello函数使用到了Singleton类的getUserName函数,在对DependsOnSingleton类进行单元测试的时候,显然我们并不想设置一个真正的数据库,所以最理想的情况是使用mock方式得到一个可以被控制的Singleton类的getUserName函数的实现。如果Singleton类不是一个单件类,这件事情非常简单,使用接口提取的方法从Singleton类提取接口,然后就可以使用mock技术了。但由于Singleton是一个单件类,这件事情就比较棘手了:Singleton.getInstance会返回一个由getInstance自身逻辑决定的Singleton对象,这样就没法直接塞入一个mock对象了。

 

代码:

代码
 1 public class Singleton {
 2     static private Singleton _instance;
 3     public final String userName = "Dennis";
 4     
 5     private Singleton() {
 6     }
 7     
 8     static Singleton getInstance() {
 9         if(null == _instance) {
10             _instance = new Singleton();
11         }
12         return _instance;
13     }
14     
15     String getUserName() throws Exception{
16         // Connect to DB and return data from DB
17         // Throw Exception instead
18         throw new Exception("There's no DB exist");
19     }
20 }

 

1 public class DependsOnSingleton {
2     
3     ...
4     public String sayHello() throws Exception {
5         return "Hi, " + Singleton.getInstance().getUserName();
6     }
7 }

 

解决:

其实解决这个问题的思路,按照《修改代码的艺术》一书的说法,主要是解决“分离”的问题。在Singleton情况下,由于getInstance函数不受控导致了这样的情况,所以最简单的做法是为Singleton类增加一个setTestingInstance函数,使用这个函数注入一个受控的实例。

 

修改后的Singleton:

代码
 1 public class Singleton {
 2     static private Singleton _instance;
 3     public final String userName = "Dennis";
 4     
 5     private Singleton() {
 6     }
 7     
 8     public static Singleton getInstance() {
 9         if(null == _instance) {
10             _instance = new Singleton();
11         }
12         return _instance;
13     }
14     
15     public static void setTestingInstance(Singleton instance) {
16         _instance = instance;
17     }
18     
19     public String getUserName() throws Exception{
20         // Connect to DB and return data from DB
21         // Throw Exception instead
22         throw new Exception("There's no DB exist");
23     }
24 }

 

 

测试代码:

代码
 1 import junit.framework.Assert;
 2 import junit.framework.TestCase;
 3 
 4 import org.easymock.EasyMock;
 5 
 6 public class TestDependsOnSingleton extends TestCase {
 7     public void testSayHello() throws Exception{
 8         Singleton depend = EasyMock.createMock(Singleton.class);
 9         Singleton.setTestingInstance(depend);
10         
11         EasyMock.expect(depend.getUserName()).andReturn("Dennis");
12         EasyMock.replay(depend);
13         
14         DependsOnSingleton itu = new DependsOnSingleton();
15         Assert.assertEquals("Hi, Dennis", itu.sayHello());
16         EasyMock.verify(depend);
17     }
18 }

 

 

 

 

posted @ 2010-11-15 23:14 关河 阅读(339) 评论(0) 编辑

2010年5月20日

为什么要使用开源测试工具?

作为一个开源测试工具的推崇者,我经常被问到这个问题。许多测试工程师对商业测试工具情有独钟,总觉得商业测试工具既好用又强大,而开源测试工具功 能弱,缺陷多,而且不好用。对开源测试工具的偏见一方面来自于商业测试工具的宣传,另一方面,也来自部分测试工程师在使用开源测试工具过程中的心态。

在本人所在的组织中,公司内使用的绝大多数测试工具或多或少都有开源测试工具的影子,从开源测试工具在本组织的应用中看来,使用开 源测试工具带来的优势非常明显:

  1. 极低的License费用:这个是显而易见的一个优点。设想,如果公司需要对Web应用进行上万并发的性能测试,使用LoadRunner等商业 测试工具的费用绝对不是一个小数字;
  2. 更高的集成度:大多数商业测试工具本身也号称提供了自己的“完整解决方案”,但商业测试工具往往只能覆盖测试中一部分的领域,对于集成测试或是针 对应用的接口测试方面,商业测试工具很难提供企业需要的好的解决方案。这样一来,这部分企业自己建立的自动化测试工具就很难被集成到商业测试工具形成的 “测试框架”中。而采用开源测试工具解决方案的话,这个问题根本就不是问题;
  3. 更适合企业需要:出于商业利益的考虑,商业测试工具总是试图覆盖“最大的用户群体”,因此商业测试工具往往是那种“谁都可以用”,但“在哪里都不 是特别好用”的那一类工具,反之,开源测试工具在这方面具有显然的优势;
  4. 更适合提高企业的测试技术水平:许多开源测试工具中都体现和非常值得学习的测试思想和方法,由于开源本身的特性,这些思想和方法是非常容易通过对 开源测试工具的研究来进行学习和掌握的。

以JMeter这个工具为例,我在许多场合下向测试工程师推荐这个性能测试工具,的确也有一些测试工程师尝试了这个工具,但从他们那里,我得到的反 馈往往是:“为什么这个工具的界面这么难看?”,“为什么这个工具没有xx功能(与商业测试工具相比)?”,“为什么这个工具没有漂亮的文档?”。许多人 在第一印象上便认为,这个工具比不上商业测试工具,然后就弃之如敝屐。实际上真是这样吗?我所在的组织的性能测试几乎完全依赖于JMeter,通过在 JMeter上扩展的图表功能,支持集群等功能,通过少量的代码,JMeter可以生成比商业测试工具更加漂亮,更加有价值的图表,而且,更重要的 是,100%适合我们自己的环境需要。

当然,除了看到开源测试工具的优点,我们也应该看到开源测试工具的不便之处。与商业测试工具相比,开源测试工具在产品的用户交互性,易用性,易学习 性方面显然 不是那么好(当然,在我看来,这方面不是测试工具的重点)。因此,要在组织中使用和引入开源测试工具的话,对组织中的成员,组织环境是有一定的要求的。

就本人的经验而言,许多目前的开源测试工具,例如Mantis、Testlink、JMeter、Selenium/Webdriver、 xUnit等都已经是非常成熟的测试工具,拥有了大量的使用者,也有许多成功的应用实例,本人的实践已经充分证明了这些工具在实际工作中能够带来的收益: 即使只是简单的使用开源测试工具去完成某个特定的任务,或是用来搭建公司内部的测试管理平台,也能从这些工具中受益不少;更何况开源测试工具拥有众多的开 发者,处于不断的完善和提高中,具有良好的扩展性,给你充分修改和改造的自由,从这个角度来说,如果你拥有足够的资源,想要打造属于自己的测试平台,开源 测试工具绝对是一个好的平台。

posted @ 2010-05-20 16:23 关河 阅读(2685) 评论(13) 编辑

2010年1月8日

在第四届软件质量年会上的演讲,标题是”让测试敏捷起来“。

 

下面的链接是InfoQ上的视频和PPT:

让测试敏捷起来

posted @ 2010-01-08 15:59 关河 阅读(1027) 评论(1) 编辑

2009年11月14日

在本系列的第一部分中,我们简要回顾了敏捷开发,以及敏捷测试与传统测试的不同。在第一部分中,我们特别提到,敏捷测试的要点之一就是,不依据于角色而是依据于任务来考虑整个开发过程中的测试。

但是,对一个开发组织来说,组织中一定存在开发工程师和测试工程师的角色划分,作为一个敏捷团队中的测试工程师,他的主要工作职责是什么呢?或者说,他可以在哪些工作上发挥自己的作用呢?

敏捷过程中与测试相关的任务很多,概括说来有如下一些:

  1. 建立不同级别的测试验收标准(也就是test suite),包括单元测试、集成测试、系统测试等各个层面的验收标准;
  2. 推动整个组织的质量文化,保证整个组织的成员在质量责任与目标方面达成一致;
  3. 通过技术或是管理的手段,保证产品、代码具有良好的可测试性;
  4. 通过自动化测试手段缩短每个产品发布周期中测试所需的时间;
  5. 与客户沟通确认客户可接受的软件质量标准,并建立针对此标准的验收测试;
  6. 深入了解应用系统和业务需求,通过探索性测试方法设计有效的测试用例,发现产品中的缺陷;
  7. 建立对整个团队可见的质量度量体系,保证整个团队能够随时看到产品的质量度量值。
这些工作都可以是敏捷团队中测试工程师角色的工作任务,但显然,在现实中,不太可能要求所有这些工作都由测试工程师来承担─同时,让测试工程师承担全部这些工作任务也并不合理,某些工作由开发工程师角色,或是由开发工程师和测试工程师共同承担更为合理。

接下来,我更详细的把列出的这7项工作中非常成“测试工程师必须完成的工作”,“测试工程师需要去推进的工作”,以及“能为项目带来巨大价值的工作”。

  1. 测试工程师必须完成的工作: 
    • 与客户沟通确认客户可接受的软件质量标准,并建立针对此标准的验收测试;
    • 深入了解应用系统和业务需求,通过探索性测试方法设计有效的测试用例,发现产品中的缺陷;
    • 建立系统和用户验收级别的测试验收标准;
    • 通过自动化测试手段缩短每个产品发布周期中测试所需的时间
  2. 测试工程师需要去推进的工作:
    • 推动低层次测试(单元测试和接口级别的测试)的进行。低层次是测试对于需要快速发布的敏捷开发来说至关重要,但在大部分国内的软件组织中,开发测试都需要经过不断的推动才能被最终执行下去,测试工程师具有相关的测试技巧,并且能够用翔实的统计数据表明低层次测试的必要性,是最好的推动低层次测试的人选;
    • 推动整个组织的质量文化,保证整个组织的成员在质量责任与目标方面达成一致。这一点对于敏捷组织来说也是至关重要的;在许多传统的软件开发组织中,经常能看到开发和测试之间的扯皮,针对一个遗漏的缺陷,大家考虑第一件事不是如何去修复,如何去防止,而是首先“追究责任”─在敏捷过程中,需要一个非常不同的环境:也即,质量责任是由所有工程师共同承担的,对于出现的问题,重要的是解决和预防。
  3. 能为项目带来巨大价值的工作
    • 建立对整个团队可见的质量度量体系,保证整个团队能够随时看到产品的质量度量值。保证产品质量度量的可见可以让整个团队清楚的看到我们现在正在工作的产品与我们期望交付的产品在质量上还有多大的差距,这样整个团队可以以质量度量作为指示,集中精力工作在这些差距上,从而可以尽快的发布“可工作”的产品。“验收测试的通过度”,“单元测试的通过率”,“功能完成情况”等等项目都可以是质量度量中的度量项。
    • 通过技术或是管理的手段,保证产品、代码具有良好的可测试性。良好的可测试性对于产品的维护,自动化测试的进行都是非常有利的─我觉得,甚至可以武断的说,如果一个应用系统没有良好的可测试性,就很难期望可以在该项目上设置良好的测试框架。测试工程师一般不参与具体的设计工作和代码实施工作,但测试工程师可以推动开发工程师在设计和实现时尽可能的考虑可测试性设计,另一方面,测试工程师也可以通过测试覆盖率这个质量及时发现应用中可测试性不强的地方,推动开发工程师的改进。
综上,就是我个人认为的敏捷过程中的测试角色必须,应该和可以进行的工作。当然,要完成这些工作,和传统的QA工程师相比,敏捷过程对测试工程师提出了更好的技能上的要求。在我看来,一个敏捷项目中的测试工程师应该具有这样一些技能:

  1. 良好的沟通和协作能力;
  2. 良好的设计和代码能力,至少可以和开发工程师在同一水平上讨论具体的设计和代码实现;
  3. 快速学习和总结的能力(运用探索性测试发现缺陷);
  4. 对自动化测试有深刻的理解(至少要能清楚的认识到自动化测试不等于UI自动化测试,也不等于用自动化测试工具进行录制和回放);
  5. 快速的风险分析和判断能力(在许多情况下都不会有足够的时间开展full regression,如何判断风险和决定相应的对策至关重要)。
==========================分隔线============================

第二部分完结。

第三部分我打算探讨下敏捷测试中的测试过程管理。与传统的软件测试过程不同,敏捷测试过程是一个非常简单的过程模型,我的重点会放在敏捷测试过程管理中的一些实用工具上。

 

另外,可测试性貌似也是一个很好的话题,不知道有没有对这个话题感兴趣的朋友?

 

posted @ 2009-11-14 21:19 关河 阅读(1650) 评论(0) 编辑

2009年11月6日

摘要: Agile testing(敏捷测试)基本上是伴随着敏捷开发的概念成长起来的,但在受关注程度上,远远不及敏捷开发本身。自然,开发队伍从数量和活跃度上来讲大于测试队伍,是其中的一个原因;除了这个原因之外,“敏捷测试究竟如何在项目中发挥作用”这个问题可能也是导致敏捷测试概念的流行度远远不如敏捷开发的原因之一。关于敏捷测试,我能找到的较早的比较系统化的描述文档应该是2002年的这...阅读全文
posted @ 2009-11-06 19:03 关河 阅读(2222) 评论(6) 编辑

2009年6月1日

posted @ 2009-06-01 15:46 关河 阅读(918) 评论(4) 编辑

2009年3月11日

摘要: 4月份到上海出差,有机会的话希望能够和上海的测试同行们见见面:)不知道有没有感兴趣的朋友?我到上海会住在南京路附近。 阅读全文
posted @ 2009-03-11 11:39 关河 阅读(741) 评论(2) 编辑

2008年9月11日

posted @ 2008-09-11 13:59 关河 阅读(1148) 评论(6) 编辑

2008年5月16日

posted @ 2008-05-16 10:29 关河 阅读(707) 评论(2) 编辑

导航

公告

本搜索尽可能收录分散在各处的各大网站、论坛中的灾区寻人信息,希望为我们找寻灾区的亲人提供方便的搜索平台。

共同努力、度过难关!祝愿我们的灾区的乡亲平安无恙!

寻找灾区的亲人
昵称:关河
园龄:5年7个月
粉丝:24
关注:0
<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

统计

搜索

 
 

常用链接

我的标签

随笔分类

随笔档案

朋友们的BLOG

最新评论

阅读排行榜

评论排行榜

推荐排行榜