优秀的开发工程师不仅是有超强的代码编写能力,同时他还有非凡的概要设计和详细设计能力,那么对于优秀的测试工程师来说,不应该仅仅是极强的发现问题的能力,还应该具备优秀的用例设计能力。用例设计实际上包含两种能力,一种是结构设计能力,一种是用例场景设计能力,今天我想和大家讨论的是前一种能力。
用例设计中的结构设计就类似于软件开发中的概要设计,它实指用例设计中的测试项分拆、合并、派生。目前我们测试组有些员工在思考用例设计时包含了这个环节,但并没有将这个环节熟练掌握,且一直困扰着部分人的测试工作开展。可能有人会说,我测试的产品质量虽然不是最差,但我的用例设计包含了80%的用例设计场景,应该不错了,干嘛还要强调用例设计中的结构设计呢?
用例设计的结构设计重要性在于如下几方面:
1、合理地拆分测试项,有助于保证测试任务执行的分配与并行
2、合理地拆分测试项,有助于和开发节奏对应起来
3、合理地拆分测试项,有助于保证测试的执行与测试用例的当初设计不脱节
4、合理的拆分测试项,有助于保证测试覆盖度
5、合理的拆分测试项,有助于用例场景的设计不出现混乱
6、合理的拆分测试项,有助于一个人全局能力的培养
……
用例设计的结构设计这一块究竟有什么方法可循吗?说句实话,至少现在我没有见到任何书籍介绍这一快,我在面试过程中也在了解其他公司关于这一块的做法,很多员工听起来很陌生,可能是这个能力仅对组长以上的员工有要求吧,有的听起来虽然不陌生,但是更多和我沟通的是关于用例设计的生成流程,
对于方法这一块是不清楚的。总而言之,用例设计的结构设计这一块对于很多公司的经验总结来说还是空白,那就更谈不上培训了。关注这一块,我是在2001年开始的,当时接受的一个是视频会议系统的测试,组里共5个人,为了将结构设计做好,的确费了一番周折。通过这几年来,在不同项目中与不同员工磨合,对用例设计的结构设计部分摸索了一套如下一系列方法。我现在还不能说最好的,但应该是最实用的,绝对不是为了推销需要。
1、基于概要设计/详细设计的模块(组件)结构设计
2、基于产品需求文档的模块结构设计
3、基于数据流的结构设计
4、基于事件驱动的结构设计
5、基于消息驱动的结构设计
6、基于处理逻辑的结构设计
7、基于条件因素的结构设计
8、基于MVC模型的结构设计
9、基于测试方法的结构设计
测试用例设计还要注意着重点
一、功能
关注页面单个功能点验证,充分考虑开发改动的每个点。这个是保证开发每个已知的修改点都能改对。
二、关联
重点考虑修改点对其他模块的影响,包括代码的影响和操作数据引起的影响。
比如新增加的功能增加了数据库表的字段,必须关联的验证每个使用该表的该字段的模块是否正常工作。难点在于需要分析出已知和未知的影响模块,考虑的越多,往往遗漏的问题就越少。
三、流程
很多系统是有流程的,比如工作流系统。当修改了一个点的时候,我们必须考虑整个流程是否能够正常运转起来。
四、升级
我们大部分系统都是对已有的系统进行升级。对于升级前的数据,我们必须保证能够正常工作。升级之前,需要模拟好各种情况。也需要对升级的数据库脚本进行充分的检查。
五、安全
比如菜单功能权限等。
六、性能
软件测试的三十六计(1)
软件测试的三十六计(2)
第二十六计- 指桑骂槐
【释义】
此计运用此象理,是说治军,有时采取适当的强刚手段便会得到应和,行险则遇顺。
本计策同样是用于团队管理,只有让团队成员处于一种危机感+成就感的情绪下,团队才能持续的健康发展。
所以,不时的敲打一下,是很必要的手段。大家都是成年人,如果连这个都理解不了,我很怀疑你的情商。
第二十七计-假痴不癫
【释义】
此计运用此象理,是说在军事上,有时为了以退求进,必得假痴不癫,老成持重,以达后发制人。这就如同云势压住雷动,且不露机巧一样,最后一旦爆发攻击,便出其不意而获胜。
同样作为团队管理者,有时候根据情形需要忍,不管是组员的,还是上面的压力,还是开发团的不协作。总之,作为一个团队的领导者,必须有时候装傻,让大家不至于过于紧绷。但是,也不能永远的装傻,该强硬的时候必须站出来。但是没事就强硬几把,那不是装逼,就是太傻了。
作为领导管理者,厚黑学得看,但是不能瞎用,自己整自己的手下是最悲哀的。
第二十八计-上屋抽梯
【释义】
上楼以后拿掉梯子。借指与人密谈。也用以比喻怂恿人,使人上当。
当一个人带领团队时,如何培养自己的组员呢,这条计策很实用。要知道,在一个公司里,如果你还有上升的余地时,除了搞好领导关系,关键得给自己培养一个接班人,你上去了,team不会变,才有机会。
所以抽掉自己的梯子之前,要先抽几个别人的梯子。没事了把几个有潜力的人逼到房顶上,然后抽掉他们的梯子,看他们摔的疼不疼,是一件很有必要的事。就当挫折教育了。 比如,在一些简单的QA 活动中,让新人去控制这些,你在旁边兜底就行。
毕竟,一旦回头看看,这些人会感谢你的,新人不断,哪怕超过你,心理成就感也是十足的。
至于抽掉竞争对手的梯子,我个人喜欢堂堂正正对决,但是经常被人抽掉,所以做好自己屁股痛的准备吧。能狠心抽别人的,也无需自责,人的本性就是这样的。
第二十九计-树上开花
【释义】
此计运用此理,是说弱小的部队通过凭借某种因素,改变外部形态之后,自己阵容显得充实强大了,就象鸿雁长了羽毛丰满的翅膀一样。
这个是个态度问题,作为互相交流的各个团队,要借助别人优秀的成果,从而提高自己的能力。但是很多时候,大家都是只借入,不借出,本性。
尤其在测试中,寻求开发团队介入测试过程,不是一件羞耻的事,反而符合敏捷的精神,双赢
第三十计-反客为主
【释义】
本是客人却用主人的口气说话。后指在一定的场合下采取主动措施,以声势压倒别人。
当你进入一个新的测试团队,如何更快的融入到这个团队中,那就是以这个团队的思想为思想,把自己作为这个团队的主人去相处,交流,学习。
如果你把自己当作一个客人去融入这个团队,那么恭喜你,你从一开始就把自己当外人了,怎么融入啊
同样,作为老人,对于新人要鼓励对方多发表意见,多参与活动,给对方一个机会,让大家成为成功的协作者
第三十一计-美人计
【释义】
此计运用此象理,是说利用敌人自身的严重缺点,己方顺势以对,使其自颓自损,己方一举得之。
其实这是一个经验,也就是探索测试的一个起点。当你测试的项目,内容,种类,行业,等等多了起来。 你就会发现,每个行业多多少少的都有自己的一些特点。
尤其是bug出现比较多的地方都心有了然。
把这些东西作为经验share出去,也标志着你是一个成功的测试人员。
第三十二计-空城计
【释义】
在敌众我寡的情况下,缺乏兵备而故意示意人以不设兵备,造成敌方错觉,从而惊退敌军之事。后泛指掩饰自己力量空虚、迷惑对方的策略。
这个其实是一个很熟悉的测试策略。当你测试的时候,你已经把所有的功能当作是运转正常的,所以现在是空,一旦发现了bug,就知道不是空的。
尤其是在模块集成测试时,你只有认为其它的模块都是正确的,才能去推断当前要测试的模块是否有问题。
所以,什么时候设空,是一个很技术问题。
第三十三计-反间计
【释义】
原指使敌人的间谍为我所用,或使敌人获取假情报而有利于我的计策。后指用计谋离间敌人引起内讧。
这也是一个测试的策略。反向数据,就是一个例子。
尤其有时候,你无法有足够的时间来确定正向的功能是否完善时,可以采用这个计策。
在正面选择能够覆盖所有check point的end to end的任意一条正向数据和反向数据。
然后把你所有能想到的正向数据和反向数据处理不了的场景列出来,然后一一举证,一旦这些场景都证明系统无缺陷,你就可以认为系统是无缺陷的了。
核心就在于,你不知道这个是对的时候,把所有的错误的可能都排除了,那就证明它是对的。
第三十四计-苦肉计
【释义】
故意毁伤身体以骗取对方信任,从而进行反间的计谋。
有时候我们想用反间计,可是不知道到底哪些是错误的,那就只好苦肉计了。那就是把所有的情况都列出来,一个个的排除,肉体置顶。
有时候,最笨的方法,就是最简单的方法。
第三十五计-连环计
【释义】
本为元杂剧名。剧本写汉末董卓专权,王允设计,先许嫁美女貂蝉与吕布,后又献给董卓,以离间二人,致使吕布杀死董卓。后用以指一个接一个相互关联的计策。
在我们测试过程中,如果要选取回归测试用例,或者需要开发数据驱动的测试框架,那么连环计是最有效的。
所有的步骤,work flow和数据都是相互依赖,相互承启的,那么就能最小的cost去获得测试结果。
尤其是数据驱动,数据依赖的测试过程,让你减少很多不必要的数据开销。
第三十六计-走为上计
【释义】
指战争中看到形势对自己极为不利时就逃走。现多用于做事时如果形势不利没有成功的希望时就选择退却、逃避的态度。
我们在测试过程中的走,其实是指所有的东西都是动态的。
敏捷测试的核心就是动态。
需求是动态的,用例是动态的,计划是动态的,环境是动态的,资源是动态的,只有所有的一切都能在动态中去进行,才说明你的团队是敏捷的
放弃那些静态的瀑布模型的恶习吧,那只是一副固定在墙上的山水画。
版权声明:本文出自 gigobin 的51Testing软件测试博客:http://www.51testing.com/?26810
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。
。
一、六顶思考帽的来历
六顶思考帽是英国学者爱德华·德·博诺(Edward de Bono)博士开发的一种思维训练模式,或者说是一个全面思考问题的模型。
它提供了“平行思维”的工具,避免将时间浪费在互相争执上。强调的是“能够成为什么”,而非“本身是什么”,是寻求一条向前发展的路,而不是争论谁对谁错。运用博诺的六顶思考帽,将会使混乱的思考变得更清晰,使团体中无意义的争论变成集思广益的创造,使每个人变得富有创造性。
二、六顶思考帽是什么
所谓六顶思考帽,是指使用六种不同颜色的帽子代表六种不同的思维模式。任何人都有能力使用以下六种基本思维模式:
1、白色思考帽
白色是中立而客观的。戴上白色思考帽,人们就只是关注事实和数据。
白帽子——代表信息及质询。我们现在有什么信息?需要寻找什么信息?还缺乏什么信息?
2、黄色思考帽
黄色代表价值与肯定。戴上黄色思考帽,人们从正面考虑问题,表达乐观的、满怀希望的、建设性的观点。
黄帽子——代表效益。这件事为甚么值得去做?有甚么效益?为甚么可以做?为甚么会成功?一定要把理由说出来。
3、黑色思考帽
戴上黑色思考帽,人们可以运用否定、怀疑、质疑的看法,合乎逻辑的进行批判,尽情发表负面的意见,找出逻辑上的错误。
黑帽子——代表谨慎、判断及评估。这是不是真的?会不会成功?有甚么弱点?有甚么坏处?一定要把理由说出来。
4、红色思考帽
红色是情感的色彩。戴上红色思考帽,人们可以表现自己的情绪,人们还可以表达直觉、感受、预感等方面的看法。
红帽子——代表情绪、直觉、感觉及基于直觉的想法。只需表达即时的感受,不需要进行解释。
5、绿色思考帽
绿色代表茵茵芳草,象征勃勃生机。绿色思考帽寓意创造力和想象力。它具有创造性思考、头脑风暴、求异思维等功能。
绿帽子——代表创新、异见、新意、暗示及建议。有甚么可用的解决方法及行动途径?还有甚么其它途径?有甚么合理的解释?任何意见都不可抹杀。
6、蓝色思考帽
蓝色思考帽负责控制和调节思维过程。它负责控制各种思考帽的使用顺序,它规划和管理整个思考过程,并负责做出结论。
蓝帽子——代表思考的组织及思考有关的问题。我们到了那个阶段?下一个步骤是什么?作出具体说明、概括及决定。需要使用那顶帽子?
三、六顶思考帽在会议中的典型的应用步骤
1、陈述问题事实(白帽);
2、提出解决问题的方案(绿帽);
3、评估该方案的优点(黄帽);
4、列举该方案的缺点(黑帽);
5、对该方案进行直觉判断(红帽);
6、总结陈述,做出决策(蓝帽)。
四、六顶思考帽的作用
六顶思考帽是平行思维工具,是创新思维工具,也是人际沟通的操作框架,更是提高团队智商的有效方法。
六顶思考帽是一个操作简单、经过反复验证的思维工具,它给人以热情,勇气和创造力,让每一次会议,每一次讨论,每一份报告,每一个决策都充满新意和生命力。这个工具能够帮助人们:
● 提出建设性的观点;
● 聆听别人的观点;
● 从不同角度思考同一个问题,从而创造高效能的解决方案。
● 用“平行思维“取代批判式思维和垂直思维。
● 提高团队成员的集思广益能力,为统合综效提供操作工具。
版权声明:本文出自 shiningredstar 的51Testing软件测试博客:http://www.51testing.com/?7622
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。
多数移动应用程序采用何种开发技术,都会给本地设备和企业带来不同的风险,因而在部署之前需要对其实施软件测试和评估。本文首先讨论黑盒测试技术和策略。
基于Web的移动应用的漏洞识别和利用
在评估基于Web的移动应用时,我们建议评估者以匿名用户的身份来执行测试,并使用多种经认证的用户角色的特权。因为基于Web的应用是通过互联网来访问的,测试团队应当使用PC上的传统浏览器和标准的应用安全评估工具。
在评估过程中,为了确认基础架构水平的漏洞,应当对Web服务器进行扫描。这种扫描的结果应当用于确认常见的应用程序问题。评估者还可以利用人工技术,充分利用所确认的漏洞,并对自动化工具常常遗漏的授权缺陷和业务逻辑进行测试。这一点尤其重要!
此外,企业应当对网站执行“非入侵性”分析,其中包括通过镜像整个站点来检查内容,然后检查客户端的代码漏洞。使用分析阶段所产生的输入,私有的专用工具应当动态地测试Web服务器的组件,用以检查常见的Web服务器和Web应用漏洞,如SQL 注入漏洞、跨站脚本、跨站请求伪造等。此外,还应当利用商业化的工具来执行漏洞扫描。
在确认了漏洞之后,为了利用漏洞,测试人员应当执行测试。此外,还有可能有如下内容:不安全的cookie处理,绕过认证,操纵表单欺诈,URL协议处理程序,基于位置的服务,敏感信息泄露,应用逻辑欺骗等。
在黑盒测试结束时,应当执行漏洞评估,并根据每个漏洞所带来的风险进行评级。
基于设备的移动应用测试环境
为移动设备开发的应用程序带来了传统应用所没有的新的测试挑战。例如,移动设备对低级过程和例外日志拥有有限的直接访问权。移动设备还支持应用程序与GPS、相机、蓝牙、WAP,以及传统PC中所没有的其它技术进行交互。为解决这些困难,企业应使用如下的两种测试方法:
模拟器测试:每一种平台都向开发人员提供了应用开发的SDK,并提供了用于测试和调试的不同型号设备的模拟器。这些工具还允许测试人员在各种配置和设备中分析和测试应用程序,而没有物理设备的限制。模拟器测试的一个好处是,代码并不需要由一个可信方来签署就可以在模拟器中运行。
物理设备测试:对物理设备的测试提供了在模拟器中测试所没有的许多功能,如SMS、GPS、相机、蓝牙等。不过,由于缺乏对底层操作系统和应用签名要求,这种测试又受到了一定限制。
基于设备的移动应用漏洞确认
根据移动应用的功能,测试人员应在模拟器或客户端提供的物理设备中执行测试,或兼而有之。在测试过程中,测试者应确认应用的功能,并针对任何内部的逻辑控制和外部连接。因为移动应用在许多方面是不同的,应当使用下面的步骤来测试每一种应用:
1、映射应用的功能
应当人工检查应用程序,确认其功能和应用程序访问不同组件的方法。评估团队应当重点关注如何确认外部的网络连接,以及数据存储、用户输入和许可等问题。
2、监视连接
移动应用有许多连接到外部源的方式。测试者应当使用代理工具和网络嗅探器,用来监视每一个请求和响应。还要记录数据通信,以便于日后的分析。如果应用程序使用了蓝牙或其它连接,为了捕获数据通信,开发团队应当使移动设备与一个服务器进行配对使用。
3、检查数据处理
由于应用程序的使用,数据可能存在于多个不同的位置。用户或非授权方有可能通过各种方式访问敏感信息或应用。评估应当确认敏感信息在何处产生,并分析如下情形中如何保护数据:由于用户交互而提交给应用的用户输入;用于输入到应用程序中的文件;在正常使和应用期间产生的文件;由于程序的例外进程所生产的应用程序日志;应用程序和设备(它们有可能将敏感数据放在非正常的或非法的位置)的缓存机制;通过网络连接而从外部服务器获得的数据。
4、反编译应用程序
只要条件允许,就应当对应用程序进行反编译,其目的是为了检查有可能使应用程序的漏洞被利用的危险方法,如检查是否有缓冲区溢出问题。虽然许多移动平台是基于Java的,但它们自己的编译器与传统的安全工具并不兼容。如今许多平台都有其反编译器,如黑莓和安卓,苹果也提供了一个反编译器。这些工具能够深入分析应用程序的逻辑,并可以进行有限的静态代码分析。
5、检查加密机制
任何时候都应当保护静态数据和传输中的数据,使其不被未获得授权的人员访问。测试人员应当检查移动设备和任何网络服务器的通信加密情况,检查应用程序是否将文件保存到了设备上,或在备份过程中是否发生过转移。
基于设备的移动应用漏洞利用
利用在漏洞确认阶段所收集的信息,测试人员应当通过以下步骤,尝试利用所确认的漏洞:
1、认证和会话管理
由于可用性的限制,移动应用使用许多新的认证技术,如清除模式,其目的是为了减少口令的复杂性。为了测试是否可以绕过认证控制或访问其它用户的数据,测试者应当测试移动应用的认证机制。在通过认证之后,测试者应当检查应用程序的会话管理。通过观察应用程序如何跟踪、记录用户,测试人员可以评估是否能够重新进行会话或是否可以跳转到另一个用户会话。
2、授权
设备的授权许可应当专门定义,这种控制可以防止设备进一步访问设备或其功能。在应用程序环境中,还应当测试没有得到许可的正常用户是否能够访问某些功能。
3、输入验证
通过规定应用程序的输入区域,并观察输出,安全评估就可以判定在其它特定应用的用户浏览器中,是否能够插入并执行客户端的JavaScript。此操作可以使某用户捕获其它用户的会话机密或应用的用户名和口令等。
4、数据存储
许多应用程序收集关于用户的使用数据。这种数据有可能过度冒犯用户的隐私。测试人员应当检查这种数据,判定应用程序收集并保存了哪些数据以及如何访问这些数据。测试人员还应当测试未经授权的用户或第三方是否能够访问这种数据。
5、风险分析
在移动黑盒测试的结束阶段,测试人员应当评估每一种风险给企业带来的危害。
本文阐述了黑盒测试的基本要点,但如果开发人员在开发过程中能够牢记安全第一的原则,遵循最佳的开发实践,在发布软件之前,积极检查并修正错误,反复测试,将极大地减轻测试人员的负担。
社交工程已经成为目前最盛行的攻击方式之一,而且在一些较大的数据泄漏案例中也总是出现。例如,2011年RSA breach就遭遇了定向钓鱼和加载了漏洞的Excel文件。因此,对于有能力模拟真实攻击的企业而言,社工渗透测试应该成为每个渗透测试工具包的强制性策略。
社工行为非常依赖心理学,有很多非常可疑的诱饵,可以让社工人员劝服人们从事某项操作。例如,Robert Cialdini在其著作《影响力:说服心理学》(Influence: The Psychology of Persuasion)中描述了六种刺激人们行为的动机:
1、互惠:因为某人帮助了你而感到歉疚;
2、社交认同:向其他人学习如何进行行为操作;
3、承诺/一致性:发展行为模式并使之成为习惯;
4、喜好:人更容易被有好感的人说服;
5、权威:对权威人物所提要求的默许;
6、短缺:当某个东西的供应受限或仅供专用时,对这个东西的需求就会增加。
渗透测试员在执行社工评估的时候可以利用这些刺激因素。有四种社工技巧可供渗透测试员测试企业的信息安全,分别是钓鱼、假托、介质投放和追尾。
社工渗透安全测试:钓鱼攻击
钓鱼是指向用户发送邮件以便说服用户进行某项操作。在渗透测试中,大多数钓鱼邮件的目的只是诱导用户点击某个东西,然后记录下这一行为或是为稍后更大规模的渗透测试安装一个程序。这之后,就可以利用客户端软件的某个特定漏洞,如浏览器和动态内容/媒体插件和软件。
成功实施钓鱼攻击的关键是个性化!向目标用户发送特制邮件,如从受信任的邮箱地址发出此邮件,可以增加用户阅读该邮件或是遵照邮件提示操作的几率。一名好的渗透测试员一般都会仔细检查邮件中的拼写和语法错误;一封内容比较少的邮件,如果措辞得体,可能会让人觉得更具可信度。
创建钓鱼攻击最常用的工具可能是开源社工工具包(SET)。通过菜单驱动的邮件和攻击创建系统,它成为了最简单的钓鱼方式之一。而PhishMe Inc.公司的PhishMe和Wombat Security的PhishGuru也很有用。
社工渗透安全测试:假托(Pretexting)
假托(Pretexting)是指打电话给攻击目标,试图从目标对象那里套取信息。在渗透测试中,这种技巧适用于能提供有用信息的非技术型用户。
最佳策略是提出一些小要求,并给出企业中一些真实员工的名字。在假托对话中,渗透测试员会解释称需要目标对象的帮助(大多数人都愿意配合完成一些看上去没什么可疑的小任务)。一旦双方创建友好关系,渗透测试员便会伺机套取更多信息。
在实施假托之前的侦查需要使用谷歌和Paterva Maltego等工具,这些侦查可以提供必要的背景信息。类似SpoofCard和SpoofApp这种电话代理工具以及Asterisk PBX插件可以隐藏渗透测试员的电话号码,甚至是使显示的号码看似来自某个企业。
社工渗透安全测试:介质投放 (Media dropping)
介质投放(Media dropping)通常是指放在某个显眼位置的USB闪存设备,如停车场或者建筑入口处。社工在闪存设备上存放了一些非常有趣的文件,而一旦这个闪存被打开便会在客户端发起某种攻击。
Metasploit是可用于创建此类文件的一款免费工具,它带有内置恶意负载生成器。SET中的“传染型介质生成器”选项虽然也可以利用Metasploit,但是却有助于进程自动化。SET可以创建“合法的”可执行文件。目标电脑启用自动运行时就会自动执行这个文件。自动执行技巧和有趣文件相结合可以增加攻击成功的几率。
而执行介质投放更为复杂的方法则是开发出能通过USB闪盘进行自定义攻击或是购买能预置此类程序的USB闪盘。为了增加USB攻击的成功几率,还可以为设备添加自动利用漏洞和攻击加载文件(以PDF,Word和Excel为宜)。然后在该USB上贴上能吸引人的标签,如“HR数据”或者“就业”之类的。
社交渗透安全测试:追尾(Tailgating)
追尾(Tailgating)是指通过强迫或愚弄的方式进入物理设备。通常,这类测试所关注的问题是证明渗透测试员可以绕过物理安全防御。
渗透测试员应该计划好获取敏感数据或是快速安装设备以证明自己成功渗透,因为在他们离开设备前所能利用的时间很短。渗透测试员可以将打印机或者桌上暴露的信息拍照,抑或是安装一个渗透测试盒来提供wifi或3G网络以便渗透员回访。
通过使用上述四个社工技巧,渗透测试员可以发现企业的漏洞,并给予相关的安全控件推荐和培训,这样可以减少企业遭受恶意社工攻击的几率。
什么是EDA?Escaped Defect Analysis,直译过来就是对逃掉的缺陷进行的分析。
软件测试人员经常会被抱怨,为什么这个缺陷被客户发现了?或者被研发自己发现了?你们没有测出来呢?作为一名测试人员,经常会觉得很委屈,该设计的用例都设计了啊、该用的测试方法也都用了啊、该考虑的环境参数也都考虑了啊…………….Why呢?
其实导致缺陷的因素有很多,并不是只有测试一个环节就能够完全保证软件质量。对于项目中所逃掉的缺陷,是有必要做一个模型并进行分析的。
以下是根据我参与的一个项目所作的一个模型:
做EDA工作的第一步,就是收集所有的Escaped Defects。那什么是Escaped Defects呢?从上面的模型,我们可以看到,客户发现的、研发人员发现的、内部或者外部试用用户发现的、产品上市以后发现的、以及应该在研发的某sprint内发现却没发现的,这些都属于Escaped Defects的范畴。不同的项目,对于Escaped Defects的来源不尽相同。对于这些Escaped Defects,我们需要进行详细的分析,one by one的找到缺陷遗漏的原因。
根据我们对已有项目的分析,原因大致来自于以下几个方面:
1、需求方面:需求定义不清晰或者颗粒度太大、需求人员和研发人员以及测试人员对于需求的理解不一致等;
2、开发环节:单元测试未有效执行、对于缺陷的duplicate执行不正确、修改缺陷引入新的问题等;
3、测试计划方面:测试用例覆盖度不够、测试用例定义错误等;
4、测试执行方面:测试方法、测试环境、测试资源等;5.UI Design的不合理。
通过EDA的分析,我们可以得到以下分析数据:
并且能够得到更详细的报告:
通过以上分析,项目组可以调整各个环节的流程和方法。比如,需求细化、加强UT、测试用例更新、测试方法修正等等。
根据我们对于项目的跟踪,EDA的分析对于遗漏缺陷率的降低还是起到了积极有效的作用。
怎么样?让我们一起来EDA吧?
版权声明:本文出自 cmriqa 的51Testing软件测试博客:http://www.51testing.com/?489136
原创作品,转载时请务必以超链接形式标明本文原始出处、作者信息和本声明,否则将追究法律责任。
(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,另外还包括一些之前版本不具备的企业级的特性。一些专业顾问可能不希望你知道的东西:
你并不需要在你的开发过程中作出重大改变就可以从敏捷原则得到很多好处
如果你花时间去真正了解敏捷(而并不只是在网络上重复的徘徊于支持和反对中),你就会认识到事实上敏捷开发并不是一种方法论,而是一种可以应用于每个软件开发的方法。当然,像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 集成到实践测试中。最后,你也将确保你的程序员遵守“你把它弄坏了,立刻你修复它!”的黄金规则。
知识型工作者只有让他们感到被尊重,被认可才能激发出他们的工作热情。制造业工厂监工式的管理方法,绝对量化的考核指标在知识型团队管理中将会失效,
这是管理人员面临的挑战,德鲁克也在《卓有成效的管理者》中对管理者和这种监工做了明确区分,其中的观点是监工是上司,但不是管理者。
一个抱着积极、认真负责,打拼事业心态的员工做事的有效产出和机械完成任务的人员的有效产出是多么的不对等,这里不需要再列举各类研究结果。尊重是激励文化构建的基石,如果没有尊重,激励就是空中楼阁亦或是短暂的激情。本篇笔记重点谈谈在项目管理过程中对如何给予员工足够的尊重。
1、项目的意义
成就感是让团队努力向前的最好激励方案,任何项目的成立都是有意义的,如果能够让整个项目团队时刻清晰的认识到自己是再做一件对部门、乃至对公司意义重大的事,则往往能够焕发出团队很强的战斗力。受到关注就会给人被看重感,人就感觉到要对事情付更多的责任。
推荐策略:
1)项目启动时,高层领导进行动员,宣传项目意义
2)项目中期,规划负责人/项目经理要能定期发出一些市场人员/客户对项目的期望
3)项目结束后,高层领导要能够反馈项目获得的成绩
2、项目时间估算
我个人比较推崇的估算方法是自下向上的估算(具体可以上篇文章:时间估算的三步曲),自下向上的估算能够给予项目组员一定的发言权及主人翁感,并且能够调动大家责任心,通常大家愿意为自己的决定负责,但是如果是领导直接压下来的任务尤其比较紧急时,通常有些抵触。当然在自下向上的估算中,要有专家进行指导和把关,包括估算漏掉的哪些事情,项目组内例行需要消耗的时间等,并且针对”狮子大开口“的时间需要进行讨论,达成一致。
在这种估算方法做出的项目计划下,如果项目最后出现了问题,尽管项目经理要承担直接责任,但是项目团队成员通常会比较自主的愿意与团队共度难关。因为决策是大家一起制定出来的。
推荐策略:尽量使用自下向上+专家指导的方法进行估算,如果有人员到位或者估算周期的有限制,至少要保证关键人员的参与,而慎用自上向下的估算方法.
3、善用加班文化
IT公司加班是件很自然的事情,如果哪家公司没有加班情况,反而会让人感觉不正常。做为项目经理应该首先理解,加班虽然是IT公司的普遍现象,但是确实是组员为了项目做出了额外的奉献,他们牺牲与家人团聚的时间,牺牲了休息时间,甚至影响了健康。这种行为值得我们尊重,我们要小心使用这项权力。
1)不要动不动就抛出一句“这个今天搞不定,就打地铺解决”等,这种言论是对员工额外奉献的一个严重的漠视,而且带着很强的个人意愿
2)时时保证项目的进展的透明性,可以通过周会,日报的形式在团队中发布。当遇到赶工时,跟当事人讲解当前团队面临的困难,总之,加班是个艰难的决定,是为了整个团队的绩效,不是项目经理的个人意愿
3)任何加班时项目经理都应该尽量身先士卒带队
4)在一些公共场合,尤其有上级领导在时,公开表扬那些为团队做出很多额外贡献的人
5)绩效考核肯定以结果为导向,不能以加班多少论英雄,但要有其他措施安慰最辛苦的人
推荐策略:加班是一种奉献精神,我们要小心使用,认真对待。不能简单的当做管理者的权力,轻言肆用,否则久之必招其离心。
4、开放沟通的团队氛围
人都希望自己能够有发言权,能够对关心的事情产生影响。上至国家领导人的选举,下至日常的工作生活。如果发言权被长期压制,就会产生压抑和叛逆的心理。因此构建一个具有开放沟通的团队氛围则显得很重要。而往往言路开明后,项目经理总是能在一些讨论中,得到很多比预期更好的解决问题的方案。一个强权的管理者,容易获得一定程度上的执行力,但是容易被自己的盲点击败。而一个开明的管理者,往往能使用集体智慧,获得跟随者,更容易产生威望。
推荐策略:
1)项目沙盘等关键策略制定时,要全体项目参与讨论
2)项目经理鼓励大家发现问题,提问问题,对于好的措施,能够采纳执行
5、责任到户 VS 大锅饭
从头到尾的责任到户制应该是最理想的工作分配方式了,在这种分配方式下,团队成员有一块自己土地,通常愿意花更多的时间与精力去耕耘(例如:某个全新的模块),如果这个模块又是他一直想尝试的方面,那将会更加完美,我们有理由相信他将会在这里充满了激情。
然而世界上总没有十全十美的事情及百分百通用的方案,尽管责任到户制如此之好,但是在某些项目上我们达成不了这样的期望。
我所亲身经历过的两个版本就遇到了这样的状况。两个版本的共性是:在一个很大的系统上做覆盖面很大的,很多小点的修改(例如:更换所有UI系统),但是基于老系统的复杂性及历史问题,项目在中会遇到很多bug,各种各样,在bug没有查到原因之前并不好确定这个问题谁改动引发或是谁的责任,这种情况下责任到户制会出现失效。在面对系统这么多的bug时,项目经理很容易想到一种方法:“那就是给大家分配bug数,下指标,每天每人要解决3-4bug等”。两次项目经历中,项目经理确实都想到了这种方法,区别是前者实施了,后者被我阻止了。原因如下:
1)团队组员容易产生不被尊重感,被当成解决问题的机器
2)团队之间的协作会发生困难,而且过度强调这项指标,例如谁每天不修改完这个bug数,就要加班到10:00之类的,会导致部分组员开始取巧,每天争抢容易处理的bug
3)没法发挥人的主动性,将团队目标和个人目标相背离
这种情况下大锅饭的机制似乎更合适一些,如果团队没有达成目标则需要一起想办法或加班解决,而不是将这人归咎个某个人。
推荐策略:在正常项目中尽量使用责任到户制,而对于一些特殊项目,则选用大锅饭制,没有一成不变的方案,具体情况具体变通。
相关链接:
项目实战笔记之一:高效会议的组织方法
项目实战笔记之二:风险管理
项目实战笔记之三:时间估算的三步曲
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。
因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。类似地,如果在“不安全”的Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。
Properties属性文件在JAVA应用程序中是经常可以看得见的,也是特别重要的一类文件。它用来配置应用程序的一些信息,不过这些信息一般都是比较少的数据,没有必要使用数据库文件来保存,而使用一般的文本文件来保存,如果是通过File直接保存的话,可能在存储和读取上都不是很方便,但如果保存为Properties文件就不一样了,属性文件都有键值对应的,在JAVA的包中,有提供专门的操作属性文件的类。这个类就是 java.uitl.Properties类,由于Properties类是一个集合类,所以,Properties会将属性以集合的方式读写。
注意:下面的代码中对于抛出的异常都未采取捕获的方式,自己在编写程序的时候一定要注意捕获异常,推荐将捕获的异常处理掉。
Properties类继承字Hashtable类,采用键值对应的存储方式,在使用Properties类管理属性文件时有什么方便的呢?Properties类有专门的读写方法来读写Properties属性文件,不用担心读写的格式问题,只要为Properties类提供一个读写流即可。Properties用于读写属性文件的方法分别是:
- //读取属性文件流的方法
- public void load(InputStream inStream) throws IOException {}
- //写属性文件流的方法
- public void store(OutputStream out, String comments) throws IOException {}
|
首先,我们来看看如何从一个属性文件中读取属性。
假定我们已经新建了一个属性文件,名为prop.properties,内容如下:
sitename=abcjava
siteurl=www.abcjava.com
我们要做的第一步就是要将文件读取到Properties类对象中,由于load有一个参数是InputStream,所以我们可以用 InputStream的子类FileInputStream将属性文件读取到Properties对象中,知道prop.properties的路径,我们就用FileInputStream(String name)构造函数:
- Properties prop = new Properties();//属性集合对象
- FileInputStream fis = new FileInputStream("prop.properties");//属性文件流
- prop.load(fis);//将属性文件流装载到Properties对象中
|
接下来我们将做的事情就是如果读取一个属性,因为属性文件中的每一行都是一个键值对应,所以每一行都代表了一个属性对象,每一行都将以键和值的关系存储到Properties中,Properties类提供了getProperty(String key)方法用来通过键名读取键值,当key在属性集合中找不到时又想为key在程序中赋予一个值时可以使用public String getProperty(String key, String defaultValue)方法,这个方法的意思就是用指定的键在属性列表中搜索属性。如果在属性列表中未找到该键,则接着递归检查默认属性列表及其默认值。如果未找到属性,则此方法返回默认值变量:
- //获取属性值,sitename已在文件中定义
- System.out.println("获取属性值:sitename=" + prop.getProperty("sitename"));
- //获取属性值,country未在文件中定义,将在此程序中返回一个默认值,但并不修改属性文件
- System.out.println("获取属性值:country=" + prop.getProperty("country", "中国"));
|
在知道怎么读取属性文件之后我们还有一个很重要的事情就是要修改和添加新的属性到属性文件,这里就是使用public void store(OutputStream out, String comments)方法,这个方法是将属性集合写到一个OutputStream流中,同InputStream流一样,这里同样是使用其子类 FileOutputStream(String name),这里就不多说了。
在保存属性集合到文件之前,我们还有一件事情就是如何修改和添加新的属性到属性集合,这里使用了一个方法就是 setProperty(String key, String value),这个方法就是当属性集合中存在指定的key时,就修改这个key的值,如果不存在,就新建一个key,同样是通过键值关系保存的,但值得注意的是,Properties类继承自Hashtable,所以也可以用Hashtable的put和putAll方法保存,但强烈反对使用这两个方法,因为它们允许调用方插入其键或值不是 Strings 的项。相反,应该使用 setProperty 方法。如果在“有危险”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。那好,下面我们就来看看修改、添加和保存属性的程序:
- //修改sitename的属性值
-
- prop.setProperty("sitename", "Boxcode");
-
- //添加一个新的属性studio
-
- prop.setProperty("studio", "Boxcode Studio");
-
- //文件输出流
-
- FileOutputStream fos = new FileOutputStream("prop.properties");
-
- //将Properties集合保存到流中
-
- prop.store(fos, "Copyright (c) Boxcode Studio");
-
- fos.close();//关闭流
|
接下就是整个程序的源代码:
- import java.io.FileInputStream;
-
- import java.io.FileOutputStream;
-
- import java.util.Properties;
-
- public class PropertyEditor {
-
- public static void main(String[] args) throws Exception {
-
- Properties prop = new Properties();// 属性集合对象
-
- FileInputStream fis = new FileInputStream("prop.properties");// 属性文件输入流
-
- prop.load(fis);// 将属性文件流装载到Properties对象中
-
- fis.close();// 关闭流
-
- // 获取属性值,sitename已在文件中定义
-
- System.out.println("获取属性值:sitename=" + prop.getProperty("sitename"));
-
- // 获取属性值,country未在文件中定义,将在此程序中返回一个默认值,但并不修改属性文件
-
- System.out.println("获取属性值:country=" + prop.getProperty("country", "中国"));
-
- // 修改sitename的属性值
-
- prop.setProperty("sitename", "Boxcode");
-
- // 添加一个新的属性studio
-
- prop.setProperty("studio", "Boxcode Studio");
-
- // 文件输出流
-
- FileOutputStream fos = new FileOutputStream("prop.properties");
-
- // 将Properties集合保存到流中
-
- prop.store(fos, "Copyright (c) Boxcode Studio");
-
- fos.close();// 关闭流
-
- }
- }
|
1、C++创建对象方式
在C++中我们可以采用如下两种方式来创建对象,
1 Dog dog;//Dog为类名 2 Dog *p =newDog(); |
这两种方式在C++中都能完成对象的创建,但是在内存中的处理却完全不同。
对于第一种方式而言,dog是被存储在栈中的,占用的大小是Dog类中成员变量占用内存的和,此处不包括成员方法,因为成员方法是存放在公共存储区以便所有该类的对象都可以访问的。
图1 C++创建对象方式1的内存分配
对于第二种方式则不同,该方式使用了指针,在定义*p时在栈中开辟一个4字节的空间,new Dog()时在堆中开辟一块空间,然后将该空间的首地址赋值给*p,这样,通过*p就可以找到对象在堆中的任何成员方法了。
图2 C++创建对象方式2的内存分配
2、Java创建对象方式
在C++中我们有两种创建对象的方式,而在Java中只提供了如下的一种方式,
JVM在进行内存管理时,首先会在栈中给dog分配一个空间,当new Dog();后会在堆中开辟对象的实际空间,然后将dog指向堆中的空间,这样我们就可以方法对象的成员变量了。
图3 Java创建对象方式的内存分配
3、总结
通过图2和图3我们会发现Java创建对象的方式和C++创建对象方式的第二种很像,除了我故意写的p和dog还有数字,其他的都是一样的。是这样的,他们的确很像,但是却不完全相同,在C++中p是一个指针,通过指针我们可以访问内存中的任何地址,可以肆意的对内存做处理,然而在Java中 dog是一个引用,可以理解成是C++中指针的一个封装,我们不可以想在C++中用指针那样在Java中直接的进行地址++操作,这样一来就保证了内存的安全,这是C++和Java的很大不同。
本人文字功底极弱,若有描述不清或不当之处,望大家指正,感谢各位花费时间阅读完毕。