2013年6月26日星期三

谈软件测试资产的存储

在当今的测试领域,如何存储测试资产是绝对不能轻视的事情。关注以下两个重要因素有助于制定正确的策略:1)避免测试资产存储中几个常见的误区,2)设计能够满足测试团队对测试资产处理的最佳存储过程以及实现有效的工具支持。本文简要阐述了如何做好上述的两个因素。

  大多数成熟的测试团队都会针对存储测试资产的常用需求制定各种策略。这些策略要考虑到测试资产的访问、限制必要的访问人员、以及确保资产不会丢失,还要考虑针对单个特定资产所需的具体存储需求,以证明该资产的存在并保持它的可用。很少有团队能够确保他们的存储方法在操作过程中不会存在任何问题,也很少有团队成功制定出最适合他们自己的高效存储过程。怎么确保在操作存储活动中不面临这类问题,在很大程度上取决于如何去避免几个常见的错误。设计高效的存储过程依赖于团队资产自身的具体需求以及存储这些资产所使用的工具,本文讨论了一些可以帮助实现这一目标的建议。

  误区一:使用测试资产一览表

  测试团队所面临的第一项艰巨的挑战是:让所有人都知道在哪里可以找到哪些资产。大多数团队采取的措施是,为新成员提供一份测试资产文档的一览表。然而,这基本上不是很有效果。有两个原因,第一,通常这种资产列表是一次性形成的并且很少更新,这意味着列表上的内容随着时间的推移越来越不准确;第二,老成员通常不会访问这种列表,因此资产列表会渐渐被遗忘。

  最好的解决方法就是建立并持续维护一个资产地图(根据需要经常更新),有策略地将其放到所有人可以看见的地方,例如:显示在团队门户网站上、粘贴到办公室墙上等。资产地图要能够告诉每个团队成员两件重要的事情:第一,在哪里可以找到与他的角色相关的资产;第二,他应该将他的工作产物存储在哪里。

  误区二:正规的存储方式不是很重要

  无论何时,都不应该使用非正式的方式或者不按照规定的方式来存储测试资产。例如,网络共享文件夹、测试计算机、团队成员正在使用的台式机或笔记本电脑以及其他非正规方式都应避免。这些方式,限制了更广泛且必要的人群访问或使用资产,鼓励了测试过程中信息孤岛的存在。

  误区三:同时使用多种存储工具能够确保测试资产不丢失

  当存在多种方式来存储测试资产时,应只明确规定使用的存储方式(仅选择一种)并强制执行。例如,一份培训手册可以同时存储于版本控制工具和文档共享工具中;当这两个工具都可用时,通常情况下会同时使用两种工具来存储文档。但是,应避免这样做而是明确仅使用一种工具并遵照执行(在这种情况下最好使用文档共享工具)。对一份资产创建多个来源仅仅比丢失资产稍好一些,因为资产的冗余存储很可能会导致错误的副本(过期版本、不完整版本等)。

  误区四:存储的测试资产越多越好

  测试团队不应存储不属于他们的资产。例如,需求、应用程序版本等资产是测试团队所需的,但测试团队并不负责它们的可用性。真正要做的是:通过建立共享过程,使测试团队能够在正确的时间获得正确的资产。另一个类似的错误认识是存储过多的内容。不再使用的测试资产应该存档或者被清除。报告、沟通记录等不需要显式地存储,尤其对于那些很容易从测试管理工具、邮件服务器等地方导出来的资产。测试日志的有效存储期应该限制在使用它们进行分析的时间段内。存储过多的东西可能会引起很多问题,例如:不易查找到重要的资产以及不必要的开支。

  建立最佳存储过程

  存储过程是一个由一系列规则和惯例组成的框架,它通常是由一个团队制定的,并规定了重要的资产应如何存储以及在哪里存储。下表提供了不同测试资产的恰当的存储方式。这些方式都是从业界的最佳实践中收集来的。尽管这些方式有助于测试团队建立可靠的测试资产存储过程,然而建立最佳存储过程并不像表中所讲的那么简单。最佳存储过程并没有统一通用的模式。很多具体细节都决定了一个团队对最佳的定义,如:团队资产所需的存储容量,一定时间段内资产容量的预期增长情况,资产存储所需的工具和使用许可,组织目标和约束等。

  选择适合的测试资产存储工具

  测试资产存储工具的选择应该是尽量从测试团队、项目团队和组织(依照此顺序)中选择已有的工具。有时,尽管利用现有工具并不能实现大幅度的优化,但也不应仅由于存储测试资产的需要而购买工具。构建自定义工具或使用免费软件可能不承担购买费用,但需要考虑到如工作量、培训等间接费用。例如,虽然一套测试管理工具是用于存储测试用例的最佳途径,但不应该仅仅由于存储测试用例的唯一目的而购买一套测试管理工具。相反,使用项目团队的版本控制工具就足够了。在没有其他的策略时,一个最佳的存储过程应满足"方便使用"的原则,即从有利于使用该资产的人员的角度出发。例如,测试管理工具和自动化工具本身提供的版本控制功能都可以用于存储自动化测试的脚本;由于自动化测试人员通常使用自动化工具来工作,因此即使在测试管理工具可用的情况下,也应该选择自动化测试工具来存储测试脚本。

测试资产

存储方式建议

测试活动的项目计划

应与设计、编码等其他项目活动的计划共同存储。应利用内容发布工具...

估算结果

应利用内容共享工具

测试策略/主测试计划/其他测试计划

应利用内容共享工具

工作指南文档、模板和表单、行政表单

这些文档应该可以从公司网站、内网或门户网站下载(维护下载链接)

工具评估报告

应利用内容共享工具

测试用例/测试数据

应利用测试管理工具

测试结果

应利用测试管理工具

缺陷

应利用缺陷管理工具

测试报告

应利用测试管理工具

日志/缺陷调查报告等

日志应明确保存期限,并定期清理。

缺陷调查报告附在缺陷管理工具中相应的缺陷中。

自动化测试脚本

应利用自动化工具提供的存储库或版本控制工具。

自动化功能库(Automation functional library

应利用自动化工具提供的存储库或版本控制工具。

自动执行结果

应利用自动化工具提供的存储库或版本控制工具。

数据库文件、脚本等

应利用版本控制工具,最好与被测应用程序使用同一个版本控制工具。

培训手册

应利用内容共享工具

审计规程/日志和报告

应利用内容共享/发布工具

测试实验室访问和账户申请等表格

应利用内容共享工具




QA测试员需要掌握的新技能:脚本和安全

是时候成为一个QA测试员了。

  这是4月28日至5月3日,在奥兰多市上STAREAST 2013会议上反复听到的一句话。讲演者一个接着一个地敦促测试专业人士接受他们的角色,作为软件生产的关键角色,但也会因为组织的业务而变。

  对此主题的讨论的版本很多,但无论是哪一种,所有讲演者都传达到相同的元信息:质量保证(QA)专业人士需要承担起领导的角色,在对应用进行计划时,而不是只是等待测试需求,这些测试需求并不会对业务制做出好的软件。

  总而言之,这给一群专业人员加深了对新工作的印象,曾经认为此工作只是对漏洞的修复,在软件发布之前找到最后的缺陷。

  但这是现实:随着他们的职业声望的提升,软件测试人员需要一组惊人的技能,来交付他们所要求的所有。他们有这些技能或资源来获得这些吗?

  在STAREAST之前的文章中,我写了关于开发领导力和管理技能方面的文章,从而获得成功。在本期的质量阶段方面,我来看看两个技术技能集合,这两个技能是现在的QA测试人员不能没有的:脚本和安全测试

  测试自动化脚本技能

  虽然没有必要成为成为编程人员的上上等,但所有的测试人员都要学会编写一些代码。原因很简单:自动化测试会一直在那,而使用这些工具需要QA专业人员编写在测试中执行的脚本。

  位于费尔吉尼亚州,费尔法克斯郡的软件咨询公司的CEO Jeff Payne在STAREAST演讲中指出了这点,测试在测试驱动的世界。公司希望雇佣那些会自动化的测试人员,而那些缺乏这种技能的人就不会优先考虑,他说。"所以要学习如何进行脚本测试,"他对听众说。"试一试脚本语言Ruby;但不要走错方向。"

  在设置测试自动化的初期,脚本技能需求特别高。但是不要傻傻地以为一旦编写了第一组脚本后,需求就会消失,软件测试专家Robert Galen说,他是位于北卡罗来纳州,卡里的RGalen咨询集团的一员。有效的测试自动化需要QA专业人士不断地对他们是否做正确的测试集进行评估,而也要评估随着需求的变化,是否有能力编写新脚本,他说。

  了解的关键是:自动化测试并不是一个全或无的命题。这只是QA测试的一个方面。人工测试一直以来也是有需求的,尤其是在进行检查进,如当应用程序产生错误信息时。在STAREAST Lightning Strikes的演讲中,Michael Bolton指出,"即使再大量的测试自动化也需要捕捉错误信息。"

  安全大前景

  还有一个领域是自动化测试帮不上忙的地方就安全。当听到"安全测试"这一词时,都会感到发抖,因为他们害怕他们会被要求深入挖掘应用和分析源代码。

  没有人要求测试专业人士做这些。但是,越来越多的人要求他们承担起安全的责任,而且对于多数软件测试人员,这安全是一个全新的领域。

  "现在安全确实很重要," Payne在他的STAREAST演讲中说。与亲自实现代码的开发人员不同,软件测试人员擅长考虑应用开发从需求到开发的整个流程,这使得他们成为唯一个有资格进行基本安全测试的人,他说。

  "攻击者想要从这个应用中偷走什么数据,他们将会采取怎样的方法来得到那些信息?" Payne说,这是一些关键问题,测试人员需要问一下他们自己。例如,全们应用指导基础的测试,从通过要求应用程序来验证用户输入的所有数据,而确保入口点是安全的。

  在他的演讲中,Payne从来没有建议测试人员应用检查一下安全漏洞方面的代码。但是当我问一个测试员,她对Payne的安全建议有什么想法时,显然,她认为他只是给了建议。"安全测试是一项技术性技能;你必须关注代码——这对软件测试人员是不现实的,"测试管理说,她要求我不要提及她的名字。

  我认为从她的评价中可以看到一个问题,这个问题是许多QA测试人员正在处理的:"我怎么获得我的领域所需的技能?我能做一切别人要求我做的吗?"

  作为一个专业领域,软件测试获得了尊重,这很好。但是软件测试人员是否具有这些技能,形成质的飞跃?他们怎么获得这些技能?



软件测试新技术的进展和应用

  摘要:随着测试技术的发展和测试需求的扩大,自动化测试软件测试中的优势越来越明显。本文通过对文献资料的阅读,介绍了自动化测试框架、自动化测试用例生成技术两种重要的自动化测试研究技术,对其目前的应用现状和实际使用情况进行了分析,提出了软件测试未来的发展趋势。 关键词:软件测试,自动化测试,测试框架,测试用例

  1、引言

  软件测试是软件质量保证的重要手段,通过软件测试可以发现软件缺陷,从而修改缺陷,提高软件的质量水平。软件产品的测试比硬件产品的检测要复杂得多,并且软件产品的测试不能充分利用检测工具,还需依赖测试人员的个人判断,对业务知识的掌握程度以及测试用例的设计能力,知识和经验。 随着计算机技术和软件技术的发展,近年来,软件测试在各个领域发挥着重要的作用。随着软件工程的发展,对系统化的软件测试技术和软件测试方法的研究也随之发展。软件测试从静态分析、动态测试等简单的查错行为发展成为系统化的工程行为。为了提高软件的测试效率,减少人员手工操作的次数,克服由于人员水平造成的测试差异,人们开始研究自动化测试技术。 本文通过对大量软件测试技术相关文献的阅读,分析了自动化测试框架、自动化测试用例生成技术两个软件自动化测试的热点问题,结合目前软件企业使用的测试工具,总结了软件自动化测试技术的应用现状和存在的问题,对未来软件测试技术的发展进行了展望。

  2、自动化测试

  随着软件系统规模的扩大和软件应用领域的不断扩展,软件系统的测试也变更越来越困难,传统的人工测试已无法满足人们的测试需要,虽然自动化测试不能从根本上解决问题,但其技术可以部分解决测试覆盖的问题和测试效率问题。 随着自动化测试技术的不断发展,自动化技术更加注重实用性、有效性和性能的不断提高,自动化软件测试技术同各种传统的人工测试技术相结合,大缩短了测试的时间和测试的开销,自动化测试已成为软件测试技术的重要研究方向。目前,自动化测试技术的主要研究内容包括:测试自动化框架、测试自动化脚本技术、自动化测试用例生成技术、测试自动化的预测、自动测试与可靠性分析、自动化安全测试技术等。

  3、自动化测试框架

  自动化测试框架模型的研究是为了使整个测试过程可以建立在一个框架模型之上,这些过程包括编制测试计划、安排测试活动、实现测试及检查和评估测试结果等。

  3.1 基于程序结构的自动化测试框架

  在文献中,作者提出了一种面向程序结构测试的一体化自动测试框架模型——C-ATFM模型。该模型是基于C语言的面向程序的测试框架,集成了自组织的环境,采用源码嵌入式的测试探针技术,模型包括5个模块。

  1)语法分析器:用于对源程序进行分析,使用了有限自动机对正则表达式所表示的规则进行识别。

  2)策略配置器:根据所要采用的测试方法来设计测试模型对测试活动的支持,使测试模型具有较好的适应性,对自动测试的有效性非常重要。

  3)指令生成器:自动采集和分析程序结构的控制流信息,在测试策略的控制下,针对不同测试策略,计算程序动态测试过程,生成测试处理模块并插入到程序中,构成包含测试信息的被测程序,提交给仿真执行模块运行测试。

  4)测试用例生成器:在自动测试过程中,为了尽量减少人工的介入,输入处理被实现为一个独立的模块,在需要时被调用,以模拟人工输入,为程序提供必要的输入数据。测试用例的自动生成技术也是自动化测试的一个重要的研究方向,将在后面的文章中进行介绍。

  5)指令仿真执行器:提供测试框架内部的仿真执行环境。

  以上测试框架是基于程序结构的测试方法,即主要被用于白盒测试过程中。

  3.2 基于类的测试模型

  面向对象的软件程序开发方法的出现,使软件测试者从传统的基于过程的测试转向基于类的测试。类的封装机制限制了对象对外部的可见性和外部以其的操作权限,而类的继承机制增加了软件测试的复杂性,多态和动态绑定为程序的执行带来了不确定性。由于以上问题的出现,人们开始讨论面向对象的软件测试模型。文献中给出了一种基于EDPN的类测试模型,作者基于面向对象软件测试的层次划分、测试方法,讨论了从UML图到EDPN图的转换,提出了一种基于EDPN的有标记的唯一输入输出测试用例的生成方式,并设计了基于EDPN模型的类测试模型。该模型可以通过唯一输入输出测试类的状态及状态转移;通过优化正交阵列测试类的交互;还可以通过生成协同路径方法测试类的层次。

  4、自动化测试用例生成技术

  测试用例可以定义为:①为了特定目标而设计的一组测试输入,执行条件和期望的输出结果;②为某一测试项记录的特定的输入、预测结果和一组执行条件。 软件测试用例生成是软件测试的核心问题,如何选择较好的测试准则,对提高测试用例发现软件错误的效率具有重要意义。

  4.1 测试用例生成技术

  软件工程技术对软件测试研究的影响表现在三个方面:软件开发过程模型决定了软件测试过程模型,软件体系结构决定了软件测试的层次划分,软件模型决定了软件测试用例生成方法。文献中提出了基于模型比较的测试方法,该方法将软件需求和软件实现转换为基准模型,通过比较得到需求模型和实现模型的差异,生成测试用例。文中采用了基于等价类的基于模型比较的测试方法和基于扩展有限状态机的基于模型比较的测试方法,并对两种方法进行了对比和分析。文献中针对不同的测试策略,设计了不同的测试用例自动生成的方法,其方法的设计和实现是基于程序规则说明的决策表技术。文中作者在其设计的自动化测试框架模型下,研究了基于程序规则说明的自动化测试技术,文中,作者采用了人工智能领域的问题求解方式,基于遗传算法的测试用例自动化生成技术和基于启发式学习的测试用例自动生成技术。文献的作者在给出基于EDPN的测试模型后,提出了一种基于带权EDPN迭代的面向对象系统的分割算法,以迭代的方法将面向对象系统分割成不同粒度而功能独立的测试子系统,并提出了基于组合EDPN模型的交互测试方法,解决了组合冲突和测试用例过多等问题。

  4.2 测试用例集约简技术

  测试用例集约简技术是生成最小测试用例集,最大限度地对软件进行高效率的测试,降低软件测试成本的关键技术之一。测试用例集约简技术也是今年来人们普遍重视和深入研究的话题。

  早在1974年,文献的作者就提出了用于简化测试用例集的贪心算法。随着测试用例集约简技术的发展,文献提出一种根据测试用例的重要性来选择测试用例的启发式算法(H算法)。文献结合了贪心算法和启发式算法的借点为,提出了充分考虑剔除1-1冗余策略的简化方法。文献提出的测试用例选择方法把测试用例选择问题转化为整数规划问题,利用整数规划方法求出最优解。以上四种方法是测试用例集约简技术中的几种经典算法,目前,很多新的测试用例集约简算法都是对以上几种算法的改进和完善。如文献通过对传统的测试用例集约简技术的分析对比,提出了一种可在测试用例集简化期间,通过有选择性地保留测试用例来生成测试用例集的最小测试用例集生成方法。文献的算法允许保留在某个测试标准下的冗余,但在其他测试标准下不冗余的测试用例。文献则提出首先消除测试需求中存在的冗余,再对由该测试需求生成的测试用例集使用简化算法,得到无冗余的测试用例集。文献中,作者分别针对组合测试的最小测试集生成技术和基于测试需求集的测试用例集约简方法两个方面进行了系统深入的研究。文中,作者在系统地研究两两组合测试用例集的启发式生成方法基础上,对其进行有效改善和补充,提出了基于网络图模型和基于解空间树模型的两种新的测试用例集生成算法。另外,作者在系统研究多次单因素试验方法、均匀设计方法、正交试验设计方法等理论和应用的基础上,提出了软件测试的单因素覆盖方法、多因素覆盖方法等概念和相应测试用例生成方法。最后,作者给出了对软件系统进行全面测试的最小测试用例集生成框架,该框架可以有效地生成、管理、约简、分析和评估对软件系统进行全面测试的最小测试用例集。在文献中,所提出的软件测试用例生成技术也是运用正交试验设计法,应将其应用于一个简易的管理信息。

  5、现状与展望

  随着软件工程及软件测试行业的发展,软件测试更多的从手工测试转向自动化的机器测试,这样可以大大提高测试的效率,使人从反复枯燥的工作中解放出来。目前,大量测试工具的出现,使软件测试工作变得更加方便高效,但由于测试工具的使用对技术的要求不高,如自动化测试工具QTC已被测试人员广泛使用,LoadRunner更是压力测试离不开的工具,因此,对于这些工具内在所包含的技术却被测试人员忽视,测试人员更多的是根据测试需求去选择需要的工具,而对工具的具体实现方式知之甚少。而对于测试工具的开发者来说,自动化测试框架和自动化测试用例生成技术已成为自动化测试技术的两大关键研究方向。在这些测试工具中,不乏上文中介绍的各种技术的应用。例如用于C\C++语言单元测试的C++ Test,利用源代码扫描技术来提高代码质量的Klocwork等工具都具有与文献提出的测试框架类似的测试框架,这些工具直接访问被测试应用程序的代码,对其中的语句进行分析,输入各种测试数据,检查返回值,比较返回值与预期结果是否一致等。当然,所有自动化测试工具执行测试的过程中都需要生成测试用例,本文引用的所有文献中都给出了测试用例的生成方法。在我们使用工具进行测试的时候,测试用例已经被淡化,自动的测试过程中集成了所使用的测试用例,而我们在对结果进行分析时,可以查看到被执行的测试用例和测试用例的覆盖情况。这些测试工具使用了各种各样的自动化测试用例生成算法,为了提高工具的执行效率,测试用例集约简技术在工具设计过程中也是必需要考虑的内容。以我公司为例,公司没有专职的软件测试人员,软件测试工作由开发人员、事业部测试人员、公司测试人员三步完成。而事业部测试人员和公司测试人员大多是一人负责多个项目的测试,由于测试时间紧、任务重,而项目的复用情况也多,完全可以使用自动化测试技术进行测试。目前,我公司的测试用例是通过测试管理工具QC进行管理,其中存在大量冗余的测试用例,会造成重复测试,如果可以使用测试用例集约简技术对已有的测试用例集进行整理,可以大大提高测试效率,但由于现有的测试工具无法提供通用的自动化测试用例约简功能,或其功能不适用,迫使我们无法将这些技术直接应用于软件测试工作中。

  软件质量越来越被人们重视,测试驱动的开发技术被人们所接受,软件测试已不再简单的是软件生命周期中的一部分。随着技术的发展,测试技术将被更多的应用于项目开发之中,而未来的软件开发更多的是以测试为目的的开发,通过工具的自动化测试功能,保证开发人员的代码质量和整个系统的质量。当然,自动化测试无法替代人工测试,但自动化测试可以帮助测试人员更快更好的完成工作,而对于测试人员,可能更多的是需要考虑如何持



2013年5月30日星期四

开发和测试的六道轮回

 2012年是移动互联网年,我学习了Object C的开发,开发了较多的功能和内容,对于开发的过程和开发后的质量,以及开发自测有了新的认识。此前一直站在测试的角度去思考开发如何做测试,如何自测,如何共同保证测试。当时觉得不是很有难度,应该可以这样做,应该可以做到什么程度。现在对这个问题有了一些新的看法,作为个人的体会和感受,希望与各位讨论。

  若隐若现

  记得毕业后,我和隔壁班同学一起分到了HW公司的某产品部门,我在测试部门,他在开发部门。刚开始的半年,我学习了业务、数据库操作系统、测试工具、测试流程和管理。半年后,我继续学习测试相关的资料,感到了一些迷茫,在HW是封闭式的环境,接触不到外面的世界,我觉得测试学得差不多了,看到同学每天写代码到很晚才下班,貌似学到了很多东西,成就感明显大于我。

  于是,我开始偷偷地拿出来自己带的C++教科书,慢慢学习C++代码,当时我没有自己的电脑,使用公司的电脑学习C++,为的是不让自己忘记C/C++的语法和基本代码,没有完整的学习规划,再加上HW公司的确工作忙,只能慢慢地学习,效果非常不好,基本上自学的代码量不超过百行。开发能力和刚毕业时有了较大的下降,但是也没有太多的危机意识,觉得自己学到了很多测试方面和OS和DB的知识,在外面能有用武之地。

  顺藤摸瓜

  在HW工作一年后,我去了A公司。相对来说,A公司的工作压力要小很多,也接触到了外面的世界,除了学习更多测试相关的知识以外,仍然没有放弃学习和编写代码。由于接触的产品是C#编写的,需要重新学习C#的语法和基础代码。由于时间较充裕,加上和开发人员关系和谐,自己可以动手编写测试工具和相关的工具。清楚的记得自己为了锻炼编写C#的代码,写一个计算器程序,代码量上千行,对于自己开发的计算器程序有种莫名其妙的成就感,体会到了一些编写代码的乐趣;后来乘胜追击编写了一个简单的写代码的Edit工具,有点类似于UltraEdit。

  也就是那个时候,发现自己编写的代码越多,隐藏的bug越多;发现修复了一个bug外,还产生了好几个bug。也许是自己的编写代码能力有限,清楚地理解了编程不是那么简单的事情。做出来的工具得到了开发以及开发主管的认可,感觉自己有编程方面的潜力,感觉不错,有些许的成就感,也曾想转岗做开发吧,但是一直没有下定决心。

  我的开发能力得到了展现,希望尽量应用到测试工作上,当时我在SE Team,专门为产品上线后提供后续服务,对于技术支持人员报告的bug,我负责重现和 验证,时间上较宽松。在重现bug后,我都要调试代码,查看问题出现在哪里,有时候找到出现错误的原因,并给出简单的修改建议,开发人员在修复bug时,大致了解我对于该bug修复的注释。

  随着时间和实践的增多,后来我不仅通过调试代码找到引起bug的根本原因,还会给出详细的修改缺陷的解决办法或变通方法,给出详细的原代码和新代码,同样也会验证结果。得到了开发的极大认可,我的成就感有了很大的提高,但是仍感觉和开发人员相比比较,我调试代码的能力较弱,投入调试的时间有限。从结果上来看,自己不仅仅保持了一定的代码编程能力,还可以将开发和测试的关系以及应用过程了解得更深入,相应地持续提高编码能力。当时也编写了基本的自动化测试代码,由于测试框架封装的较好,测试代码基本上没有太多含金量,这些工作不仅仅是了解这个代码规范,还详细了解了测试框架的架构以及基本实现方式,为后续接触不同的测试框架打下了基础。

  东山再起

  来到淘宝,我对测试能力保持充分信心。当时淘宝还是页面自动化的初始阶段,我结合以前对测试框架的架构的理解进行内部交流,为淘宝的测试框架的改进带来了一些新的架构思路,比如Page Model和DB Model。此时的编程语言变成了Ruby,只好尽快学习Ruby编写自动化测试代码,接着为了编写接口测试代码,马上学习Java,2010上半年我的开发能力还停留在自动化测试代码阶段。后来部门实施技术产品化的策略,将测试技术转换到产品中来,必须学会开发产品,所以当时参与了Web应用开发,开发公共用例中心(CTC),从而了解到了更多开发方面的知识。中间件、Spring、iBatis等等,在Java开发方面有了更多的进步,但个人认为还是皮毛阶段。

  2011部门开始提倡测试具有定位bug的能力,在几个项目测试过程中,在时间充裕的情况下也会调试代码,从而找到引起bug的根本原因。但这个要求在互联网的项目流程中实施起来较难,因为测试阶段本身的时间非常有限,还要花费较多时间调试代码,有些得不偿失。开发人员和项目经理(PM)也未必真正认可,因为在测试阶段会给项目带来进度上的风险。但是这个过程,对于测试人员提高前端开发和Java开发方面的技术知识有较大的帮助。

  我的个人体会是,测试人员不是一直处在编写代码的时间轴上,测试人员的开发能力随着时间的推移,下降很快,重新捡起来,需要花费较长时间。当时我在编写前端代码和Web service的Java代码时,投入了很多精力,咨询了很多同事,总算搞定了。但是3个月后(期间未做任何开发相关的工作),重新开发类似的工具或功能,还是需要花费较多的精力,感觉非常痛苦,真想转做开发岗位了。

  知己知彼

  2012年,部门开始强调开发自测,很多部门开始进行直接的开发测试比的考核和价值考察。我对这种做法一直持保守态度,可能和个人的经历有关,也可能和被测产品有关。对于互联网产品来说,需要做很多测试工作,完善被测产品的质量和用户体验。

  刚开始我的策略较为简单,将测试设计共享和传承到开发人员,开发人员能接受多少,就可以一定程度上避免某些bug,从而在进度和提交测试质量上保持良好的平衡。开发人员还是比较喜欢这种方式的,但是开发人员很少真正将异常测试场景自测下去。经过几个项目的试点,发现效果较差,原因肯定有多个,大家也会猜到一些。

  接下来强化单元测试,一方面开发人员提高单元测试的覆盖率,另一方面测试协助单元测试,但是这其中有很多瓜葛,特别对于上层Web应用来说,开发人员的压力较大,提测(开发人员完成开发和自测后,进行提交给测试团队的时间点)压力也较大,从而一定程度上影响单元测试的覆盖率和持续集成,再加上测试人员的Java理解代码能力不高,短时间内也无法做到较好的单元测试。只能测试人员慢慢地提高Java代码理解能力,导致测试进度缓慢,很多事情开发和测试都是心有余而力不足。当然,开发自测还有很多其他的策略和方式,不是本文讨论的重点。

  2012年,开始无线移动开发和测试,我希望把握工作机会,开始了iOS开发之旅,重新学习Object C语言,重新学习新的开发方式,坚持了一段时间后,自己对于iOS开发有了一些感觉。总体上来说,iOS开发比其他的开发更有成就感,因为开发出来的APP看得见摸得着,容易看到成果。刚开始加入产品的开发团队时,将测试设计的大部分时间用来开发产品的某个功能,感觉比较痛苦,我花了3天才开发出来的功能页面,一个刚毕业不久的开发人员只花了一天就搞定了。我当时的痛苦只能自我感受,必须持续坚持下去。为了尽快熟悉iOS开发技术,我多此请教开发人员。后来开发了tBug,从使用Storyboard到丢弃它,写了更多的代码,看着自己开发的APP,成就感真的比发现bug要强烈多了。

  通过在iOS上积累开发经验,这让我更多地理解了开发人员,更多亲自感受开发人员的心态和对于测试的态度,大致包括几个方面。

  (1)使用快速迭代时,对于某个功能需求,开发人员编写代码时绝大部分考虑正常流程,较少考虑到异常流程,很多精力是放在如何实现功能,而不是思考用户会在多种场景下,如何使用这个功能(此任务需要测试人员投入很多时间思考)。

  (2)开发人员在修复一个bug后,存在一定的思维惯性,只能验证这个bug是否修复,没有较多的时间测试相关的功能流程,而测试人员会发现该bug修复后引出的新的bug。我针对Bug调试代码后,很快找到引起bug的原因,很快的修改了bug,较少思考修复的方案是否会带来新的bug。在修复一个bug时,开发人员往往有多种方案去解决这个bug,但是不同的方案会带来不同的结果,有些方案会引发一些新的bug,有些不会。所以我也经常建议测试人员不仅仅要验证bug,更要思考bug的解决方案,思考这个方案会带来什么影响,从而探索式的使用更多的测试场景去测试它。

  (3)开发过程中,考虑如何去测试它,难度不小。有人会说,使用"测试驱动开发(TDD)"方式,开发之前,先把测试用例写好。这个方式的确很好,但是对于测试经验较多的人而言,可以这么去做,但是开发人员还是需要耗费较多时间思考如何实现,而不是如何测试它(这就是测试人员与开啊人员思维的差别)。所以测试人员强迫自己写完代码后,多去测试它以及周围相关的功能。真正体会持续集成的作用,虽然没有发现bug,但是对产品的质量提供了充分的信心。

  (4)开发人员可以发现很多测试人员都发现不了的bug,然后"悄悄地"修复bug。2011年我经常和开发人员沟通,开发人员说他们发现了好多个bug,已经修复了,测试人员是不会发现的。我当时无法理解这个事情,现在我总算能明白一些了,开发人员在修复bug时或编写相关功能的代码时,会发现某些问题,然后修复掉,而测试人员完全不知道,很多时候也不会去测试这些场景。举个例子,APP登陆分为第一次登陆和后续登陆的逻辑区分和判断(包括读写cache和客户端数据库),假设第一次登陆出现错误的结果,测试人员报告bug。开发人员修复bug时修改了相关的代码,从而引发该业务逻辑的错误,测试人员的大部分测试都不是第一次登陆看到的结果,测试人员很难想象第一次初始化会出现问题。假设测试人员想到这个场景,需要重新登陆、甚至需要重新安装APP、重新初始化,这些过程都是很麻烦的过程,测试人员不一定有坚定的信念完成这些操作。如果他知道如何实现功能的代码,调试相关if else代码,进行逻辑的修改,从而可以在白盒层面测试到自己需要测试的部分。

  (5)开发人员需要了解的知识面远大于测试人员。完成一个任务,开发需要实现这个功能,需要付出很多精力。对于测试来说,完善的测试设计和测试执行,可能需要了解业务逻辑层面,而不是技术层面(如果在白盒层面进行更多的测试,情况会不一样)。总体时间是固定的,开发人员将在实现功能上耗费更多精力,响应减弱在自测上的投入。而测试人员刚好相反,测试人员会投入更多的精力去分析功能的异常逻辑是什么、用户的正常使用路径和异常使用路径是什么、用户体验上是否有改善的地方、开发会如何设计这个功能、会存在什么样的风险和问题等等。希望开发也会用一些时间思考测试人员如何测试程序,这样或许能帮助提高自测的质量。

  六道轮回

  上面讨论了个人做开发期间的一些感受,希望真正的站在开发的角度去理解测试,从而更好的从测试角度去测试产品、提高开发的质量。我需要解释这篇文章标题的含义了。我在2009年问过一位在微软总部工作的测试开发工程师,微软的测试最大的核心价值观是什么。他毫不犹豫的告诉我:开发就是测试、测试就是开发。

  对此观点,我现在明白了一些了,表面上不同的岗位,不同的职责,大家的目的和目标是一致的。开发的过程中,开发人员思考如何测试产品,就是更好的开发产品。测试人员更好的思考如何开发产品,也就是更好的测试产品。开发久了,不得不思考测试的重要性,不得不提高代码的质量(其实你就是在做测试)。测试久了,不得不思考开发的重要性,不得不去发现更多更好的bug、不得不设法提高代码的质量,从而提高整个项目的流程和进度,同样也是减轻自己的痛苦(其实你就是在做开发)。

  开发和测试,都有脱离不掉的责任和目标,为此,开发和测试人员都需要换位思考自己、思考对方。我相信未来开发和测试会有更好的机制理解对方、制约对方、依赖对方、完善对方、改变对方。开发人员不再看不起测试人烟、测试人员不再自我感到彷徨,大家在六道中享受轮回带来的乐趣和成长。



工具类App困局:变现之路崎岖

  从2012年开始,移动互联网就进入了"降温"通道。这种"降温",其实并非是玩家退出盘子缩小,而是产业格局的整体变化。在资本力量的引导与推动 下,优势资源开始朝着有明确商业前途的应用汇集,而未能在这个窗口期寻求到明确商业模式的应用,如果没有足够投资可供延续,则会黯然退场。

  显然,游戏、电商应用(包括O2O类应用)、儿童应用和垄断性质的重应用App都有明确的商业模式。而在这四个群体之外,还存在着大量的大众工具类应用。粗略划分,这些工具类应用大体上可归为网络与终端工具、生活信息、生活记录、社交与多媒体等类别。它们显然具有用户价值,但在商业化的道路上往往被其他应用甩在后面。

  对于这些起步并不算晚的工具App来说,时至2013年仍然存在的它们显然可能面临着相同的困境——比如盈利时间尚不可测;却也会迎来不同的机遇——比如相同定位的新竞争者出现的概率已经很小。工具类应用正处在一个十字路口。

  然而,这究竟是长跑的最后一公里,还是永无止境的不归路?通过对这些应用的观察与分析,也许能够彰显出移动互联网更本质的一些东西。

  门槛

  工具类App应用所面临的共同局面是:开发门槛相对较低和竞争对手众多两个不利局面。然而,这些应用能够留存到现在,已经说明了其具备可观的用户价值。

  以Camera360应用为例,这款2010年6月诞生的App,是比Instagram还要早的拍照类app 之一,并且在2012年初就拥有了3000万用户。Camera360的用户数量在很长时间内都与Instagram的用户数量相当。截止到2012年上半年,Camera360已经拿到了三轮融资,这在当时拿到第二轮融资都屈指可数的中国开发者团队里面,的确是凤毛麟角。

  然而,Instagram在去年被Facebook收购,可谓是给了Camera360以及同类App一个有喜有忧的暗示。喜的是 Instagram的被收购价格在一定程度上证明了自己的价值;忧的是Instagram放弃了独立探索盈利之路,这对它们这些曾经目标远大、现在用户仍旧可观的拍照App无疑是一种与理想渐行渐远的暗示。

  3G门户总裁张向东对《商业价值》表示,在他看来,一款大众工具类App若想实现商业模式,必须经历几个门槛:第一道是拥有大量用户;第二道是拥有良好的产品体验;第三道是满足用户个性化需求;第四道是能使用户长时间停留。

  按照这个逻辑,显然,Camera360已经迈过了前两道槛,第三道也基本迈过,但在第四道前面被卡住了——拍照类应用没有长时间留住用户的基因。

  在这方面,似乎3G门户的Go桌面系列比Camera360更前进了一步。Go桌面App一直是3G门户在海外广受好评的产品,2009年将Go桌面剥离出产品群独立运营,并于去年12月在Google Play上线了价格为15.99美元的高端3D桌面App——Next Launcher系列。仅用两周,Next Launcher就登上Google Play应用商店个性化分类"创收最高"榜首位置,销售收入突破100万元人民币。这应该说是Go桌面应用商业化的里程碑。

  对于Go桌面为何能跨越最后一道门槛,张向东的解释是,桌面应用是相对比较底层的应用,容易长时间吸引住用户。

  然而,像Next Launcher这样能够直接下载收费的app必然是少数,并且收费前提还是在海外市场。对于大部分大众工具App来说,不能直接迈过第四个门槛,靠流量变现的模式探索盈利可能仍是一个必选动作。

  出路

  流量变现这条路按照PC互联网的视角,看上去很美,然而却充满艰辛。众所周知,在移动互联网爆发之后,移动广告却没有跟上整个行业的步伐。流量变现这一种原本应该是互联网最基本的商业模式,竟然在移动互联网上失灵了。

  于是,从充满期待到失望悲观,诸多开发者都在等待PC上面那些挥金似土的广告主的给养,以摆脱仅靠手游广告和巨头应用广告惨淡经营的局面。这就必然要求这些大众工具类app在保证迈过前三个门槛的同时,还要等待姗姗来迟的广告主。

  在塞班时代就开始创业的墨迹天气,是国内创业最早也是最知名的天气类App。其目前已经拥有了1.2亿用户,日活跃用户在千万级别。2012年 年末,墨迹天气开始试水品牌广告。比如其专门设置了紫外线指数,并给出该指数下的饮料推荐;又在iOS 2.8版本中由身着品牌服装的姚晨、阮经天等明星给出用户穿衣提示。

 虽然已经取得了些商业收入,但墨迹天气的创始人金犁对《商业价值》表示,要想继续生存下去,在产品在驻留时间方面有短板的前提下,必须通过社交功能加强用户粘性,进而曲线实现张向东说的长时间停留。比如,墨迹天气正在通过"时景拍照功能"打造摄影师社区,并且与微信对接,增加了朋友圈分享功能。

  既然没有盈利,金犁并没有允许墨迹天气在市场推广方面进行大量支出,而是吸收了1月份登陆湖南卫视《天天向上》后用户激增的经验,采取品牌化推广的路子。其在不久前刚刚与青海电视台合拍了一个公益节目。

  与墨迹天气一同登陆《天天向上》的还有Camera360应用。实际上,Camera360的境遇与墨迹天气十分相像。两者采取的都是通过加强社交功能曲线延长用户驻留时间的办法,也都打算通过品牌运作减少渠道推广的支出。

  与Camera360、墨迹天气和Go桌面都不同,知名记账App随手记采取的是另外一套生存策略。随手记上线也很早,但拥有5000多万用户的它同样因商业模式问题苦苦探索了好一阵子。

  2012年,随手网旗下的第二款产品——卡牛上线,这款信用卡消费实时通知App,与随手记形成了搭配关系,并且可以整合双方数据来记账。随手 网创始人谷风向《商业价值》介绍,由于记账类应用无法社交化,那么随手记等产品只能选择面向企业去运作,以增加黏性。例如,成为银行理财产品的推荐渠道或 者与银行联合发卡。这是随手记系列产品今后的基本商业模式。当然,随后记也没有放弃改善产品体验,例如随手记9中就开辟了旅游、装修与结婚事宜垂直记账表 格。

  2011年随手记的市场推广费用只用了18万元,现在则因找到了商业模式,每个月的推广费用都超过了这个数。

  值得一提的是,这些拥有大量用户的大众工具类App ,绝不会被归零。像Instagram被收购那样实现与巨头的耦合价值成为了它们保底的选择。实际上Camera360、美图秀秀、陌陌等知名大众工具App都已经与巨头联姻。

  总之,由于门槛低却想象空间大,加之流量变现有待时日,致使大众工具类App仍旧处在一个前途不太清晰的探索阶段。

  但因为它们有着巨大的用户价值,所以各开发者已经有了比较明确的产品定位和方法论。只不过,它们各自的成长道路却往往相差很大。

  谷风认为,现在很像PC互联网的2002年,每一款大众App的最终市场饱和量就是2~3家,这是一致的。而且即使最后被收购,那也是一种成功。

  "MSN最后也被QQ干掉了,谁能挺过恶性竞争谁就是赢家。这就是互联网。"谷风说。



为什么测试在敏捷项目中重要


前段时间发布了《QA部门将会消亡》一文。

  本文是一位测试专家对该文做出的回应。

  就如同已经灭亡的皇室(国王已经消逝了,但是皇后却将永存),我们的软件开发正传递着类似的呼声:"测试已死,我们再也不需要测试人员了!"但随之你会发现,哎呀,客户不满意,最后又回到"测试万岁",但这次是更好,更完整,更有效的测试。就如同历史上众多的复辟王朝(我最喜欢皇后伊丽莎白1世)一样,测试将强有力地帮助重新定义事物完成的方式以及它们的工作原理。

  我打赌你现在正在想这不过是自我吹嘘而已,但是,事情是这样发生的:

  让我们讨论一下测试的概念:什么是测试?测试就是考虑什么是"对的"的一个流程,定义方法以判断所测试的事物是否是"对的",确定度量以明确"对的"是什么样子,理解"对的"的等级对团队其他人的任务和活动意味着什么,还有协助团队根据有用的信息做出好决策从而满足"对的"所必须的等级。

  测试远不止随机敲击键盘以期找出问题这么简单;测试需要真正地理解所要求的解决方案,参与交付产品所采用的方法计划,了解交付方法所含的风险,同时还要尽早发现这些风险以便采取合适的补救措施。测试还需要驱动项目往成功的方向发展,并且帮助每个人理解成功所要求的合适水平。

  为什么我们还需要关注测试呢,敏捷团队中的每个人不都在做测试吗?事实上并非如此。

  所有的争议都是从质量的概念开始的。可能你会对自己说:"这简单。"如果你确实是这么想的,那就把它推到下一步…定义它。让你的开发团队、客户、产品所有者、项目经理以及组织中的首席信息官和首席执行官定义质量,要好好地定义,定义到足够好的程度。他们会同意吗?如果不同意,那这就是你的第一个问题。测试的任务就是帮助团队定义和理解质量所带来的影响。

  "质量的影响??这是什么?"这是你的下一个问题。事实上:质量是需要成本的!更糟糕的是:真正的高质量需要更高的成本!想真正建立质量,我们首先必须定义它,然后需要找到它。如果没有将质量建立到流程和技术中,没有将完整的各个级别的测试构建到我们的工作中,就不可能实现质量解决方案。

  "啊,总算逮住你了"开发人员说道,"我们在敏捷中通过定义"完成"来明确质量"。"垃圾!"是我的答复。在我从事IT的所有时间里我听过最让人兴奋的概念就是定义"完成"—所有的组件,集中所有的知识,传递所有的信息……将解决方案的复杂性预先定义,所有的团队(开发和客户团队)都知晓所需要完成的任务以达到"完成"。定义"完成"让我想起了测试相关的一切。但是坏消息是我们并没有这么做!是的,我们没有这么做!就像我们不定义质量一样……我们只是假装我们定义了而已。哇~, 是否刺到你的痛处了?

  为什么我这么说呢?首先,定义"完成"就如同定义质量一样,非常难。因为质量就像"美丽"一样,它是一个仁者见仁,智者见智的问题。测试的内容包括接受培训从而关注质量的定义,紧接着是对质量的探索(或者是质量缺陷),还有就是沟通在项目过程中依据进程、风险和剩余工作明确质量等级意味着什么。对于"完成"的定义也是如此,对于每个"执行者"(非旁观者)而言"完成"是不一样的,这允许我们理解"完成"的多个层次……我的完成,我们的完成,故事的完成,迭代的完成,特性的完成,发布的完成,产品的完成,项目的完成。

  "这个没有关系,我们可以在其完成时再定义。"这是你对这个问题的机智回答。现在真正的挑战来了!定义"完成"与定义"很好地完成"是完全不一样的。"很好地完成"中的"很好"不仅仅是要完成目前产品中所要求的工作,还要明确我们如何知晓它达到了被要求的标准。每个层次的"完成"都有不同的完成标准,以及一个非常不同的"很好"的质量标准。团队中就有一群人不仅非常适合于协助定义"很好地完成",同时还可以协助定义用于寻找"干得好"等级的流程和技术。

  步骤一,定义"完成"…嗯,这看起来很简单嘛——保证执行者按照"完成"的等级完成所有需要交付的组件。好吧,目前为止听起来还不错。但是紧接着难点就来了…如果客户不满意,那么任何事情都不算"完成"。这就是敏捷宣言的基本属性之一。我引用了"可工作的软件胜过面面俱到的文档"这句话。因为一些不为人知的原因,人们往往会混淆"可工作"的定义与"完成"的定义,同时还会混淆"面面俱到的文档"这一概念与"良好测试"的定义。然后这就违背了原则"我们的最高目标是通过尽早持续地交付有价值的软件使客户满意"。那么是什么使软件具有价值呢?是不是交付产品?当然不是!而是该软件能很好地完成它所要完成的工作!!那么这算是我的"完成",我们的"完成",还是什么的"完成"呢……?

  我们该如何去做呢?首先,我们需要认识到测试不仅仅是考虑开发和用户所关注的功能。功能要实现什么是非常简单的部分(简直就是轻而易举——我发誓)。功能很容易定义、构建和评估。功能倾向于二进制,类似"完成"与否的!"完成"有两个等级……"完成"和"未完成"……没有什么"几乎完成"这类说法。功能类似于煮食物……只有能与不能工作之说……二进制!但接着我们就进入了"完成"和随后的"很好地完成"领域,甚至更进一步的"为谁很好地完成?"。

  测试关注于理解什么能使一个解决方案或方法对于使用它的人有价值。价值是上下文独立的,并且必须在项目和客户的上下文内定义。使用类似ISO9126之类的标准,根据它的6个质量特征(功能性,可靠性,实用性,有效性,可维护性和便携性)及其子特性,可以激发测试人员针对什么是好的、恰当的、有价值的这些问题进行讨论。但是更好的是我们需要真正的测试来找出这些价值。这类测试同样也需要时间和计划来很好地执行,如果想做得更好地的话,就需要更长的时间。

 一个解决方案中的所有非功能特性都是设计层特性,并且通常不能在迭代中演变。需要预先对其进行讨论,而且需要在解决方案确定时尽快讨论,是的……在解决方案设计确定时尽快讨论。如果这些特性在最开始没有被正确嵌入的话,那么它们最终永远都不会在测试中被找到。单元测试能做这些吗?当然不能!

  "噢~~~,这就是为什么我们做验收测试驱动开发啊!"你说。我同意,但是我们往往并没有将ATDD做好,我们只关注客户所知道和所问的内容,而没有关注前期需要考虑和捕获的内容。

  "那我们就只关注功能吧。"这是我经常听到的一句话,往往让我感到厌烦……这意味着很难想到其他的事情,我们只好继续前行,并祈祷它是对的。你是否"曾经"听过"忽略"敏捷呢?敏捷就是要从一开始就把事情做对。

  测试通过静态测试从一开始就协助建立正确的解决方案。静态测试是"不通过执行代码来测试解决方案"。静态测试之美在于它可以在任何时间和任何地点执行。静态测试应该在解决方案的第一个想法产生时执行。理想情况下,应该有个测试人员提出这样的问题:"这是功能不错……但你是如何确定它是有价值的呢?"通过问题,图表和该解决方案的计划来测试该概念以查看它是否真正交付了所需要的解决方案,这是产品生命中至关重要的一部分。

  我们还可以测试交付计划,关注风险、时间以及各组件间的依赖,以及如何利用不同等级的"完成"来证明我们正在往正确的解决方案行进。往"很好地完成"的方向上定义"完成"需要正确的人在工作初期就参与进来,而不是在编码已经开始之后。测试计划是至关重要的——是否定义了正确的环境、团队、资源和方法来交付价值?这是一个问题,但往往并没有在编码前得到回答。这个奇妙的新测试制度的存在引发了这个问题,并且所有人都在前往下一步之前就把它回答了。

  测试计划的完成可以通过使用测试设计技术预先定义接受标准。你可能会喊道:"什么???已经开始测试了???"是的,完全正确。如果不提前执行的话,那测试人员获取的那些培训和证书又有什么意义呢?你看到测试人员所做的大部分测试执行活动都是他们基于风险和测试设计技术规范而形成的测试设计活动的结果。概念、特性、长篇故事和用户实例其实都只是规范在不同名字下的转译。更好地,在理想的敏捷世界里,测试人员会参与到需求定义中,这样他们就能够静态测试它们,然后可以在任何人试图实现一行代码前对其应用动态技术。

  接下来,我们开始真正的工作(轻笑……任何人如果觉得编码前的工作不是工作的话,那他并没有理解工作的概念),我们开始编码,做单元测试,改进代码,做集成测试,将代码发布到测试环境(咚,咚,咚……鼓声响起)……我们开始尽全力寻找紧急行为!

  紧急行为——这是测试人员在敏捷队伍中的真正价值:关注模块、代码和用户故事如何结合在一起从而交付所需要的功能。但是我们都知道这些地方往往是那些重要bug的藏身之处。bug只有在我们开始多方位查看解决方案时才会露出端倪。测试人员的技能就是在系统中根据客户需求和路径风险设计这些路径,利用测试技术定位需要关注的重要区域。这里是决策表和有限状态模型(比如:N-1切换覆盖)真正发挥作用的地方。那些在单元测试或集成测试时没被发现的缺陷,会让验收测试立即崩溃。

  在系统测试过程中,设计测试发掘具有风险的紧急行为,提供具有实践经验的证明来评估覆盖率、遗留风险、缺陷密度、开发进度等其它质量属性也是测试人员应该具有的技能。当然我并不是说开发人员或BA不能做这些,只是他们太过忙于自己的工作,往往没有时间或精力去想这些。同样我建议测试理念和技巧在计划、执行和报告这些问题上是最有效和高效的。

  这把我们带到了确认和验证的讨论。它们的不同点到底在哪里?验证是确保所建立的东西是正确的——符合标准,遵循模式,在正确的时间做正确的事情。确认在另一方面是定义正确的事情是什么!确认和验证这两个部分都必须完成,测试给了我们完成这两部分的技术和技能,同时也允许我们将这两部分覆盖到系统需要的各种属性上(例如质量)。

  下一个问题是"那我们还需要测试人员吗?"恕我直言,--需要!!!为什么?因为测试实践人员所想的与团队里的任何人都不一样。测试人员是"专业的悲观主义者"(ISTQB基础教学大纲)。好的测试人员会花费时间关注潜在的问题,而非潜在的解决方案。从一开始我们就考虑坏的消息——到底哪里会发生严重的问题,如何快速定位问题,甚至如何去阻止问题发生。这和敏捷概念中的"快速失败"和尽早理解风险这两点完美切合。我们需要这样的思想观念尽早地参与到项目和解决方案设计中,从而让我们能够尽快并尽可能多地发现潜在障碍。

  真正拥有足够多的测试知识,能够准确计划测试工作的人并不多,而敏捷团队中需要关注的哪里和何时需要测试的东西又太多。在用户故事等级测试,迭代等级测试和特性等级测试之间应该有个明确的界限;还记得之前讨论过的"完成"的等级吗?由谁,在哪里,何时完成哪一部分测试都需要明确地确定出来,以保证所有的环境、工具、技术、数据和人员在执行时的有效性。测试(就像大部分事情一样)在好的团队中并不是偶然发生的……好的测试会做优秀的计划。优秀的测试需要杰出的计划。在该计划中,需要紧密地考虑测试人员和测试以保证所有相应的安排都建立到位。

  你是否会问:"那测试人员如何做到这些呢?"大部分人认为测试只是测试执行,但是在现实世界中,你所看到的那小部分测试是测试中最简单的。执行测试用例花费了总体测试工作大约25%的时间。大部分测试是在思想和文档中完成的。"天哪!"……你被震惊了……敏捷不是说了吗:"可工作的软件胜过面面俱到的文档"!没错!但是测试可以在任何或全部文档中发生(故事实例、白板设计、验收标准等)。第一个也是最大的一个障碍是,人们或整个团队不愿意定义什么是"很好地、价值、完成",或者由于太难而不愿将它们细化。

  多样的团队允许我们掌握每个方面最好的那一部分。特意排除某组技能或某组知识是幼稚的,非常不成熟的行为,且不能提高解决方案或方法的长期性。一个完整的并且拥有能够在最好的可能时间以最优惠的可能价格交付最好的可能解决方案所需要的所有技能的团队,才是完全聪明的、优秀的业务团队。认识到团队中其他人的技能,并将它们最大化发挥出来也是聪明的举动。

  那测试人员需要有自己特有的团队吗?不需要……敏捷项目中的任何人都可以成为测试人员,事实上,敏捷项目中的所有人都是测试执行者。主要问题是,团队中的所有人都需要遵守纪律,为了完成必须的所有测试活动(不单单是测试执行)他们需要在日常工作中时刻做到"测试先行"。如果团队没有在他们的工作产品、方法和解决方案中花费时间或精力计划、设计并应用测试,那团队将无法知晓他们的进程以及他们所面临的问题。

  因此我能留下的建议是:

  确保整个团队对每个层次"完成"的定义有个明确且一致的理解——自己的任务、用户故事、迭代、发布、项目和产品

  确保整个团队对这个产品的"质量"概念有个明确且一致的理解——是什么构成了"可工作的软件"

  测试并不只是敲击键盘以期找到缺陷,也不仅仅是执行单元测试

  测试是整个团队的责任,应该从第一个概念的讨论开始,并涵盖敏捷项目中的所有方面

  尽早测试,并且经常测试——等到所有工作完成之后才开始想到测试是错误的

  静态测试(检查每一块工作以确保其达到质量要求)比执行测试用例更有价值

  设计好的测试是个专业活动,敏捷团队中任何人都可以做到,但是需要一个正确的理念

  测试在敏捷中是否灭绝了呢?是的,但那是传统的,过时的,生命周期测试末期的测试。新的,完整的,预先的,积极参与的,挑战思想模式的,挑战现状的,并允许团队交付…交付价值,交付 "可工作的软件",交付客户真正想要的解决方案的测试将会永存。



五大敏捷原则——可以应用到每一种类型的开发过程

  一些专业顾问可能不希望你知道的东西:

  你并不需要在你的开发过程中作出重大改变就可以从敏捷原则得到很多好处

  如果你花时间去真正了解敏捷(而并不只是在网络上重复的徘徊于支持和反对中),你就会认识到事实上敏捷开发并不是一种方法论,而是一种可以应用于每个软件开发的方法。当然,像SCRUM(Scrum 是一种迭代式增量软件开发过程,通常用于敏捷软件开发)和 XP(Extreme Programming 极限编程)的方法都旨在制定敏捷原则的具体使用,但这并不意味着你可以通过这些工作方式来获得的敏捷开发的全部或大部分好处。

  一些工作中使用到了敏捷可能你没有注意到

  几个月前我们在与客户交谈的过程中,客户告诉我们,想要在工作中使用敏捷方法,但是在他们的团队中没有足够的时间实施SCRUM。该团队的经理提及曾经与一个SCRUM 顾问谈及敏捷开发的的实施,但是在进一步的考虑之后,他决定最好等待,直到当前产品发布,要在接下来6 到9 个月的时间实现所有必要过程的变动。

  顾问的建议给经理留下了非常深刻印象,他要求团队做出小的变化同时开始实施的一些顾问建议的想法。因此,每天早晨在喝咖啡和吃点心之后开15 到20 分钟小会议以及他们开始组织2或3人的程序员团队并使其尽可能在短周期内完成任务,而不是让每个程序员单独完成这样可能需要长达6 到8 周的时间才能完成的任务。

  他们所做的另一件事是让测试人员更早的介入工作,更紧密地与开发人员合作,在编码阶段开始,测试人员将对尚未完成的产品执行初步测试,也告诉程序员一些他们如何改善单元测试和集成测试的想法。作为这个过程的一部分,程序员也学到如何在提交修改之前自己进行部分的手工测试作为内部健全检查的一部分。

  最后,经理要求整个团队在每个月的月底与产品营销人员安排一个正式的会议,并将演示相关特性功能的开发进展。在这些营销会议提供的反馈仍然可以实现当前版本发布而不延迟版本发布。经理告诉我们,自从他们开始用这种方式工作,大大提高了团队的生产力和工作气氛,他真的很期待他们的团队实现SCRUM。

  他不理解的是,他们的工作方式并没有做任何革命性的改变,他们就已经实施了部分的敏捷开发并且从中体验到敏捷的好处。

  小的变化和改进之路

  这个经理的故事是一个很好的例子。如何在你的整个工程中使用小的改变来实现敏捷就能实现很多你想获得的结果并不需要开展一场彻底的革命。

  以下是一些想法,可以从上面的故事得到证明,我们相信,无论你的团队目前正在使用哪种开发方法都可以快速实现敏捷。

  (1)小/更小块的工作

  把工作分解成更小的,更易于管理的块,而不是少量的非常大的需求或任务,可以在更短的时间间隔内(数天或数周)完成。通过这种方式确保任务不比你原先分配的占用更多的资源(因为如果你的计划设想开始在工作中出错,你会在2周内而不是2-3个月才发现它),最重要的是,你会更快地交付功能给测试人员和产品营销人员,并得到及时反馈,进行必要的修正和调整,而不会影响你的发布日期。

  (2)增加程序员和测试人员之间的协作和沟通

  如果这个想法是为了使开发人员尽快得到功能的反馈,那么最好的办法是更早开始测试,很多时候,即使是在平行开发时也是如此。

  你可以通过多种方式实现这一目标,例如通过一准备好部分功能就邀请测试人员直接在开发环境运行其测试,(而不是等到所有部分都完成的时候)。

  另一种方法是测试人员与开发人员合作来计划和写单元和集成测试的方式,这将有助于测试人员更迅速地捕捉到更多的错误。最后,如何能让我们开始教程序员怎样运行少部分的由测试人员编写的手动和自动测试程序,作为他们在提交代码之前的健全性测试的一部分?我们看到很多的团队,在开发人员提交代码的主要分支之前他们需要运行开发自己的测试集进行测试。

  (3)有更多的自动化测试以及更多经常运行它们

  这是应用敏捷的团队的首要原则之一,事实上,也是符合每一种类型的项目逻辑。作出承诺,有意识地投资自动化。

  首先,指导你的开发人员为每一个新功能或重要的错误修复,创建单元测试和集成测试。

  你也可以让你的测试团队创建自动测试,以覆盖尽可能多的产品,并指导你的开发人员使用这个功能的自动化更简单,更强大(例如,通过使用GUI 元素中正确的仪器)编码方法。

  但是,创造你的测试是远远不够的。你需要有一个框架,尽可能多地运行这些测试,并在测试发现缺陷时即时反馈给程序员。

  现在,有很多很好的持续集成框架(如 Jenkins1,Bamboo2 或TeamCity3),所有这些都可以利用我们强大的API 集成到实践测试中。最后,你也将确保你的程序员遵守"你把它弄坏了,立刻你修复它!"的黄金规则。

 (4)寻求快速反馈和持续改进

  改善最大的敌人是人类行为:没有人喜欢被批评,我们指的就是没有任何一个!

  这就是为什么每当我们在做某件事,我们不愿意展示给别人,除非我们认为它已经完成了,我们的观众能够"完全"理解我们所做的。

  但正如你可能已经明白,这是反作用于编程的,因为如果我们等太久才得到反馈,我们不可能实现任何变更而不错过我们的交付目标。

  那么,你能做些什么呢?

  基本上,克服害怕被批评的心理,作为一种政策要求,在工作中每个人展示给其他团队成员以及产品行销人员他的工作过程。

  营造一种企业文化让人都知道如何给予和接受反馈。你通过确保反馈针对的是工作,而不是人,同时让人反馈产品的好和坏的方面(而不是只集中在需要修复的部分)来可以实现这一目标。

  起初,这可能不是一件简单的事,但它会随着时间的推移会变得容易,从中获得的价值简直是不可思议的。

  (5)拥抱变化和有序工作

  这可能是敏捷实现的基石,无论你如何努力工作规划你的项目,无论你有多擅长,最终事物会改变,你需要调整你的计划。

  但是,除去口号,你该怎么拥抱变化呢?

  首先,计划要少,不要深入但是要有,减少长期的,因为你无法准确地预见现实到底是几个月。

  寻求反馈宜早不宜迟,确保,如果你不得不改变功能和计划,你在2.4周时知道,而不是6至9个月。

  为改变做计划,并确保你的团队知道,变化确实会来,而且它会被接受,这使得他们当他们面临着这一现实和需要时,更容易应付它。

  小的变化应该是你工作方法的一部分

  你可以从敏捷的理解中获取最好的原则之一,正如产品和需求是不断变化的,所以你的工作流程应该是动态的,自适应。

  能接受被提问关于你是否工作在最好的和最有效的方式,或者是是否你能在过程有或大或小的改进?

  能接受反馈,寻求它,甚至奖励给出反馈的人。一旦你能够引入接受反馈的企业文化,你将看到如何真正开始改善,甚至是他们自身。

  注:

  1、Jenkins,之前叫做Hudson,是基于Java 开发的一种持续集成工具,用于监控秩序重复的工作,包括:

  I、持续的软件版本发布/测试项目。

  II、监控外部调用执行的工作。

  2、Atlassian Bamboo是一款持续集成构建服务器软件(Build Server)(非开源软件)。Bamboo 的特点: 简单的用户界面容易安装-顺利的话,5 分钟内就可以让运行起来!自动检测你的设置 - 如果你的Server 上使用了Maven,Ant 或者Java 设置, Bamboo 会自动检测他们; 连续的日志 - 监测你的build 的colour coded 日志;容易显示所有项目。

  3、TeamCity是一款功能强大的持续集成(Continue Integration)工具,包括服务器端和客户端,目前支持Java,.NET项目开发。

  TeamCity 提供一系列特性可以让团队快速实现持续继承:IDE 工具集成、各种消息通知、各种报表、项目的管理、分布式的编译等等,所有的这些,都是让你的团队快速享有持续集成带来的效率提升、高质量的软件保障。

  使用 TeamCity,你能够在几分钟之内为你的项目配置一个构建服务器,它内建了持续单元测试,代码质量分析和早期的构建问题分析报告,你甚至可以在IDE 进行。

  TeamCity提供平滑的学习曲线,你可以逐步的学习经它的高级特性和功能,你很快就能加强你发布管理实践。本次发布,在可用性作了大量的改进,更新的IDE 插件支持 CVS 和SVN,另外还包括一些之前版本不具备的企业级的特性。



产品的性能测试

 项目的情况简介:

  项目属于客户端/服务端模式产品,要求每个服务端能支持连接500个客户端

  测试环境简介:

  服务端支持三级连接模式,每个服务端能支持连接500个客户端,总要求支持大约5000个客户端。

  测试的过程描述:

  在测试实验室中,只能搭建10个客户端的环境以及三级连接的环境。服务端初次连接客户端后,客户端会保留服务端的IP地址。下次客户端机器启动时,会自己连接服务端。每次连接属于短连接。在产生事件时,客户端会自己上报给服务端。

  测试过程遇到的问题:

  在实验室中测试系统稳定可用,但在用户那里遇到服务端异常退出。

  问题分析:

  客户端同时大量上报事件时,服务端处理出问题,导致系统异常退出。

  希望寻求的帮助:

  如何模拟多客户端问题?如何进行产品的性能测试?如何保证产品的稳定性?

  分析一:

  作者:多瑙河

  分析内容:

  很简单,这种情况,用loadrunner最合适了,用loadrunner这种压力测试工具,模拟多用户环境,不知道你们是用什么语言开发,如果是java的甚至可以利用loadrunner的Tunning组件,达到代码级的调优。如果是C#.net,那很要等啦,Mercury同意支持C#.net,但支持版本还没有出来。我在给你个建议,找个系统整合专家,看看是不是他们的网络有问题,或者是服务器没有调试好。有时候,机子CPU多,没有调试好,可能大量的CPU资源用于频繁的调度,而造成系统异常。有时候,还要改进算法。这种系统调试最麻烦了!

  分析二:

  作者:关河

  分析内容:

  个人意见:对这个问题的分析应该考虑两个层次:

  1、解决现有问题的层次;

  2、探讨测试不充分问题产生的根源并从根源上避免此类问题的发生。 这个问题本身是比较好解决的,在现场出现问题后,我们要做的是利用实验室的环境(或者现场的环境)确定问题产生的原因,从例子的描述来看,应该是在客户端大量建立连接时服务端无法支持,产生异常退出。对该问题的定位可以用LR等性能测试工具(或是自己编写的工具)模拟进行大并发量的突发连接测试,并据此给出改进的方法。

  其次我们还应该探讨测试不充分问题产生的根源。在这个例子中,由于设备不足够,可能根本就没有进行压力和负载测试,这本身就留下了隐患。其次,作为测试负责人,对这种项目的经验不足,一般来说,基于短连接方式的C/S结构应用最大的可能出问题的地方就是大量用户同时进行连接操作,即使没有环境在实验室中进行测试,也必须把这个作为一个大的项目风险列出,要求在交付最终用户使用前进行这类测试。

 分析三:

  本案中,作者的描述有些歧义:

  1、"三级连接模式",不知道是不是有服务器,有端站,有客户端的模式,还是采用了服务器集群,多台服务器分三级级连

  2、"每个服务端能支持连接500个客户端,总要求支持大约5000个客户端。"

  3、"服务端初次连接客户端,"这个不知道是不是应该是"客户端初次连接服务端",而书写的当时,思维太快了,手没跟上,请教开发工程师都说"一般都是客户端去连接服务端的"拉"模式,而极少服务端向客户端"推"的模式。"

  4、"在产生事件时,客户端会自己上报给服务端",不知道是不是以发送日志文件的形式上报。

  5、"在实验室中测试系统稳定可用",实验室中测试是不是只有10个端站的情况下,而并没有采用任何的测试工具来做模拟端站和用户,已达到实际需要的量级。

  6、"下次客户端机器启动时,会自己连接服务端。"这个连接,是指自动登录还是会同步数据或者仅是网络连接?

  所以,对于本案编者只能按照性能测试的一般做法做一个介绍,不能详细的分析本案为什么会出现了不稳定运行的状况了,希望能对本案作者及遇到相同问题,或者准备做性能测试的同行们有所启发。

  首先,我们为什么做性能测试呢?

  性能测试的目的:

  一、评估系统的能力,测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的数据处理能力,并帮助作出决策。

  二、识别体系中的弱点:受控的负荷可以被增加到一个极端的水平,并突破它,从而修复体系的瓶颈或薄弱的地方。

  三、系统调优:重复运行测试,验证调整系统的活动得到了预期的结果,从而改进性能。检测软件中的问题:长时间的测试执行可导致程序发生由于内存泄露引起的失败,揭示程序中的隐含的问题或冲突。

  四、验证稳定性(resilience)可靠性(reliability):在一个生产负荷下执行测试一定的时间是评估系统稳定性和可靠性是否满足要求的唯一方法。

  性能测试类型包括:

  负载测试:负载测试是一种性能测试指数据在超负荷环境中运行,程序是否能够承担。

  强度测试: 强度测试是一种性能测试,他在系统资源特别低的情况下软件系统运行情况。

  容量测试:确定系统可处理同时在线的最大用户数

  性能测试观察指标:

  性能测试主要是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。负载测试和压力测试都属于性能测试,两者可以结合进行。通过负载测试,确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。

  在实际中作中我们经常会对两种类型软件进行测试:bs和cs,这两方面的性能指标一般需要哪些内容呢?Bs结构程序一般会关注的通用指标如下(简):

  Web服务器指标指标:

  1、Avg Rps: 平均每秒钟响应次数=总请求时间 / 秒数;

  2、Avg time to last byte per terstion (mstes):平均每秒业务角本的迭代次数 ,有人会把这两者混淆;

  3、Successful Rounds:成功的请求;

  4、Failed Rounds:失败的请求;

  5、Successful Hits:成功的点击次数;

  6、Failed Hits:失败的点击次数;

7、Hits Per Second:每秒点击次数;

  8、Successful Hits Per Second:每秒成功的点击次数;

  9、Failed Hits Per Second:每秒失败的点击次数;

  10、Attempted Connections:尝试链接数;

  11、CS结构程序,由于一般软件后台通常为数据库,所以我们更注重数据库的测试指标:

  12、User 0 Connections:用户连接数,也就是数据库的连接数量;

  13、Number of deadlocks:数据库死锁;

  14、Butter Cache hit:数据库Cache的命中情况

  当然,在实际中我们还会察看多用户测试情况下的内存,CPU,系统资源调用情况。这些指标其实是引申出来性能测试中的一种:竞争测试。什么是竞争测试,软件竞争使用各种资源(数据纪录,内存等),看他与其他相关系统对资源的争夺能力。性能测试的流程步骤和做其他的测试没有什么区别,做性能测试也要如下步骤来做:

  1、测试需求分析

  2、测试设计

  3、测试脚本开发

  4、测试实施

  5、测试结果分析

  测试需求分析,性能测试(或者其他的测试)做的好与坏完全取决于测试分析做得好不好。软件最终始要被应用的,要在应用的实践中考验,所以,任何类型的测试分析都要以实际业务的要求为依据。那么,性能测试的测试需求分析都需要分析哪些内容呢?

  1、性能测试的需求来源。客户需求和期望,实际业务需求,系统需求。

  2、业务数据量级,要根据实际业务分析可能出现数据吞吐瓶颈的地方,比如本案中作者提到的要求每个服务端连接500个客户端,总要求连接5000个客户端。分析到这个程度还不够,还要进一步分析业务操作集中的点,时间段和量。如,本案中客户端开启会自动连接服务端,那么在每天开始上班的时候客户端的开启就会出现峰值,可能会持续20分钟,服务端需要响应客户端的连接请求,请求还可能并发至少 5000/120次每秒,同时短时间内集中请求的频率也是有阈值限制的。

  3、系统架构,在每种不同的系统架构的实施中,开发人员可能选择不同的实现方式,造成实际情况纷繁复杂。我们不可能对每种技术都详细解说,这里只是介绍一种方法提供给你如何选择测试策略,从而帮助分析软件不同部分的性能指标,进而分析出整体架构的性能指标和性能瓶颈。

  4、测试策略和评估标准,任何测试的目的都是确保软件符合预先规定的目标和要求。性能测试也不例外。所以必须制定一套标准。通常性能测试有四种模型技术可用于评估:

  * 线性投射:用大量的过去的,扩展的或者将来可能发生的数据组成散布图,利用这个图表不断和系统的当前状况对比。

  * 分析模型:用排队论公式和算法预测响应时间,利用描述工作量的数据和系统本质关联起来

  * 模仿:模仿实际用户的使用方法测试你的系统

  * 基准:定义测试和你最初的测试作为标准,利用它和所有后来进行的测试结果进行对比

  测试设计,测试设计是在了解软件业务流程的基础上。设计测试用例的原则是受最小的影响提供最多的测试信息,设计测试用例的目标是一次尽可能的包含多个测试要素。这些测试用例必须是测试工具可以实现的,不同的测试场景将测试不同的功能。因为性能测试不同于平时的测试用例,尽可能把性能测试用例设计的复杂,才有可能发现软件的性能瓶颈。

  测试脚本开发,性能测试是通过工具,模拟大量用户操作,对系统增加负载。所以需要掌握一定的工具知识才能进行性能测试。大家都知道性能测试工具一般通过winsock,http等协议纪录用户操作。而协议选择是基于软件的系统架构实现(web一般选择http协议,cs选择winsock协议),不同的性能测试工具,脚本语言也不同,比如rational robot中vu脚本用类c语言实现。

  开展性能测试需要对各种性能测试工具进行评估,因为每一种性能测试工具都有自身的特点,只有经过工具评估,才能选择符合现有软件架构的性能测试工具。

  测试结果分析,运行测试用例后,收集相关信息,进行数据统计分析,找到性能瓶颈。通过排除误差和其他因素,让测试结果体现接近真实情况。不同的体系结构分析测试结果的方法也不同,bs结构我们会分析网络带宽,流量对用户操作响应的影响,而cs结构我们可能更关心会系统整体配置对用户操作的影响。