qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

我的软件测试之旅:(9)行动——简化测试文档和流程

  现有的各种测试相关文档都很齐备,但是已经有较丰富经验的我感觉到其中的信息有很多都是不必要的冗余,老早就想把它们给简化简化。因为我这个人总觉得,如果是没有必要的或者不需要的信息,为何一定要放在文档里呢,直接不写不就行了么?放在那里总会吸引人去看一眼,然后心想“哦,N/A。”,这也是时间和精力的浪费啊!保持文档干净整洁,只记录有意义的信息,不是很好么。而且,在原来的测试管理工具中,测试用例和测试计划,都有很多不同的版本,针对的是不同的产品发布版本。版本多也好的,但问题就是有的时候时间上最新的版本不一定是信息最新的,对于后续的测试人员来说,这会增加他们的工作量。还有就是每一份测试计划所描述的都有局限,所有的信息都是针对当时的那个版本测试任务,针对其中所要验证的功能,而这只是被测对象所有功能的一个子集,看不到一个整体的景象。

  Scrum试点项目提供了这样的一个机会,可以去操作这种简化,因为我是第一个,也是项目团队数量扩张前的唯一一个测试出身的团队成员,一定程度上享有一锤定音的权力。而Scrum这种开发模式,要求测试用例的全集必须能持续地体现被测系统的全景,因为每一个迭代所新开发出来的功能都要进行验证,而之前已经存在的功能也需要进行回归测试(其实在敏捷的方式下,“回归”这个说法已经没有了意义),因此我们必须随时都掌握着当前最新的测试用例集合。而另一方面,增量式的开发需要频繁地回归验证以前的功能,对手工测试的方式来说这是不可能完成的任务,必须秉持100%自动化的思想,而这也正是我的坚持。不过当时我和Scrum Master以及项目经理在100%自动化上的意见有些出入,为此交流过无数次,我记得最后我们还是坚持了100%自动化的想法,因为我确确实实就做到了。

  自动化的地位得到提升,间接地使得另一个问题浮出水面,也即测试计划。在传统的模式中,由于测试工作大多根据模块或者领域来划分,以单个项目的形式来进行管理,持续时间较长, 每一个测试项目所要验证的功能数目也比较多,因而需要安排一个单独的测试计划环节,还需要产生出测试计划文档,并且由相关人士来评审。但是在Scrum这种迭代增量式开发方式下,每一个迭代所开发的功能数量都不会很多,而要执行的测试用例却呈现不断增加的趋势,因为它要执行新功能测试用例加旧功能回归测试用例。对于测试计划这个活动来说,如果每一个迭代都要开测试计划评审会议,产生测试计划文档并且得到批复的话,将会是一笔非常大的管理性开销,而且每一个测试计划的重复信息量都很大,还会产生很多的版本。因而测试计划这个活动在Scrum模式下必须得改变才行。

  还有一个收到影响的就是缺陷追踪实践。我们也就是4个人的团队,而且都坐在同一个会议室里,面对面肩并肩。如果发现一个缺陷,还得打开IE浏览器(呃,其实我用FireFox更多一点),打开缺陷追踪系统的网页,输入各种信息提交缺陷报告,等待邻座的开发人员在专心写代码的时候收到通知邮件,打开网页,研究分析缺陷相关的信息,然后再给我提要求,然后我们再通过网页来回几个回合?当然这样做很没有必要,我们自然是可以面对面交流的,但是交流完解决了问题,我们是否还需要记录呢?将这样的问题记录到缺陷追踪系统中去,到底有没有意义,毕竟记录信息也还是要花时间的,而这样的问题可能在一个迭代里会遇到很多,还有可能很多缺陷并不是什么大问题,几分钟可能就改好了,要记录吗?

  还有一个问题就是,在传统的模式中,等到测试人员开始工作,通常都是代码已经开发完毕,有较稳定的产品版本供测试人员使用。但是在Scrum的模式中,在一个月的迭代周期里,我们是否也应该如此操作?这样做的问题在于,在迭代刚开始的那一段时间里,开发人员很忙,测试人员却很空,空得无事可做,到了迭代快结束的时候却是忙得不得了。更让人担心的是,如果这么晚才开始测试,测试又发现了不少的软件缺陷的话,剩下的时间根本就不够给开发人员用来修复缺陷。这样的开发过程必须得有变化。还有就是,每一个迭代都会拿到不同的新功能开发任务,但这些新功能的情况会有不同,有的功能开发任务相对较轻松却需要花不少功夫测试,有的功能则是开发很困难测试很容易。因此必然会出现在一个迭代当中,开发测试工作所需要的工作量比例不同,但此时开发测试人员的比例在一个团队中确实保持不变的,在Scrum保持团队稳定的原则前提下,如何处理这样的情况呢?

  这些都是我想要利用Scrum试点项目这个机会,或者是作为Scrum试点项目中的测试人员必须要思考解决的问题。

相关链接:

我的软件测试之旅:(1)起点——作为软件开发人员

我的软件测试之旅:(2)转变——作为专职测试人员

我的软件测试之旅:(3)同期——加入测试自动化小组

我的软件测试之旅:(4)并行——自动化回归测试

我的软件测试之旅:(5)难点——功能改进的测试

我的软件测试之旅:(6)跳转——追逐新鲜事物的探险者

我的软件测试之旅:(7)启程——Scrum中的测试工作者

我的软件测试之旅:(8)困难——没有现成的测试工具

posted @ 2012-08-08 09:34 顺其自然EVO 阅读(291) | 评论 (0)编辑 收藏

软件测试用例的设计

  一个测试用例,就是设定输入数据,运行被测试函数,然后判断实际输出是否符合预期。输入数据是测试用例的核心,输入数据的定义是:被测试函数所读取的外部数据及这些数据的初始值。

  1、自动测试工具的选择

  目前通过使用自动化工具对于软件的质量进行保障已经司空见惯,我们可以通过在测试中应用自动化工具来大幅度提高软件测试的效率和质量。常用的白盒测试自动化工具有Telelogic公司的Logiscope软件、Compuware公司的DevPartner软件和IBM公司的Rational Purify等;而黑盒测试工具主要有IBM公司的Rational系列如TeamTest、Robot,Com-puware公司的QACenterm等。

  2、测试用例中输入数据的选择

  用一定的规则选择有代表性的数据作为输入数据,主要有三种:正常、边界、非法输入,每种输入还可以分类,也就是平常说的等价类法,每类取一个数据作为输入数据,如果测试通过,可以肯定同类的其他输入也是可以通过的。下面举例说明:

  (1)正常输入

  例如字符串的Trim函数,功能是将字符串前后的空格去除,那么正常的输入可以有四类:前面有空格;后面有空格;前后均有空格;前后均无空格。

  (2)边界输入

  例中空字符串可以看作是边界输入。再如一个表示成绩的参数,它的有效范围是0-100(百分制),那么边界输入有两个:0和100。

  (3)非法输入

  非法输入是正常取值范围以外的数据,或使代码不能完成正常功能的输入,如上例中表示成绩的参数,小于0或大于100都是非法输入,再如一个进行文件操作的函数,非法输入有这么几类:文件不存在;目录不存在;文件正在被其他程序打开;权限错误。单元测试与代码编写是“一体两面”的关系,编码时对上述三种输入都是必须考虑的,否则代码的健壮性就会成问题。

  在设计测试用例时,应当包括合理的输入条件和不合理的输入条件。合理的输入条件是指能验证软件的输入条件;不合理的输入条件则是指异常的、临界的、可能引起问题异变的条件。用不合理的输入条件测试软件能核实软件的容错能力和完全性,往往比合理的输入条件能发现更多的错误。

  3、预测输出结果

  合理设计测试用例,适当选择测试方法完整的测试用例不但需要测试的输入数据,而且需要对应这些输入数据的预期输出结果。

  在使用白盒测试时,最理想的情况是希望能够执行到每条路径,但由于软件需求的不完整性、软件逻辑路径的组合性、输入数据的大量性及结果多样性等因素,哪怕是一个极其简单的程序,要想穷尽所有逻辑路径,所有输入数据和验证所有结果是非常困难的一件事情。在这里我们举一个简单的例子。

#include <jostrcan。h>
void main( )
{ int a,b,c,t,I;
cout<<”input x,y,z”<<endI;
cin>>x>>y>>z;
if (x>y) {t=x;x=y;y=t;}
if(x>z) {t=x;x=z;z=t;}
if(y>z) {t=y;y=z;z=t;}
cout<<”the result is:”< <x< <y< <z< <endi;}

  这个例子基本上保证了每条路径至少被执行了一次,代码中没有循环,只有三个if语句,它就是代码中的多路径源,共形成了6条路径,如表1所示。

  表1 三个if语句形成的6条路径

条件

If

If

If

结果

x>y

x<y

x< >z

x<z

y>z

y<z

x< >y

x<y

y< >z

x<y

 x>z

 x<z

 x<z

 x<y<z

 x<y<z

  为了测试这些数据,必须组织6组数据,每组数据测一条路径。请看表2的测试套和期望结果。

  表2 6组数据的测试套和期望结果

输入

第一步

第二步

第三步

期望结果

5,4,6

4,5,6

6,5,4

5,6,4

4,6,5

6,4,5

4,5,6

 4,5,6

 5,6,4

 5,6,4

 4,6,5

 4,6,5

4,5,6

 4,5,6

 4,6,5

 4,6,5

 4,6,5

 4,6,5

4,5,6

 4,5,6

 4,5,6

 4,5,6

 4,5,6

 4,5,6

4,5,6

 4,5,6

 4,5,6

 4,5,6

 4,5,6

 4,5,6

  4、妥善保留全部测试用例

  软件测试开发过程中,一定要做好测试用例的保存工作,这样在测试人员发生变动或者开展回归测试时会减少许多工作。我们在在程序改良或者Bug改正后需要重新测试时,就避免大量的枯燥乏味的重复工作,从而在提高测试效果的同时也相应的节省了软件开发成本。

  5、测试用例设计的误区

  在确定测试用例设计目标时,一些项目管理人员强调测试用例“越详细越好”。这种做法和观点最大的危害就是耗费了很多的测试用例设计时间和资源,可能等到测试用例设计、评审完成后,留给实际执行测试的时间所剩无几了。因为当前软件公司的项目团队在规划测试阶段,分配给测试的时间和人力资源是有限的,而软件项目的成功要坚持“质量、时间、成本”的最佳平衡,没有足够多的测试执行时间,就无法发现更多的软件缺陷,测试质量更无从谈起了。



posted @ 2012-08-07 14:03 顺其自然EVO 阅读(435) | 评论 (0)编辑 收藏

我的软件测试之旅:(8)困难——没有现成的测试工具

新的测试工作面临的第一个调整就是无法使用熟悉的工具,之前的工具是根据产品的操作系统平台以及人机接口进行了封装的,而新的Linux系统显然还不在他们的关注范围内。于是我得另寻方法,方法当然也简单,因为被测对象也就是我们所开发的东西,就是在Linux下运行的应用程序,其中有些核心模块(Kernel Module),只要通过Shell脚本使用相关的命令就可以完成测试了。

  Shell脚本只能够做到一个测试用例,写一个Shell脚本,于是有大量的重复,测试自动化上已经有丰富经验的我自然难以接受,不过暂时也无能为力,毕竟我还不具备单独开发出一个测试自动化框架的能力。只能够在单个Shell脚本中去执行多个测试用例,在脚本内抽取出一些公用代码,做成函数,最大的缺陷就在于测试的颗粒度不够清晰,以及测试用例之间的耦合度太高。

  在Linux系统下进行测试,了解一些基本命令是必然的,比如查进程清单、输出重定向之类的命令。由于没有现成的函数可以使用,要能够处理应用程序或核心模块的输出,进行自动化的测试结果收集和分析也需要了解一些文本操作的高级命令,例如awk和sed等,最好还要懂得怎么使用正则表达式,才有可能从瀚如烟海的日志输出中快速地识别出所要寻找的信息。

  一点点的编程能力也是需要的,有时候开发的功能就是为系统其他应用程序和模块提供服务,测试的对象就是它们提供出来的API(Application Programming Interface,应用程序编程接口),就只能够自己写一些测试用小程序,在程序里面调用这些API,并通过输出一些日志信息来进行测试。

  所幸的是,后来测试自动化小组又从芬兰引入了一套新的框架,也是口碑非常好,我后来也非常的喜欢,爱不释手。这套框架叫做robotframework(www.robotframework.org),目前已经开源。它提供了Telnet的库,可以通过Telnet协议和我们的被测设备交互,向被测设备写入命令,以及获得输出,从而完成测试。框架本身的测试用例的格式也很简单,当时主要支持Excel的CSV格式和HTML表格格式,我偏好其中的表格格式。表格格式的意思是,在一个HTML文件中(或者叫页面上),有四个表格,每个表格分别具有不同的含义,框架本身会区别对待其中的信息,加以处理。根据其表格的内容和格式,填入文本化语言,而不是脚本语言或是编程语言的函数调用,就是文本化的语言,写好保存,这就是一个测试用例,也是一个测试脚本了。文本化的语句需要有对应的库函数才可以真正产生作用,例如“Get Page Title”就得有类似于相应的getpagetitle()库函数,库可以用Java或者Python语言实现。

相关链接:

我的软件测试之旅:(1)起点——作为软件开发人员

我的软件测试之旅:(2)转变——作为专职测试人员

我的软件测试之旅:(3)同期——加入测试自动化小组

我的软件测试之旅:(4)并行——自动化回归测试

我的软件测试之旅:(5)难点——功能改进的测试

我的软件测试之旅:(6)跳转——追逐新鲜事物的探险者

我的软件测试之旅:(7)启程——Scrum中的测试工作者

posted @ 2012-08-07 11:55 顺其自然EVO 阅读(321) | 评论 (0)编辑 收藏

探索性测试需求思路

  卖点测试法:

  新需求必需强调功能特性的卖点,关键功能点,核心业务点(哪些必须实现),以user story的故事提出。并且要说明场景的特性,差异化优势,

  必备条件:规划经理提交需求时明确客户可能的用户场景

  备注:当前的需求经常是一句话就列出了需求,必须细分

  质疑测试法:

  为什么是这样的客户场景?场景是否合理不是规划经理一个人的事,需要进行讨论。我们要敢于质疑场景的合理性,做出来的产品不能脱离客户,我感觉市场人员对需求可能会比测试人员更加清楚;研发体系的模块专家对设计更加清楚;市场人员会质疑,如果客户这样操作会怎么样;而模块专家会从模块实现的关联分析提出自己的质疑

  必备条件:测试团队,模块专家和市场人员对规划经理的需求进行质疑,模块专家可以对这样的场景从设计上进行一定的质疑,这样设计有什么缺陷。4.2R1后期发现问题后才召集模块专家对规划经理提出质疑,取得了一定的效果,但我相信这个配合提前的话会更有效。

  破坏测试法:

  这个是基于风险测试策略的,一般我们实现功能会有一些业务节点,项目的转发功能业务大概是 A -->B -->C。考虑如果B挂了怎么处理?C挂了怎么办?(通过这样的质疑,发现了2个需求问题)其实这个也是质疑软件的实现,就是讲我们的业务实现分解成一个个小的功能特性,考虑如果下个业务节点失败,程序会怎么处理。

  必备条件:画出功能特性实现逻辑图,可以提前和开发一起代码走读(先粗略再细化)

  买一送一测试法:

  这个主要是考虑程序并发,如cgi同时下发,程序同时读取,结合AC可以想自动升级的,如果点一次就去请求一次升级,那还得了,所以最终实现是点一次升级后建立一个标志?。所以涉及到脚本,cgi,程序时可以考虑同时下发测试。

  快递测试法:

  用快递来比喻数据经过程序到达别的地方。其实现在我们更多的就是关联的数据分析不到位。我们要对功能特性进行分解,还是结合4.2R1分析,转发注销信息,那么注销信息的数据来源是什么?城市热点的注销命令,网关强制注销,无流量超时注销,心跳超时注销。。。我的思路是我们的功能肯定是用户操作什么的功能(功能就带着数据的流动),要对这个数据进行分析,还有哪些地方用到了这样的数据?(可以搜索版本project进行分析)。这个是数据的输入,输出同理。

  必备条件:和开发共同确认功能特性,列出影响到的数据

  上面的测试方法,在最近做的项目用到了一部分,也有部分是后期测试发现了问题后用的方法保证的质量。1,2可以在测试前期用于发现需求或设计问题。

posted @ 2012-08-07 11:51 顺其自然EVO 阅读(208) | 评论 (0)编辑 收藏

乱谈SQL Server数据库视图

  数据库里存储着大量的数据,但是为了保证数据的安全也为了方便,并不是所有用户的都可浏览所有数据。为此SQL Server里用权限、角色、视图来解决这一系列问题。本篇博客我先介绍视图。

  概念:视图是从一个或多个关联表中派生出的一个虚拟表,换句话说就是以一个或多个表中的部分数据组成的虚拟“表”。

  特点:

  一、分割数据,简化视点:即通过SELECT和WHERE语句来选择你关心的数据,而去除无关的数据。

  二、简化操作:视图可以避免对表的访问和存取操作,同时视图是一个很好的查询窗口。

  三、保护数据:针对用户创建视图,自动屏蔽权限外的数据。

  四、为数据重构提供一定的逻辑独立性:在关系型数据库中数据重构是不可避免的,最常见的是垂直分割为两个表,那么由于表中的数据类型和值并没有改变,所以只要稍微改动视图的定义既可以满足变更之后的表

  五、自动更新:在数据库结构不变的情况下,如果基表中的数据改变,会被自动的反应到视图中

  疑问:对于视图是一个对象,又是“虚拟表”,还具有自动更新的特点,引发了我对视图存储的思考:视图是对象说明视图创建后即被实例化,那么它应该是实际存在于数据库中的,它也确实存在。但是它是虚拟表又怎么解释呢?首先,它只能是以结果集的方式存储,每次打开就打开结果集,但是这样的话如何自动更新;或者是以T-SQL 语句才方式存储,每次打开便执行一次语句,这样就可以解释自动更新了,但问题是视图可能很大每次执行浪费资源。所以这两种存储方式并不科学。

  我查了一些资料,也咨询了学长、学姐,结果是没有结果。但经过讨论我认为,视图应该是以结果集的形式来存储的,同时存在着一种类似于触发器的机制来时时更新视图里的内容。这样的话视图的性质和特点就都可以解释了。当然这只是我的推断,不是事实,写出来只是想寻找答案。

posted @ 2012-08-07 11:13 顺其自然EVO 阅读(273) | 评论 (0)编辑 收藏

Java最优良的Adapter模式:适配器模式

  网上关于JAVA的适配器模式例子有很多,但真的有少实在不怎么样,看也不懂。自己总结了一个在性能和结构上都很容易理解的Adapter模式。

  Adapter模式也叫适配器模式,是由GoF提出的23种设计模式的一种。Adapter模式是构造型模式之一,通过Adapter模式,可以改变已有类(或外部类)的接口形式。

  在大规模的系统开发过程中,我们常常碰到诸如以下这些情况:

  我们需要实现某些功能,这些功能已有还不太成熟的一个或多个外部组件,如果我们自己重新开发这些功能会花费大量时间;所以很多情况下会选择先暂时使用外部组件,以后再考虑随时替换。但这样一来,会带来一个问题,随着对外部组件库的替换,可能需要对引用该外部组件的源代码进行大面积的修改,因此也极可能引入新的问题等等。如何最大限度的降低修改面呢?

  Adapter模式就是针对这种类似需求而提出来的。

  Adapter模式通过定义一个新的接口(对要实现的功能加以抽象),和一个实现该接口的Adapter(适配器)类来透明地调用外部组件。这样替换外部组件时,最多只要修改几个Adapter类就可以了,其他源代码都不会受到影响。

  实现Adapter模式的2种方法与范例

  Adapter模式通过在Adapter类中调用外部组件来实现功能。

  根据调用方式的不同,Adapter模式有2种实现方法:

  1、通过继承实现Adapter

  2、通过委让实现Adapter

  为了能更清楚地说明2种实现方法的区别,我们举例说明:

  比如,我们需要实现一个发送邮件的功能,需要用到一个名为OutMailer的外部组件,因为上述原因,我们决定用Adapter模式实现对OutMailer的透明调用。

  首先,我们把邮件发送的功能抽象成一个接口:

  1. IMailer.java  
  2. interface IMailer {  
  3.     //发送邮件 
  4.     publicvoid sendMail();  
  5. }

  然后定一个实现IMailer接口的MailerAdapter类。

  下面我们来看看MailerAdapter的实现方法。

  通过继承实现Adapter

  MailerAdapter.java

  1. class MailerAdapter extends OutMailerimplements IMailer {  
  2.     //发送邮件 
  3.     publicvoid sendMail() {  
  4.         //调用OutMailer.sendMail()方法实现邮件发送 
  5.         this.sendMail();  
  6.     }  
  7.     //这里省略其他方法 
  8. }

  通过委让实现Adapter

  MailerAdapter.java

  1. class MailerAdapter implements IMailer {  
  2.     private OutMailer outMailer =new OutMailer();  
  3.     //发送邮件 
  4.     publicvoid sendMail() {  
  5.         //调用OutMailer.sendMail()方法实现邮件发送 
  6.         outMailer.sendMail();  
  7.     }  
  8.     //这里省略其他方法 
  9. }

  不管是通过继承实现Adapter,还是通过委让实现Adapter,调用方MailerClient的调用方法完全一样,如下:

  MailerClient.java

  1. IMailer mailer =new MailerAdapter();  
  2. ...  
  3. mailer.sendMail();

  我们可以看到,这里完全没有直接调用OutMailer,也就是说OutMailer即使被替换了,我们也不用对MailerClient做任何修改。

posted @ 2012-08-07 09:40 顺其自然EVO 阅读(198) | 评论 (0)编辑 收藏

几行代码创建属于你自己的SQL数据库

创建数据库有多重方法,如可以使用企业管理器创建数据库,也可以使用向导创建数据库。上面两种方法操作都很简单,但却有一个很大的缺点就是他很难大规模重复。换句话说,如果你创建一个准备重新分布到世界各地的数据库,对于一个没有经验的用户来说,应付SQL企业管理器并建立数据库并不是一件容易的事。于是为了解决我们上面所说的难题,用T-SQL语句创建数据库的方法变应运而生。

  在讲语法之前我先给大家介绍下什么是数据库文件。数据库文件说简单点就是存储我们所需要的数据库的数据,或者事务日志。就好比文件夹是为了存储文件一样。

  在SQL Sever中有如下三种类型的数据库文件:

数据库文件类型

描述

主数据库文件

        是所有数据库的起点。这些文件不仅包含数据库用户收集的信息,还包含了数据库中所有其他文件的有关信息。每个数据库都有一个主数据库文件。主数据库文件的扩展名默认并推荐使用.mdf

辅数据库文件

        顾名思义它其实是那些你增加到数据库中的其他任何数据库文件。增加它们可以用来为数据库增大容量。不是所有的数据库都有辅数据库文件,但是如果想要你的数据库文件延伸到多个物理磁盘上,就需要有辅数据库文件。它的扩展名默认使用.ndf

日志文件

        用来保存数据库的事务日志。每个数据库至少有一个日志文件。日志文件的扩展名使用.ldf

  那接下来让我们认识Create Database语句的语法:

CREATE DATABASE <database_name>
      On [primary]
      [<filespec> [,…n]  ]
      [,<filegroup> [,…n]  ]
[LOG ON {<filespec> [,…n] }  ]
[FOR LOAD |  FOR  ATTCH  ]

  上面几句就是创建数据库最基本的语法,很简单吧。但是里面有些选项还是需要我们慢慢讲来的。

  其中的两个选项<filespec>和<filegroup>是什么意思呢?简单的说他们分别代表了创建一个文件和一个文件组所需要的信息,可能很难懂吧,不用着急我们看下面它们两个的语法。

<filespec>::=
                   (   [NAME=logical_file_name,]
                        FILENAME='os_file_name'
                        [,SIZE=size]
                        [,MAXSIZE={max_size | UNLIMITED}]
                        [,FILEGROWTH=growth_increment])  [,…n]
       <filegroupspec>::=
                        FILEGROUP filegroup_name <filespec>  [,…n]

  在SIZE、MAXSIZE、FILEGROWTH中如果大小的单位是兆字节(MB),则该单位可以省略,也就是说兆字节是缺省单位。但其它的表示单位不可省略。

  没晕吧(偷笑),没关系我们接着来看个例子。在下面的例子里,你可以建立一个数据库Test、一个数据库文件Test_Data和一个日志文件Test_Log:

  Create Database Test

         On primary

         (      name=’Test_Data’,

                 Filename=’c:\mssql17\data\Test_Data.mdf’,

                Size=10[MB],

                Maxsize=50[MB],

                Filegrowth=5[MB]   )

         LOG ON

         (      name=’Test_Log’,

                Filename=’c:\mssql17\data\Test_Log.ldf’,

                Size=5[MB],

                Maxsize=25[MB],

                Filegrowth=10%    )

          GO

  在SQL 2000中的查询分析器中执行后,你会看到一下的结果:

  CREATE DATABASE 进程正在磁盘 'Test_Data' 上分配 10.00 MB 的空间。

  CREATE DATABASE 进程正在磁盘 'Test_Log' 上分配 5.00 MB 的空间。

  上面代码括号中的部分即为<filespec>部分,是对创建的数据库的说明。怎么样,变的很简单了吧。


posted @ 2012-08-06 10:45 顺其自然EVO 阅读(353) | 评论 (0)编辑 收藏

分布式测试框架架构与思考(1)技术选型

  “工欲善其事必先利其器”。无论是哪个行业,这都是一句至理名言,软件测试当然也不例外。这也正是分布式测试框架(下文简称DST)设计的初衷。

  DST是海量数据项目背景下,为了解决测试集管理、运行、查询和测试执行、控制以及监控、日志数据的收集整理的一个通用型测试与分析平台。这个平台既包含了传统测试框架的特点也包含了自身的开创性思想。作为DST从前端界面到后端服务的亲身经历和开发者,下面我将从技术选型、架构设计、功能点分析、使用场景以及周边支持工具这几个角度来对DST测试平台做一个总结,进一步思考和回顾,以便发现不足和需要改进之处。

  --------------------------------------------------------------------------------

  第一篇  技术选型

  对于一个好的软件来说,技术选型无疑是最重要的一步,这将决定软件是否有良好的扩展性、健壮性、可靠性以及可维护性。对于DST来说,传统的B/S是一个显而易见的架构性选择,那么从前端到后端都需要有良好的Framework以及清晰的技术轨道与之配合。

  好的技术选型可以大大缩短开发周期,并提高代码的质量,减少bug产出率,优良的技术往往是具有清晰的结构化框架的,便于追踪问题,以及向其他开发者分享代码。

  技术选型贯穿了整个DST的设计与开发始终,并经历了多次回滚调整,最终采用现在的技术轨道并非是一件一帆风顺的事情。下表列举的是DST使用到的相关技术:

名称

描述

Webx

基于经典MVC设计模式的WEB框架,构建前端UI的主要骨骼脉络,具有清晰地层次化构造,良好的扩展机制。

Velocity

基于java的模板引擎,允许仅仅简单的使用模板语言(template language)来引用由java代码定义的页面对象。

ibatis

持久层框架包括SQL MapsData Access ObjectsDAO),是一种“半自动化”的ORMObject/Relation Mapping)实现。

Jeasyui

jQuery Easyui,基于jQuery的前端页面和javascript设计框架,简单且易于上手,封装的AJAX简洁易用。

HBase

一个分布式的、面向列的开源nosql数据库DST利用其实现海量监控和日志数据的存取。

Mysql

持久化前端以及测试数据。

HighCharts

一套界面美观的纯Javascript图表库。

RESTful

REST (REpresentational State Transfer)描述了一个架构样式的网络系统。

Ueditor

一个百度开源的富文本编辑器。

AJAX

交互式网页应用的网页开发技术。

SyntaxHighlighter

高亮显示代码用的Javascript库。

Thrift

Facebook开发的一个软件框架,用来进行可扩展且跨语言的服务的开发。

Jetty

开源的servlet容器。

  其他还有一些例如SimpleTip(浮动标签)、MapReduce(用来做nosql数据的定期备份)等技术,由于涉及不多,不再列举。

在整个DST的开发周期中,围绕技术选型,曾经发生过几次重要的争论,列举如下:

  1、框架之争

  DST之前有Kelude测试平台可以借鉴,Kelude采用Ruby语言的Rails框架,其特点是轻巧灵活,代码极少重复,开发效率极高。然而考虑到精通Ruby语言的程序员不多,后端服务的技术人员大多精通Java而非Ruby,且海量数据平台的大部分产品都是Java开发(如Hadoop),将来在DST与测试场景接合的时候,相同的语言可以省却很多麻烦。最终定选的Webx作为一个成熟的MVC设计模式,在淘宝的使用很广泛,有大量资料实例可以参考。

  持久层采用Hibernate还是ibatis,这要归功于我们团队的leader叶渡的技术选型,在后来的开发过程中,不谈外部的一般说法,我的感觉是ibatis结构非常清晰,sql语句完全被抽象到了sqlmap文件中,适合DBA以及其他开发人员对sql语句的审核。从DAO接口到之上的事务层,都可以通过ibatis很好的管理起来。但是ibatis从生成到增删改非常繁琐,增加一条sql语句,一般情况下至少要修改6、7个文件,这个过程很容易出错。

  2、UI设计之争

  作为后端测试工程师,因为我在DST立项开始的时候并没有太多的前端开发经验,因此在UI设计上,曾经发生过是否要专业UED参与的争论。这个争论虽然之后随着DST的开发渐渐消失,但此时提及,是为了记录我在设计过程中的一些思考。

  我觉得DST如果有专业的UED协助进行用户体验的设计那是最好不过的事情,但是对于此类项目的开发早期,很多功能点不是很清晰的情况下,由开发人员掌握住整个流程还是相当有必要的。开发者的亲身参与会省去许多探雷的过程,且测试人员自己才最清楚需要一个什么样的系统,UED的参与更多从普通用户角度思考,而测试框架作为一款特殊的软件产品,更需要从开发者角度去思考他们的操作习惯。

  3、海量数据持久化之争

  身处海量数据开发项目,自然少不了和动辄上千个节点的集群打交道,从这些集群收集到的监控数据和日志数据的量也可以用浩如烟海来形容。按常规经验,一个百台规模的集群,收集到的监控数据一年约有8TB,传统关系型数据库撑住这样的数据量还要保持高效的并发读写效率,往往需要一个很有经验的团队来支撑,分表操作会成为一个常态。而我们所需的查询动作往往又非常简单,基本上都是扫描一段时间内的数据。这恰好是nosql型数据库最擅长的领域。

  但是在这部分设计之初,我们发生了关于持久化是通过直接存取二进制文件方式,还是存取HBase方式之争。

  直接存取二进制文件方式的理由是,可以直接从RRD(Round Robin Database)数据库文件中读取所需的监控数据,对查询请求可以通过固定算法计算出数据所在位置后,用seek函数直接跳转过去进行连续读取,好处是速度快,硬件资源需求少。但这样的方式带来的问题,一是查询依赖于编程,不利于查询方式的扩展和数据挖掘;二是没有足够可靠的数据冗余备份方案,一旦机器损坏,数据就将发生不可逆转的丢失;三是扩展性不够,能够hold住百级别节点的集群,并不意味着我们仅仅只有百台机器需要存取监控和日志数据,一旦规模扩大,这样的解决方案将面临无法动态扩容的危险。

  最终我们选择了将监控和日志数据存到HBase中这个方案,上述的三个问题都不会发生。而在后来的设计中,我进一步发现与其从gmond保存的RRD数据库文件中读取监控数据,不如通过替代gmond master节点的方式来直接解析xml形式的监控数据。这样可以避免磁盘操作这个性能瓶颈,数据流完全是从内存到网络(gmond)再到内存(我们的工具)再通过网络到HBase集群的内存中。整个过程完全将没有磁盘这种慢速设备的干扰。关于这部分的详细设计思想,我将会在后文中继续描述。

  4、敏捷开发模式实施之争

  采用敏捷开发模式是DST设计过程中不可忽视的一个重要技术选型。按照书本上的定义:敏捷开发强调程序员团队与业务专家之间的紧密协作、面对面的沟通(认为比书面的文档更有效)、频繁交付新的软件版本、紧凑而自我组织型的团队、能够很好地适应需求变化的代码编写和团队组织方法,也更注重做为软件开发中人的作用。

  而DST在开发之初,有过一些并不是很适宜的对某些开发点的反复关注和修改,浪费了一些时间。这在随后持续进行的迭代开发周期中,还是需要警醒自身,并持续改善的。一方面避免代码浪费,另一方面还要和业务需求层面多进行沟通,以便做出的产品与实际需求之间偏差较小。

  综上所述,技术选型的过程并非是一帆风顺的,其过程尤其是人与人之间交互中,需要各方不断的争执和妥协。有些选型也并非一成不变,在发现问题之后,及时的回滚就可以了,最重要的是不可一条错路走到黑。而我们平时更愿意只选择自己最熟的路走,这对于开发产品来说并不是一件好事。

  我认为一个比较好的习惯是,无论遇到什么问题,哪怕是自己已有成熟想法的,都应该首先去搜索一下业界同类问题的解决办法,能够走大部分人共同走过的路,才是最安全可靠的。我们设计一个优秀的软件,做一个零散部件的组装者要比做一个从矿工开始的开发者需要付出的更少,且有更多的机会获得成功。技术选型正是一个选择零件的过程,这比架构的角色更为重要,无论拥有多么优秀的架构,一个足够分量的错误的零件都有可能会毁掉你设计的整座大厦。





posted @ 2012-08-06 10:41 顺其自然EVO 阅读(628) | 评论 (0)编辑 收藏

基于TestNG 与Selenium 的自动化测试设计与实施

  1、引言

  软件测试是关系到软件开发和维护成本的重要环节。任何软件产品在正式发布之前都必须经过严格的测试。随着计算机技术的迅速发展,软件的结构越来越复杂,同业竞争越来越激烈。为了保证软件产品的高度可靠性和竞争力,很多软件开发机构都将其主要的研制力量投入到软件测试之中。

  回归测试是软件测试中的重要组成部分,占有很大的比重。每次例行包发布前都需要对软件现有功能进行回归验证,确保无误以后才能发给各地现场,大家都知道电信业是个发展较快的行业,需求变更快、迭代周期短,从而导致回归测试十分频繁,这个时候如果单靠手工进行测试,会消耗大量的时间和精力,测试人员也随着耐心的减退而力不从心。为了避免这种情况,对于原有功能的自动化测试显得尤为重要。

  2、工具介绍

  说到开源自动化测试工具,网上众说风云,但别人说好的东西不一定适合你,我们在组合自动化测试工具时,根据自己的实际情况选择了 Selenium + TestNG + DBUnit组合,我先介绍一下这几种工具。

  Selenium,它所采用的原理是通过录制应用程序产生的线性脚本进行回放从而达到自动化测试的目的。其优点是简单,通过录制就可以得到所需脚本。类似于录制/回放测试工具有很多,我之所以选择它的原因是它是开源的,而且它测试直接在浏览器中运行,就像真实用户所做的一样。Selenium测试可以在 WindowsLinux上的 Internet Explorer、Mozilla和 Firefox 中运行。其他测试工具都不能覆盖如此多的平台,更重要的是Selenium支持多种语言、JAVA、Ruby、Python等(如图1)

图1

  支持这么多语言说明我们通过Selenium开发的测试脚本可以任意移植到多个平台,可以继承Selenium API来扩展一些我们自己的测试类,甚至可以在此基础上开发出一套属于我们自己的自动化测试平台,而其它工具,包括大名鼎鼎的QTP,SilkTest是有所不及的,虽然这些收费的软件后面有强大的技术支持,学习文档和参考资料也相当丰富,但这些工具的局限性太大,一旦使用这些工具,你就会越来越依赖人家的东西,从而无法沉淀出自己的技术,这是我选择Selenium的根本原因。

  Selenium 系列一共有4款工具

  Selenium Core:支持DHTML的测试案例(效果类似数据驱动测试),它是Selenium IDE和Selenium RC的引擎。

  Selenium IDE:FireFox的一个插件,支持脚本录制。

  Selenium RC:Selenium Remote Control。

  Selenium Grid:允许同时并行地、在不同的环境上运行多个测试任务,极大地加快Web应用的功能测试

  通过selenium编写测试case的理想化是先通过Selenium IDE录制脚本,通过Firebug辅助定位页面元素,然后通过Selenium RC来完善测试脚本。Selenium IDE是Firefox的一个插件,是可以进行脚本录制以及案例转换,所以Selenium IDE+Firebug会成为你日后写测试案例的两大助手,但遗憾的是上述两个工具都依赖Firefox浏览器,如果你的程序不支持Firefox浏览器,就只能通过手工编码来完成自动化测试脚本,对于初学者来讲,如果没有这两个工具的辅助,在编写测试脚本时还是比较困难的,但熟悉了Selenium API和掌握了页面元素查找的方法以后,这两个工具就显得没那么重要了。

 TestNG,单元测试工具典型代表,可能大部分开发人员只对JUnit比较熟悉,JUnit是 Java 语言单元测试当前的一站式解决方案。这个框架值得称赞,因为它把测试驱动的开发思想介绍给 Java开发人员并教给他们如何有效地编写单元测试。但是,在过去的几年中,JUnit的改进不大;所以,为当今复杂的环境编写测试已经变成一个越来越困难的任务,即 JUnit必须与其他一些补充性测试框架集成起来。而 TestNG是一个测试 Java应用程序的新框架。我选择TestNG是因为它是一种基于注释的测试框架,通过添加诸如灵活的装置、测试分类、参数测试和依赖方法等特性来克服JUnit的一些不足之处。此外,TestNG运行于Java 5.0(通过注释)和Java 1.4(通过JavaDoc样式的注释)之上。我来列举一下NG的优势:

  关键字:参数化。TestNG将数据驱动的自动化测试的概念诠释的淋漓尽致,我举个例子,一个被测试方法根据不同的入参组合出20个CASE,根据数据驱动测试的思想,我们只需要写一个测试方法,然后准备20种参数组合的数据。如果使用JUnit你可能需要写20个测试方法,而TestNG通过注释就可以实现参数化。将20种不同的入参组合整理到一个Excel文件中管理,文件里可以增加用例描述甚至测试方案等相关信息,如果增加新CASE,只需要增加一行测试数据即可,如图:

  测试方法只需要写一个,如图所示:

  关键字:失败和重运行,在大型测试套件中,这种重新运行失败测试的能力显得尤为方便。这是 TestNG独有的一个特性。在 JUnit 4中,如果测试套件包括 1000项测试,其中 3项失败,很可能就会迫使您重新运行整个测试套件(修改错误以后)。不用说,这样的工作可能会耗费几个小时。一旦 TestNG中出现失败,它就会创建一个 XML配置文件(如图4),对失败的测试加以说明。如果利用这个文件执行 TestNG运行程序,TestNG就只运行失败的测试。所以,1000项测试有3项 Failed,这种场景你只需重新运行三个失败的测试脚本,而不是整个测试套件。

  这里只列举了TestNG比较明显的优势,除了上述优势以外还有很多,这里就不详细阐述。

图4

 DBUnit,它通过有效地管理测试场景中的数据简化了使用数据库的工作。其设计理念就是在测试之前,备份数据库,然后给对象数据库植入我们需要的准备数据,最后,在测试完毕后,读入备份数据库,回溯到测试前的状态,通过DBUnit还可以辅助数据持久层的测试工作,如验证一个实体通过被测试程序(DAO)进行持久化的操作是否正确,验证数据实体是否按照预期写入数据库,并且提供了将数据从数据库与XML文件存储中互相转换的功能。

  上图是从客户表中导出的一条数据,如果测试过程中需要这条数据,那可以通过DBUnit将此条数据初始化到数据库中。

  还有一种情况,如果是新增一个客户,那这个文件里的数据可以用来做断言预期的依据,DBUnit可以将xml转换为DataSet甚至 JavaBean,你可以直接通过数据集进行比较而不是每个字段都要比较一次。

  不过DBUnit也有自己的缺陷,如上图所示,当通过DBUnit与数据库交互时需要检查表的主键,如果某张表没有设置主键就没有办法使用DBUnit的API,只能通过其它方式实现。

  Fitnesse,业务驱动测试的工具代表,FIT是一种通用的开放框架,将测试人员编写的测试方法转换成表格的形式展现给客户,常用于自动化验收测试,在页面上以表格形式记录测试用例输入、预期输出内容,自动运行并显示测试执行结果。但是增加了开发人员一些工作量,要想让fit与你的软件通信,需要自己编写Fit fixture来实现业务与程序逻辑的转换。



  3、自动化测试实施过程

  通过上面几种工具的组合,灵活使用,就可以搭建出一套适合自己的自动化测试平台。

  下面我来介绍一下,这些工具在不同测试场景下的使用情况:

  1)接口测试

  (TestNG+DBUnit)接口自动化测试可以通过单元测试来完成,利用TestNG对每一个接口编写单元测试代码,通过DBUnit初始化数据库,将一个或多个测试并被定义为<suite>标签,批量执行测试代码并生成测试报告。

  2)Webservice接口自动化测试

  目前大多数互联网公司都采用SOA架构,因此对于webservice接口类型的测试显得更加重要。通常测试工程师可能会借助SoapUI等工具进行web service的测试,不可否认SoapUI在进行单一webservice接口测试中具有非常好的效果,但是在接口组合测试,以及在测试结果需要进行数据库校验的情况下就显得不是那么的自动化,总是需要人工干预,这在一定程度上导致测试效率偏低,因此我们在这里介绍如何使用Fitnesse这块开源产品实现接口测试自动化(未完待有时间补充)

  3)WEB应用系统的自动化(Selenium +  TestNG + DBUnit)

  TestNG 尤其适合与Selenium结合使用,可以实现其他测试框架无法实现的测试,例如使用依赖项进行测试,重新运行失败了的测试,以及使用单独文件中定义的参数进行参数化测试。所有这些特性结合在一起,使它在众多 Web应用程序测试框架中脱颖而出。

  在测试自动化中,测试代码不仅仅包含测试逻辑,还包含许多其他的代码,比如URL拼接、Html/xml解析、访问UI控件,等等。若把测试逻辑与这些无关的代码混在一起,测试逻辑将很难理解,也不容易维护。而采用分层结构可以解决这一问题。在分层的测试框架中,其三层结构为:

  (1)数据层,包含UI数据和测试数据;UI数据是指在页面中需要输入的数据,如,普通客户新装,你需要在页面里输入三户信息,包括订购的产品及资源数据。这些通过页面注入的数据我们统称为UI数据,需要在执行测试前提前整理到Excel中,如图所示:


  实现起来比较容易,使用TestNG注释功能,就可以将这些数据作为页面的输入。而测试数据是指数据库中基础数据,这些数据是用来支撑整个系统运作的,比如操作员及组织权限,新装订购的套餐,套餐与产品的关系数据等等,没有这些数据,系统就没有办法正常运行,所以执行测试脚本之前要对这些基础数据进行初始化;还有一种情况当执行完一次测试脚本时产生的新数据会影响测试脚本的二次运行,这意味着运行任何测试之前,都希望数据库具有一组干净的数据,使用 DBUnit 的 CLEAN_INSERT 命令确保在先前运行的测试中创建的行被删除掉,因此我可以重新运行测试,该测试可以不断创建数据并且不用考虑数据库约束。将测试数据提前整理到xml文件,也可以从数据库直接导出到xml文件里,如图所示:

  在执行测试脚本前,通过DBUnit将这些文件里的数据提前初始到数据库里,这样一来数据库就是程序所期望的样子。

  (2)测试用例层,包含业务逻辑和控制逻辑。驱动程序WebDriver(Selenium2.0)负责UI数据的载入,在页面回放时将UI数据输入到页面中。前台页面回放完成后,数据进入持久阶段,这时需要比对后台业务处理逻辑,比如客户数据是否正确写入数据库,产品订购是否正确。由于输入的不同,场景的不同,业务逻辑比对也会不同,所以这块脚本的编写是整个环节中比较重要的部分。为了能够区分这些分支,需要将整个新装流程拆分多个模块进行管理,使用TestNG将测试用例分组,形成多个Test Suite进行控制。

  (3)待测系统层,与测试端完全分离,被测系统只需要提供URL通过HTTP协议就可以被测试脚本调用执行。

  4、自动化测试的持续集成

  持续集成是一种软件开发实践,对于提高软件开发效率并保障软件开发质量提供了理论基础,持续集成保障了每个时间点上团队成员提交的代码是能成功集成的。换言之,任何时间点都能第一时间发现软件的集成问题,也能尽快将测试脚本投入生产使用。

  通过SVN统一代码管理,在Ant或Maven脚本增加测试组件配置,当例行编译结束后即可以使用Hudson定时启动测试脚本的运行工作。运行结束后返回测试报告给测试人员。整个迭代周期如下图所示:

  5、结语

  软件自动化测试弥补了手工测试时重复劳动的缺陷,而且能在软件开发过程中尽早发现缺陷,因此实施自动化测试是非常有必要的。本文中介绍了几种自动化测试工具,通过不同的工具组合成适用自己的自动化测试框架,不仅使自动化测试在产品测试中发挥其独特的作用,而且还节约了资源成本,包括测试工具购买的成本以及人力资源成本等。







posted @ 2012-08-06 10:26 顺其自然EVO 阅读(2260) | 评论 (0)编辑 收藏

我的软件测试之旅:(7)启程——Scrum中的测试工作者

加入到Linux部门后不久,就遇到一个可谓千载难逢的机会。我们需要基于业内新的通信架构(ATCA,Advanced Telecommunications Computing Architecture)硬件,在Linux系统上实现公司老产品的功能。后来还要研究OpenSAF(Open Service Availability Framework),看看是否以及如何融入到我们的实现中去,我们还专门为之分配了时间,每天都有预留部分时间以供大家学习、交流。

  当时更让人激动的是这个新项目将采用一种新的软件开发方式,叫做Scrum。小组长问我想不想加入这个项目,我说先等等,这可是从来都没有听说过的玩意儿诶,晚上我突击学习,在网上疯狂地搜索资料,了解这个Scrum。如果我没有记错的话,当时(05年底)网上还没什么中文资料呢,都只有看英文的才行。最终,我被它所吸引,决定加入。除了Scrum本身,项目经理是吕毅(到目前为止还是唯一的中国人CST,Certified Scrum Trainer),我们的后援团包括我后来加入的Flexible Company(其实是公司内的一个团队,专注于支持敏捷转型),以及Bas Vodde和Craig Larman。而且,我加入的时候团队才只进行了一个Sprint而已,也算是赶了个早。团队仅有的三位成员都是很资深的同事,而且里面还有一位不挂名的架构师,在浙大读硕士的时候就已经和老师合著出版过Linux的著作,有这样的高手在,何愁学不到东西,又有何理由不加入这样的优秀团队呢?

  而我为他们提供的价值则是,专业的测试思维(注意不是能力)。我加入的第一个迭代,团队之前验证通过没有发现问题的实现,被我发现起码是二三十个问题,印象中这也一定程度上帮我赢得了大家的信任,认可我是个靠谱的测试人员。

  吸引我的另一个原因是自由度,这个项目得到了管理层极大的支持,由于Scrum模式在国外的研发中心使用收到了很好的效果,所以管理层决定引入杭州研发中心进行试点,也因此给予我们可以抛弃所有现有流程负担的自由,完全可以自主决定自己使用的开发流程。而之前的工作中,我们的测试流程和各种规范详尽完备但却显得有些笨重累赘,我早有想法要改变它,但自己对流程制定并无发言权,新项目则可以提供这样的自由。

posted @ 2012-08-06 09:57 顺其自然EVO 阅读(227) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 301 302 303 304 305 306 307 308 309 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜