发布新日志

  • 测试也辩论-测试用例颗粒度之粗细

    2010-07-29 20:08:24

    这话题之前内部也探讨过。
    今天参加淘宝的黑灯辩论,也是这个主题。

    正方观点:写细点好。细致到从操作上不可再拆分的程度。好处:覆盖率高、可操作性强、便于工作量评估、便于跟踪、便于新同学学习理解,等等。

    反方观点:写粗点好。突出测试思想框架,关注业务流程关注系统间交互,不纠缠页面细节,杜绝同类性重复用例。好处:养成有高度有宽度的测试思想,控制重复性细节性此类投入产出比低的投入。

    以上,是我替他们大致总结的观点。

    辩论本身并不是很精彩。但给我一个机会回炉自己的想法。

    这本身是一个伪命题。用例的粗细粒度,很难有标准,更难说一定是细好还是粗好。就像我的博客上写的,测试是艺术。既然是艺术,哪有标准可言,只有是否适合口味的差别。所以这肯定是没有标准答案的。

    但是,我们目前的实际做法中,肯定还是有倾向性的。我想批判一种倾向性的现象----对已知的浅显的测试需求,用例写到细的不能再细,而不花精力去思考未知的潜在的可能被遗漏的测试需求。这样下去,人慢慢就变成机器人了,只是反复的、一丝不苟的做那些已知的事情。线上故障会有,人的能力也不会上去。这个现象,暂且简称为机械主义。我想周遭是能看到这样的现象的。

    我比较倾向的做法是,平时,对于已知部分,凭借经验尽可能抽象出公共可用的用例,而且要写的足够细致全面。项目中,同类测试需求,稍微加以修改就可以保证高覆盖率;多腾出一些时间来思考未知测试需求,构建新的测试用例。如果项目中的测试需求全部是新的,没有历史的可用,那么在时间进度压力下,我倾向于“重”测试分析“轻”测试用例,从分析层面/思想层面保证测试的覆盖(抓准业务流程规则/资金流转规则/系统间交互规则/非功能测试需求等),如对于资金流转,其实你画个图比你写一堆测试用例要有用简洁的多,虽然它可操作性不强,有可能会导致测试执行偏差,但我宁愿选择把这个风险靠人员的责任心去弥补,而不是担心人的责任心而要求用例一定要细致细致再细致。况且,互联网的测试跟传统软件行业的测试是有差别的,要做到快速响应,就不得不有取舍,有策略。

     

  • 支付宝测试团队招聘英才啦

    2010-03-18 13:42:18

    支付宝急招资深软件测试工程师和资深测试开发工程师。详见 http://job.alipay.com/recruit/offerDetail.htm?offerId=21683

    有意者投递简历至resume@alipay.comling.gll@alipay.com.

    期待您的加入!

     

    工作地点: 杭州、上海

    1.参与软件产品的需求分析,关注项目需求的可测性,并能预先评估项目的风险;
    2.软件产品的测试方案制定和评审,帮助测试工程师提高测试分析和用例设计水平;
    3.负责重大项目的测试组织和指导,保持和PM以及项目组员有效沟通,协调问题和缺陷的有效解决;
    4.通过总结,对外交流,技术钻研和培训,协助主管进行测试过程和测试方法的持续改进,提升团队技术实力。
    1.计算机相关专业,本科及以上学历;
    2.至少3年以上软件开发和测试工作经验,3个以上大型项目的测试组织和执行;有J2EE软件架构设计和开发经验者优先;
    3.精通测试过程设计和用例设计方法, 至少在性能测试,自动化测试,白盒测试方面有一处专长;
    4.熟悉Linux或Unix操作系统,熟悉J2EE软件架构和常用脚本语言;
    5.能主动进行技术钻研,擅长辅导和培训。
  • 谦逊从容、创造变化是技术人不能丢的美德

    2009-10-27 19:52:36

    最近出去巡回校招。每天要面试二三十个人,用的结构化的面试方法,面对应届生,抛问题的差别不大,不时的还有人催你加油面,后面有好多同学等着呢。几天下来感觉自己像流水线的面试机器,有点焦虑有点浮躁。

    忽然有一天,看到邓老师在旁听孔宣老师的面试。我好奇了,得空也坐在边上旁听。听完,自惭形秽。孔宣老师的从容谦逊,把我从焦虑与浮躁中拉了回来。针对一个问题,他会一环扣一环的发问,学生答不上的时候,他会适当引导启发一下,甚至会给一些中肯的建议。学生会感觉跟一个学长在切磋技艺,我想如果我是学生的话,我会很喜欢这种方式。我们做面试官,除了要在既定时间内高效率的找到我们需要的人才,同时这也是一个传递我们企业品牌形象的平台,另外,作为同是技术相关人员这个群体来说,能作为学长给这些学生们一些引导和建议也是一件美差。

    很长一段时间以来,我一直觉得我还蛮爱动脑筋的、愿意创造变化的人,这次才发现其实这只是若干年前的虚幻记忆了。话说我们阅卷,手工的,我只是觉得工作量大有点累,但是还是要尽快做完。没去考虑如何优化阅卷方式。因为去年也是这么做的,而且今年还比去年好些,没有主观题了。孔宣老师一来,大大的抛了一个问题,为什么我们还是这么原始的阅卷方式,为什么答题卡和标准答案的格式不一样,批起来好累,为什么不动下脑筋搞的简单点?于是,后续组委会开展了优化阅卷的行动,明显的改进的阅卷效率,可以让我们早早的回宾馆睡觉而不是批阅到凌晨。

    总之,这次校招出去,最大的收获就是我似乎离谦逊从容、创造变化这样的技术人有点远了。有点诧异,因为之前没发现,有点惭愧,其实自己已经不知不觉变浮躁了。要不得啊。不过,回头是岸。

  • 测试质量控制

    2009-07-29 22:25:16

    软件测试,有几种形态,验证、排错、预防、控制。

    验证是最初阶的,只要基于需求,验证需求被实现即可。

    排错,其实有点像排雷了,除了验证以外,要确保基本范围之外隐藏地雷的排除。这个是有技术含量的,至少也是需要经验积累的。

    预防,主旨在于尽早介入,从需求、设计的层面提出问题、屏蔽问题。

    控制,其实是综合了验证、排错、预防的。但我今天想说的是一种主动控制意识。有这样一个案例:某项目发布上线了,线上报了一些问题回来,开发同学修复,测试同学回测。几周下周,处理了不少这样的问题。我跟测试同学说,看下这些问题为什么会漏测。看了之后,给我反馈是很多页面的查询功能没好好测,项目后期时间紧,没覆盖全。我说那赶紧补救。于是开展补救行动,做法是先整理查询面板的公用测试用例,然后再Review这些用例,然后再拿着这些用例去跑一下那些页面的查询功能。我问:这个要多久?回答:大概1周时间。我说:直接测要多久?回答:1天。我说:为什么不直接测?回答:本来安排进行补测的这个人不熟业务可能直接测不了。我说:有没有直接能测的人?回答:有。我又说:难道你们不担心这一周过去,不等你开始补测,线上又抛问题来了?如果担心的话,为什么不让能测的那个人直接补测?回答:......   后来是直接找了个熟悉业务的人补测了,1天时间发现了13个查询相关的缺陷,开发立马进行了修复......   这个简单的案例告诉我们什么?主动控制,这里的控制是赶在客户发现问题之前去发现问题,控制质量影响。

    对测试来说,其实本质就在于质量控制,开展一系列的控制活动,并且是主动、积极的去控制。

     

     

  • 测试工程师,成长需要加速度

    2009-07-20 18:19:50

    最近面试了不少人,有点小感慨。

    有的同学,做了5年测试,现场画一个业务流图,连个起点终点都没有。更不要说状态转换或时序了。

    有的同学,做了3年测试,你问她最擅长的是什么,她说她就是很细心耐心。汗滴。

    有的同学,做了4年测试,你问他正交用例设计法用过没?他说不知道。

    相当的恐怖ing,也很可悲。现在很多软件公司都有专门的测试工程师,要说给出去的薪水,或者给很多企业or用户作出来的软件产品那是一堆堆的。但大家的成长在哪里?

    大家都知道竞争很激烈,但是却太少的人真正关注自己的成长速度,更别说加速度了。

    当然我也有面到一些很优秀的。这些人的共同特征就是:注重自己在团队中的价值发挥(关注自己是否是个对团队有用的人,而不是做完委派的工作任务),注重在实战中积累(不是做过就完事,强烈追求下次做的更好),关注行业发展(有一些同行好友,经常切磋交流,而不是井底之蛙),关注自己的能力发展(有相对清晰的自我学习发展目标并定计划挤时间学习,而不是每天下班上开心网种菜还说我很忙)。

    其实不管是做哪个行业的,都要快速的成长。对于测试工程师来说,尤其的需要,因为相比于其他学科,这是一门历时还不算久的学科。如果你一直以这个行业还不够成熟来安慰自己,或者以这个行业会有很好的远景但现在还有很大的差距为理由来麻木自己的成长,那你已经被淘汰了。

  • 三角形关系的权衡

    2009-04-21 22:38:29

    某大型项目,PRD很差(差的意思是说后续开发测试基本脱离了它),系分不好评价(不好评价的意思是说目前来看似乎系分最有技术含量,它直接指导了开发),编码实现让人很分特(让人很分特的意思是说它不断延期,交出来的东西缺陷一堆堆),测试很伟大(伟大的意思是说靠着口头沟通所得整理测试需求)。本来说开发是一次交付的,后来改成两次交付了,因为第一次交付的时间点上很多东西没做完,或者交付没有测试通过。测试再次的伟大,评估了一下说两次交付也可以接受,因为在第二次交付之前可以针对第一次交付通过的内容进行详细测试,整体上对进度影响不大(实际上真的不大吗?你进行测试,他还在开发剩余内容,谁给你改缺陷?),只是跟预先计划的测试顺序稍稍有些变化。

    现在进到计划的第二次交付的时间点,还是延期。这个时候,测试不再伟大了,说这样的状况,肯定是不ok的。这个时候关键人物们着急了,因为这个项目大,关联性大,不能延期。于是说这几天我们开发保证把该完成的内容全部完成,哪怕我们加班加点,但是要增加测试资源来确保后续进度。咋一听是可行的,但实际上是荒唐的。后续加测试资源就能解决问题?加新资源进来不需要分散已有人员的精力去做任务分解,去辅导新加入进来的人?加进来测试资源,缺陷提交速度更快了,开发会不会都来不及改(本来就来不及改了)造成测试等待更多?再说,如果开发这两天不能保证完成所有东西,那是不是还得再加更多测试资源?测试资源是唯一用来解决问题的法宝?

    问题的关键根本不在测试资源,最后却变成要测试部门来消化这个后果。为什么不去解决本质问题呢?为什么不早点为本质问题做预防呢?为什么早的时候都拍着胸脯那么乐观呢?

    时间、成本、质量,这三者的管理和平衡。看似简单,但我们却总是一而再再而三的犯错。

  • 分歧终端解决器

    2009-02-23 18:29:45

    最近发现自己一直在扮演分歧终端解决器的角色。解决项目与项目之间,团队与团队之间的配合、协作问题。有时候我能快速的解决掉,有的时候我不能,我要花很大的成本去摸清楚状况,结果还不一定尽如人意,可能还会得罪人。but没办法。真的没办法吗?

    我来做分歧终端解决收益高,还是当事人自行解决收益高?显然是后者。但一般当事人谈几下谈不拢就往外捅出去,依赖外力解决,本来两个人的事情会演变到4个人的事情甚至6个人的事情。分歧的解决,真的那么难吗?我总结还是【本位主义】比较严重。上次去参加开发组的一个周会,某主管提到了关于分歧解决的几种模式,如下:

    1.分歧->争吵->升级->问题升级

    2.分歧->争吵->冷战->问题搁置

    3.分歧->争吵->分析->问题解决

    现在比较少看到第三种,多半是1、2两种然后通过外力来解决。如果少一些【本位主义】,多一些【换位思考】,多一些【包容】,应该比较容易进入3的轨道,这才是真正的分歧终端解决器。

  • 说说答辩这个事

    2008-10-31 18:11:11

    答辩,大家最熟悉的应该是毕业论文答辩,呵呵。今天我要说的是工作中的答辩。之前在BQ的时候,这个形式的应用较普遍,产品认证答辩(确认员工熟悉这个产品,能胜任销售、开发或测试、客户服务等工作基础能力),试用期满答辩,晋升答辩,产品方案答辩。最近我们的大团队遇到一些问题:新近的外包员工对业务对流程一个熟悉度并没有一个较直观的评判,跟着师傅学了一阵就匆匆交代很多任务开始忙起来;新员工试用期前后离职;部分人反映试用期内可能缺乏一些压力,虽然我们是有试用期绩效考核与转正面谈的,但总觉得还差点什么;于是我想尝试把答辩在这里试用一下。我不确认答辩这样一个形式能针对性的解决这些问题,但我相信它的作用是很微妙的,慢慢的,大家甚至会喜欢这样一个形式。那么我们想通过答辩获得什么呢?

    1.让参与答辩的人主动呈现其工作成果,尽情的展现他的技能与才华,鼓励员工呈现其成果与技能的主动性,形成一种百家争鸣、积极主动的气氛。

    2.通过答辩的互动,一些关联问题的探讨。大家能发现公司、团队一些亮点(发扬之)与缺点(改进之),特别是师傅,他应该能借此机会提炼不少有效信息。

    3.附加价值---员工会因为有这样一个形式,过程中更有压力与动力做好每件事,在答辩之前也会认真的借这个机会沉淀总结自己这一段时间以来的所思所得。

    最近连续尝试了两次(一次是外包新人业务、流程胜任力答辩,一次是新人试用期答辩),总体来说大家还是认可这个形式能带来的价值的,但也理出来一些待改进的点,如下:

    1.答辩的意义要让所有人员形成共识。特别是千万不要让员工认为这个是考核他的一个形式,这样,他会很有压迫感,会有所防备。

    2.答辩资料的准备应该是师傅与员工的共同产出,而不是员工一个人的。我记得之前我带过的一个徒弟试用期答辩,他的PPT我们一起改了10遍,最后获得满堂彩了。师傅要帮着一起理顺思路与重点,确保尽情呈现所有成果与想法。

    3.评委的准备。评委最好不要在不知情的情况下匆忙参与,问些不着边际的问题,搞得员工很被动。答辩的资料(员工准备的答辩资料 以及 评审表格)预先发到评委手上,评委预先了解情况甚至预先抛一些问题给员工。

    4.主持者。我们以前的话,是HR主持。那现在既然是职能部门自发的,觉得可以让员工的师傅来主持,从发出会议邀请开始掌控整个答辩的全过程,并且在员工接到一些特棘手的问题师傅还可以稍稍解围一下。

    先理这些,下个月还有再次实践。到时候再更新。

  • 测试项目人力安排的一个案例分析

    2008-07-09 16:10:43

    业务量的膨胀带来测试资源需求猛增,可能是因为前期与产品规划部门的沟通没做好,显然我们是没有做好充分的事先准备的。因为接这个部门时间也较短,内外部满意度都要兼顾,所以就会尽量想办法精简现有项目里的人,腾出来应对更多的项目。

    发现有个项目,测试负责人安排了5个测试人员但其中三个人的工作量不是百分百。于是我想从里面抽一个人出来,要解释也很简单,让每个人都百分百,不就可以腾一个人出来了嘛。去跟测试负责人确认,她是反对的,理由是这样PM不会同意,我们的人员名单已经在kickoff的时候就跟PM定了。于是找PM,他果然反对,我深挖原因,真因是这样的:项目过程中会出现很多的意外状况,影响测试的进度,特别是开发可能碰到的技术障碍等等,在项目deadline不变的情况下测试时间就被压缩了,但是如果测试人力多一点预留的话,就可以抵消这些风险。原来如此!我表示理解,虽然我知道预防这种风险其实还有其他办法,而且从项目管理来说更应该做的是预防这些风险的发生,而不是尽可能储备风险发生后的解决。但因为我是在kickoff之后抽人,情感上有些愧疚,所以也没深究,最后与PM达成的共识是将我们这样做的后果列为整体项目风险(测试人力全部都百分百投入以至于没有buffer应对可能发生的延迟风险)。

    其实现在回头来反思一下,其实有这么几个需要改进的地方:

    1.我们做测试人力安排,应该从测试需求出发分解测试任务,需要承诺的是总人力而不是总人头。

    2.从项目管理来说,为项目留buffer,更应该的是从策略上去做风险控制,而不是多腾些人力,尤其是测试的人力,这样反而会让开发的产生惰性。特别是当前组织的特性就是要求每个人有很高的工作效率,整体上尽可能多的容纳业务需求,怎么还可能用这种腾人力的方式作为buffer呢。

    最近多接了一个新部门,除了架构组之外。实在是变化太多太快,有点恍惚。没能好好的做有深度的思考,关于上面的一些分析还欢迎拍砖。

     

  • 最近关于团队管理的一些体会

    2008-07-09 13:37:26

    最近又是经历了很多的变化,忙呼呼,一定要停下脚步,稍微整理一下了。

    1.切忌不要为问题人员花费太多的时间

      这点得益于老板的点拨。我们的时间是有限的,需要我们投放精力的事情有太多。对问题员工要快速高效处理,但假若多次明显无改观,那我们宁愿选择放弃。

    2.不是百分百能实现的事情,最好不要提前承诺给员工。

      有时候是想用提前承诺去激励员工,但更多时候这些承诺的实现是带有风险的,假若实现不了,你需要花费很大的精力去做疏导,甚至会种下你意想不到的隐患。

    3.人员能力体现关键看应急能力

      有条不紊状况下看到的人员能力表现往往是肤浅的,只有紧急异常状况发生时才能较好的判断出员工的主动性、技能自信度、耐压能力、协调能力、影响力。能很好的对抗紧急异常状况的员工,才是我们最需要的优秀骨干力量。同时,紧急异常发生时,也是我们对能力偏弱员工进行辅导的绝佳时机。

     

  • 这两个月

    2008-05-27 22:56:35

    很久没有来这片责任田耕耘了,差不多两个月了,看到大家现在还在跟帖,真的是汗颜,抱歉了,4月份从苏州来到杭州,这段时间是在努力适应一些变化,以至于冷落了这里。今天忽然的有上来涂鸦的兴致,这似乎是一个很好的信号,窃喜。所以,从今天开始我会继续坚持的。

    说说这两个月的一些事情吧。现在带的团队叫做测试架构组,刚来的时候老板跟我说架构组就是为测试团队提供服务的,我有点恍惚,我不知道我该做什么,我不知道我如何带着这个小小的团队做出老板期待的东东来。可能是因为这个组织本身也成立不久,在初期的话,有些事情的边界不是那么清晰,这会让我更加的恍惚,甚至怀疑自己是不是不合适这个位置,似乎我之前的积累很难在这个职位上有所应用。一直带着一些疑虑,每天在自我肯定与自我否定间挣扎。直到今天忽然灵光一现,其实也不是那么神奇的一道光啦,呵呵,而是这段时间以来的不断沟通,不断确认,不断思考的一个自然结果吧。原谅我可能领悟的有点慢了,但是人切换到一个新的环境里,所有东东不再是你驾轻就熟的,所以做一些判断的时候就会比较的迟钝(我很不喜欢这样的感觉)。测试架构组这样的一个组织不是一般的企业会有的,他必须是致力于持续构建自己的品牌,自己的产品,自己的核心技术体系。测试架构组的话,应该是从测试策略,测试方法,测试技术上引领测试团队不断提升测试效率与测试品质,以适应外部要求。也许看起来还是有点虚,那就看看这个文章:http://www.cnblogs.com/mikeyond/archive/2008/05/05/1184205.html。其实前阵子就有看到这个文章,但是当时比较麻木,今天忽然有种触摸到真经的微妙感觉,有点小兴奋。现在回头再来看“提供服务”这样的一个定位,其实还是很妥帖的,这可以避免测试架构师陷入技术细节而忽略掉外部价值呈现的追求。

    我意识到其实现在面临的这个境况是非常的有意义的,甚至说是伟大的。希望我的团队能与我携手并进,我们一起突进。

     

  • 小告示 和 调查

    2008-03-26 18:17:14

    小公告:

        很久没有上来写东东,主要是实在是太忙了,以至于完全像个死蜜蜂一般。等我忙完了这阵,偶来总结一下子。

    调查:

        你最近在看什么书?

     

     

  • 【转贴】self - evaluation英文自我评价常用句子

    2008-02-21 11:39:17

     

     Mature,self-motivated and strong interpersonal skills.思想成熟、上进心强,并具极丰富的人际关系技巧。

      Energetic,fashion-minded person.精力旺盛、思想新潮。

      With a pleasant mature attitude.开朗成熟。

      Strong determination to succeed.有获得成功的坚定决心。

      Strong leadership skills.有极强的领导艺术。

      Ability to work well with others.能够同他人一道很好地工作。

      Highly-motivated and reliable person with excellent health and pleasant personality.上进心强又可靠者,并且身体健康、性格开朗。

      The ability to initiate and operate independently.有创业能力,并能独立地从业。

      Strong leadership skill while possessing a great team spirit.有很高的领导艺术和很强的集体精神。

      Be highly organized and effecient.工作很有条理,办事效率高。

      Willing to learn and progress.肯学习进取。

      Good presentation skills.有良好的表达能力。

      Positive active mind essential.有积极、灵活的头脑。

      Ability to deal with personnel at all levels effectively.善于同各种人员打交道。

      Have positive work attitude and be willing and able to work diligently without supervision.有积极的工作态度,愿意和能够在没有监督的情况下勤奋地工作。

      Young,bright,energetic with strong career-ambition.年轻、聪明、精力充沛,并有很强的事业心。

      Good people management and communication skills. Team player.有良好的人员管理和交际能力。能在集体中发挥带头作用。

      Able to work under high pressure and time limitation.能够在高压力下和时间限制下进行工作。

      Be elegant and with nice personality.举止优雅、个人性格好。

      With good managerial skills and organizational capabilities.有良好的管理艺术和组织能力。

      The main qualities required are preparedness to work hard, ability to learn, ambition and good health.主要必备素质是吃苦耐劳精神好、学习能力优、事业心强和身体棒。

      Having good and extensive social connections.具有良好而广泛的社会关系。

      Being active, creative and innonative is a plus.思想活跃、有首创和革新精神尤佳。

      With good analytical capability.有较强的分析能力。
      
           以上文章转载自:傲英英语学习网
    http://www.oenglish.cn
           还有一些其它求职英语资料,如果需要的话,就去看看吧:http://www.oenglish.cn/html/Job/Interview/


  • 敏捷与测试

    2008-02-20 18:42:49

    敏捷这个话题,很多组织在谈,也有在实践的。我之前所在的组织,做过RUP和敏捷的整合尝试,有收到过一些效果。这里把我个人的实践以及一些体会整理一下,分享给大家。

    首先,为什么要敏捷?

    ---为的是更好的迎合市场和客户的需要,能快速响应变化。之前的组织是做产品的,快速响应的要求来自于两个因素。1,竞争对手的。人家推陈出新,我们也不能落后。否则人家一做市场推广,江山就被他们占去一片了;2,客户的。潜在重要客户关注的需求,我们得尽早做出来好让他对我们的产品满意愿意掏钱买。

    RUP不是不能接受变更,但是它的方式是控制变更,也就是变更是它不希望看到的。但是加入敏捷,就是要很好的适应变更。来了变更,不影响当前迭代,就自然而然将变更放到下一个迭代中去,原先规划的迭代任务可以根据优先级做退让。

    其次,敏捷给测试带来的挑战。

    很多时候,大家谈敏捷,很少谈到测试。从我的观点来看,敏捷之后,测试反而显得更重要。因为敏捷希望每个迭代出来的产物都是可运行可演示甚至可交付的,这绝对需要测试来保障。其实敏捷之后,对于尽早测试,全程测试反而支持的更充分了,是好事。只是对测试带来的压力就更大。体现在:

    1. 管理迭代中开发结束与测试结束的时间差。

       每次迭代,我们的目标是可运行甚至可交付,那也就是说需要事先定义迭代成功标准,并且通过测试去校验该标准是否达成。但开发跟测试总是有个时间差的,你这边还在测,可能开发就需要投入到下一个迭代开发中去了,为了赶时间,不可能等待你完全测试结束,哪怕只相差一两天,虽然他们也还是会留人力处理后续的缺陷,但是你已经落后了,所以一定要能从前一个迭代中腾出人力来及时进入下一个迭代,并且他们要有能力将前期获取的信息有效传递至后面参与进来的测试人员,如此循环。另外作为测试负责人要事先控制时间差,要参与到迭代任务分配筛选计划中,尽量避免发生时间差过长的现象。

    2. 管理讨论结果

       因为敏捷迭代有很高压力,就是在规定的时间内完成迭代目标。一般来说,开发人员还是做不到将需求做到够细、将设计做到够细再入手编码,于是很多时候会在白板上讨论比划来不断明确一些东西。有时候这就是我们测试的依据,这也涉及到RUP非常关注的输入输出原则,非常重要,所以我们不能轻易只将这些东西记在脑子里,但我们又不能做到每次要求他们文档化,于是我们想了个办法,那就是把黑板上的结论拍照片存档,这招很管用,既节约了时间又记录了讨论结果。

    最后,我将我之前实践的流程图分享出来。

    图一:整体研发计划,分若干迭代完成。

    图二:每个迭代的子流程。

        

     

  • 由【测试过程分析的15个常用度量元】而起

    2008-01-21 14:23:43

    以下这个表格摘自:http://www.sawin.cn/doc/QM/Test/TheEdge422.htm 感谢原创作者。

    序号 优先级 度量对象 度量元 度量单位 采集周期 采集/计算方法 分析方法 作用
    1 1 用户发现的各类型的缺陷 缺陷个数 交付阶段 直接统计 80-20分析:对缺陷类型按缺陷个数排序,找出客户发现的最多的20%的缺陷类型 分析客户的关注点是什么?为什么客户能发现这些类型的缺陷,为什么我们没有测试出来?定义改进措施
    维护阶段
    2 1 软件模块 缺陷密度 个/KLOC 系统测试阶段 缺陷个数/代码规模 80-20分析:对所有模块的缺陷密度进行排序比较,找出缺陷密度最大的20%模块 找出质量最差的模块,采取改进措施
    3 1 遗留的缺陷 缺陷个数 系统测试阶段 上阶段遗留的缺陷个数+本阶段发现的缺陷个数-本阶段解决的缺陷个数 和阶段出口准则对比 里程碑评审决策的依据
    4 1 各级别严重程度的缺陷 缺陷个数 系统测试阶段 直接统计 和项目目标对比 判断是否达到测试结束与产品发布准则
    5 1 回归测试活动 缺陷个数 系统测试阶段 直接统计 趋势线分析:横坐标为某次回归测试,纵坐标为缺陷个数,建立拟合曲线,判断收敛性 针对每次回归测试活动,进行收敛分析,作为发布决策的依据
    6 2 代码走查 代码走查的效率 个/小时 编码阶段 代码走查发现的缺陷个数/代码走查的工作量 和项目目标对比 比较评审与测试的效率,以确定二者投入工作量的比例
    7 2 单元测试 测试效率 个/小时 编码阶段 单元测试发现的缺陷个数/单元测试的工作量 和项目目标对比 建立单元测试的性能基线,预测单元测试投入的工作量
    8 2 系统测试 测试效率 个/小时 系统测试阶段 缺陷个数/测试工作量 和项目目标对比 建立测试活动的投入产出模型,用以估计为了达到项目的质量目标而需要的测试工作量
    9 2 系统测试 系统测试用例相对逻辑规模的密度 个/功能点 系统测试阶段 系统测试用例个数/需求的规模 和项目目标对比 判断系统测试的充分性
    10 2 系统测试 系统测试用例相对物理规模的密度 个/KLOC 系统测试阶段 系统测试用例个数/代码规模 和项目目标对比 判断系统测试的充分性
    11 3 测试发现各类型的缺陷 缺陷个数 编码阶段 直接统计 80-20分析:对缺陷类型按缺陷个数排序,找出最多的20%的缺陷类型 根据类型的分布,查找错误的原因,定义编码或设计的改进措施
    系统测试阶段
    12 3 单元测试 缺陷密度 个/KLOC 编码阶段 单元测试发现的缺陷个数/代码规模 和项目目标对比 建立单元测试的性能基线,用以制定项目的质量目标
    13 3 单元测试 单元测试用例相对物理规模的密度 个/KLOC 编码阶段 单元测试用例个数(或断言的个数)/KLOC 和项目目标对比 判断单元测试的充分性
    14 3 集成测试 集成测试用例相对物理规模的密度 个/KLOC 集成阶段 集成测试用例个数/KLOC 和项目目标对比 判断集成测试的充分性
    15 3 系统测试 测试用例的有效性 % 系统测试阶段 依据测试用例发现的缺陷个数/所有的缺陷个数 和项目目标对比 评价测试用例的有效性,判断是否需要提高测试用例的设计技术

    以上这些度量项,对于测试管理者来说应该都不陌生,全部整理到一起,真的还是蛮齐全的了。测试品质保证的乐趣,其实很多就在这些关键度量元素间。其一,这样的分析显然是颇具科学意义的,统计学嘛;其二,真正能通过管理这些度量项达到提高质量的效果,那是一件很美妙的事情。我个人而言,比较有实用感触的是1,2,3,5,15这几项,上了底色。

    1---客户反馈缺陷,即漏测。其实这是一个很直观的质量保证结果,本人非常崇尚用这个指标衡量测试人员的结果绩效。虽然漏测的原因不单单在于测试的疏忽,但终究能在很大程度上体现测试的质量。且通过对这个指标的线性观察,发现一些潜在的可能在未来会反馈回来的问题,我们还能亡羊补牢,出补丁提前堵漏。

    2---模块缺陷密度。往往找到缺陷最多的地方也是潜在缺陷最多的地方。这个规律几乎是千真万确。就跟越是担心会出问题的时候一般都是会出问题的,类似。这个在测试过程中或者发布之后拿来分析都很有意义。

    3---遗留缺陷。仅仅看一个绝对的数字并无太大意义,它的意义在于与之前拟定的交付标准做比对,假若在标准之内就放行,不在标准之内那就卡住。另外,被允许的遗留缺陷一般也是下一阶段启动任务之时开发任务的首要任务之一。

    5---趋势分析。这是一个质量活动如期完成的强力证明工具,当然要真正看到收敛才对。

    15--测试用例有效率。这个指标更大意义的是规范测试活动,其次才是提高测试用例的质量。想要统计出有效率,有个前提就是测试集驱动测试,即你开展每一轮测试之前,根据测试需求建立好测试集,并且集里面的测试用例也都已经确定好,之后照着逐一测试。很多测试人员说测试用例只不过是我用来熟悉需求的产物,等我拿到被测对象,我根本就不看测试用例就刷刷的往下测。殊不知,人的记忆往往是有漏洞的,当你脱离测试用例来测试,你就是在走向随机测试,大家想想随机的活动有没有可把握性?

     

    简单评论之后,我再加一个度量项,尤其是在这提倡测试先行的年代。---需求review阶段发现的需求issue数/整个测试过程中发现的需求Issue的总数,这个指标体现测试人员在需求熟悉阶段对需求透析程度,透析度越深往往对促进需求精致化的贡献度越大,对测试用例的有效性的贡献也越大。我们毕竟不希望到了测试执行阶段才来不停的质疑需求这里有问题那里有问题。

     

     

  • 软件测试人员不要把自己当作一个特殊群体

    2008-01-16 09:55:43

    若干次听业内或业外的朋友讲软件测试是比较特殊的一个职业,从事这个行业的人也就是一个特殊的群体,诸如处于软件工程的最后环节,诸如技术含量相对没有开发的高,诸如经常会不受到企业的重视,诸如被某些人认为可有可无。。。。。。于是,当遇到不可逾越的困难时,总是拿这些理由来安慰自己。

    我一直不屑于这样的格调,从内心里。不管哪个行业,如要列举一些特殊性,总是可以找出来很多的。所以这些所谓的特殊,也都是无意义的。不管哪个职业群体,存在的意义无非都是创造价值,所谓价值就是你的劳动成果能让他人受益。所以我们要思考的是测试人员的价值是什么?要树立一个正确的价值观。之后,我想做任何事都应该是昂首挺胸奔着创造价值去的。困难,那是必然的,关键是克服困难的心态和方法。

    那么测试人员的价值是什么呢?

    测试本身是质量保证的一个重要手段。价值取向就是保证质量,提供具备高测试质量的产品,在控制好成本与时间的前提下,尽可能多的找到软件产品的缺陷,尽量减少交付之后的缺陷反馈。除此之外,若有余力,可以尝试去挖掘附加价值,比如为产品经理提供产品发展的有效建议,比如与研发经理一起分析测试过程中发现的缺陷帮助他们改善他们的工作,比如与研发一起持续优化本公司的研发流程,比如能将自身的专业技能做成课程包对外授课直接创造利润,甚至将测试中的严谨形成一种质量文化能影响整个组织......

    当你把份内的价值尽情展现出来,大家会认可尊重你的劳动;当你创造了附加价值,大家会感受到你的不可替代性,会以与你共事为荣。

  • 对代码覆盖率价值的初步认识

    2007-12-20 11:26:48

    关于代码覆盖率,之前6年的工作经历中,只是依稀听闻过。之前的组织里,从未关注过这个指标,只是有一段时间用NUnit做了单元测试,主要是测试一些关键类关键方法是否正常,对代码覆盖率的印象就真的一直是停留在听闻的程度。汗一个!

    前些时日,关于自动测试的讨论中有人提及到代码覆盖率,激发了我的好奇,到底什么是代码覆盖率?最重要的是于测试工作而言有怎样的价值呢?今天花了一点时间查了一下,有了初步的认识。大致归纳如下:

    一。基本概念

       代码覆盖率是单元测试活动任务之一;

       覆盖率分语句覆盖率(即通常所说的行覆盖率)和分支覆盖率。

    二。价值

       代码覆盖率的分析能在一定程度上评判代码质量,一般覆盖率高的代码出错的几率会相对低一些。但是高覆盖率只是表示执行了很多的代码,并不意味着这些代码被很好地执行了。所以,似乎覆盖率测试结果出来并不能帮我准确的评价代码质量。那么我们为什么要做覆盖率测试呢?如何让它给我们带来价值呢?

       1. 尽早评估代码质量。

    比如在开发的过程中,定时的去看整个项目的代码覆盖率,监控覆盖报告可以帮助开发团队迅速找出不断增长的但是没有相应测试的代码。例如,在一周开始时运行覆盖报告,显示项目中一个关键的软件包的覆盖率是 70%。如果几天后,覆盖率下降到了 60%,那么您可以推断:软件包的代码行增加了,但是没有为新代码编写相应的测试(或者是新增加的测试不能有效地覆盖新代码)。能够监控事情的发展,无疑是件好事。定期地查阅报告使得设定目标(例如获得覆盖率、维护代码行的测试案例的比例等)并监控事情的发展变得更为容易。如果您发现测试没有如期编写,您可以提前采取一些行动,例如对开发人员进行培训、指导或帮助。

       2. 为功能测试关注点提供情报

    假设覆盖报告在指出没有经过足够测试的代码部分方面非常有效,那么质量保证人员可以使用这些数据来评定与功能测试有关的关注区域,可以更有针对性地加强这些区域的测试,因为没有被测试代码覆盖到的区域,出错的几率应该相对更高。

       3. 估计修改已有代码所需的时间

      对一个开发团队而言,针对代码编写测试案例自然可以增加集体的信心。与没有相应测试案例的代码相比,经过测试的代码更容易重构、维护和增强。测试案例因为暗示了代码在测试工作中是如何工作的,所以还可以充当内行的文档。在另一方面,没有经过相应测试的代码更难于理解和安全地修改。因此,知道代码有没有被测试,并看看实际的测试覆盖数值,可以让开发人员和管理人员更准确地预知修改已有代码所需的时间。

       -----

       当然,这样的理解还是比较浅层的,我想实际应用中除了以上三点之外,还有一个很重要的工作就是提高测试代码的质量来更好的体现代码覆盖率的价值。


      

     

     

     

  • 【转载】理想、激情、生存——位技术管理人员的20年工作经历和感悟

    2007-12-19 14:52:50

    http://blog.csdn.net/vincetest/archive/2007/11/12/1881108.aspx

    很敬仰这样的前辈,激励我继续前行。

  • CMM认证不代表成熟度

    2007-12-17 16:55:11

    上周2007年的SEPG大会在科技园召开,我有收到去免费听演讲的通知。不过也许是懒,也许是担心这样的大会演讲比较空洞浪费时间,反正就是没去。今天翻朱少民老师的blog,他在讲他参加大会的一些心得。呵呵,稍微有点后悔没去感受一下这近在家门口的盛会。

    我也要有感而发,关于朱老师提到的过程改进在于数据和结果而不是一个认证。之前所在的公司,可能是企业特性而定,一直没有涉及CMM,大抵老板也不屑于此,我们是卖自己的产品,不是卖自己的IT服务。也一直说原先的组织有不好的地方,但我在那里耕耘5年,至少在测试成熟度这块,还算有所积累。因为我们有衡量我们自身成熟度的数据,且我们致力于不断确认这些数据的真实性并不断优化这些数据。测试用例命中率,漏测缺陷率...... 总之,我们在这些数据中成长,尤其是漏测率,直接体现客户对我们的满意度。不管哪个角色,要出绩效,总是出在外部,外部人员受用于你的工作成果,那你就有绩效了。这是《卓有成效管理者》一书中的观点。切入现在的公司,一个多月的时间,是过了CMM3的,有数据,但是数据的真实性尚有改善余地,也就是说目前对于CMM3有序化过程的质量还无法把握,也就无法快速进步。不过我想组织的复杂度决定这个过程会稍稍漫长。没关系,沉下去,慢慢来,总是可以改善的。

     

  • 【转贴】WEB自动化测试中针对验证码的解决方案

    2007-12-12 15:40:53

     
     
    作者:guanhe 来源:cnblogs
     

    目前,不少网站在用户登录、用户提交信息等登录和输入的页面上使用了验证码技术。验证码技术可以有效防止恶意用户对网站的滥用,使得网站可以有效避免用户信息失窃、广告SPAM等问题。但与此同时,验证码技术的使用却使得WEB自动化测试面临了较大的困难——由于验证码的存在,传统的“录制”-“回放”工具由于不能识别验证码而失效。在各大软件测试的论坛中,经常能看到测试工程师在焦急地发问:“自动化测试时如何处理页面上的验证码?”,可见,该问题确实是一个对相当多的测试工程师造成严重困扰的问题。其实,验证码并不像它表面上看起来那么神秘,也并不像一些测试工程师认为的那样坚不可摧,通过一些技术和非技术性的手段,测试工程师完全可以把这个阻碍测试的绊脚石踢开。

    下面,本文就从验证码的实现手段说起,向各位饱受验证码困扰的测试工程师说明,如何通过我们的聪明才智,成功地解决验证码带来的自动化测试方面的问题。

    1 验证码及其为自动化测试带来的困扰

    验证码一般应用在WEB系统涉及登录和输入的页面上,其实现的一般方法是在页面上显示一幅图片,要求用户肉眼识别图片中的信息并将该信息作为输入的一部分进行提交。页面上显示的这幅图片一般是一串随机产生的数字或符号,并且被添加了用于防止识别的背景。验证码的主要目的是为了防止恶意用户利用自动工具(机器人)对用户口令进行暴力破解、恶意注册用户,或是向网站发布令人厌烦的广告信息等。

    验证码具有随机性和不易被自动工具识别的特点,当用户访问某个使用验证码的页面时,每次对该相同页面的访问都会得到一个随机产生的不同的验证码,并且,这些验证码具有能够被人工识别,但很难被自动工具识别的特点,这样,自动工具就很难适应使用验证码的页面,从而达到保护网站不被恶意使用的目的。

    当然,不同网站使用的验证码在表现形式上会有所不同。例如,常用的一些论坛程序、小型网站等使用相对较简单的数字验证码;而Hotmail和Gmail等则使用较为复杂的数字、字符等混排的验证码,并通过变形等手段对验证码图片进行处理;还有一些网站使用动物图片作为验证码。

    图1给出了几个典型网站的验证码表现。

     
    ITPub的验证码 Gmail的验证码
    Hotmail的验证码

    图1        几个典型网站的验证码

    辨证唯物主义告诉我们,任何事务都可以从正反两个方面来看待,验证码也不例外。验证码在保护网站不受到恶意注册和垃圾信息困扰方面发挥了有效的作用,但对于需要使用自动化测试工具进行测试的自动化测试来说,验证码则带来了相当的困扰。因为验证码在本质上是一种为了防止自动工具对网站进行操作的手段,而自动化测试工具也不幸属于自动工具之列,因此,在软件测试的过程中,验证码同样成为了自动化测试的障碍。

    自动化测试工具基本的原理是“录制”-“回放”,也就是使用测试工具“录制”用户的操作形成脚本,并在后续测试过程中通过“回放”该脚本来重复用户的操作。设想我们使用自动化测试工具对某个使用了验证码的网站进行测试,由于验证码的存在,录制得到的脚本就不能直接回放成功。

    在各大软件测试论坛中,“如何处理WEB验证码”是一个被经常问到的问题,可见,该问题确实是一个对相当多的测试工程师造成严重困扰的问题。解决验证码的问题并不容易,但也并不是不能解决,本文拟从生成验证码的方法、测试的不同类型和阶段提出针对WEB验证码的自动化测试解决方案,分析各种方案的优缺点,并结合具体的测试工具说明各种方法的应用。

    验证码的主要实现方法

    要解决验证码的问题,我们首先来看看在不同类型的网站上,验证码究竟是如何实现的。

    从实现方式上来说,验证码分为“读取式”和“生成式”两种。

    读取式”是指从服务器上指定的目录下随机读取预先制作好的图片文件,将图片文件显示在页面上要求用户识别。粗看起来,这种方式的安全性应该比较好,因为网站制作者可以通过精心制作非常难于自动识别的图片,将自动工具自动识别的风险降到最低,但实际上,这种方式存在一个致命的缺点:容易在页面文件中泄漏图片文件的URL,而恶意用户正好可以利用这一点,通过反复尝试访问使用验证码的页面,获得大部分预先制作好的图片文件URL和需要输入的验证码之间的关系,然后通过该对应关系跳过验证码的验证,使验证码失效。

    另外,由于该方法需要预先制作大量的图片文件,前期的工作量比较大,因此,目前已经很少有网站完全采用该方式实现验证码技术。

    生成式”则是指在程序中通过代码的方式,随机生成一个串,并将该串用图形的方式显示在页面上要求用户识别。这种方式由于实现较为方便,因此目前主要的网站均采用该方法实现验证码。当然,“生成式”也有一定的缺点,例如,由于“生成式”一般利用某种网站开发语言提供的图形函数生成图形,每个字符生成的位图是完全相同的,恶意用户可以利用这一点,使用OCR的方式将位图“翻译”成对应的字符串内容。因此,“生成式”一般还会在生成的图片上叠加背景噪音,增加识别的难度。Hotmail和Gmail等网站更是利用变形、改变颜色等方法让验证码的自动识别变得几乎不可能。

    总体来说,“生成式”是依靠程序中的代码在运行时动态生成起到验证作用的图片的,但从其具体实现上来看,这种实现方式依赖于具体的编程语言,以及生成图片的格式。

    1.1 Xbm图片格式及其动态生成

    x-xbitmap格式的图片(以下简称为Xbm格式)由于其特殊性,是一种广泛被用于验证码的图片格式。该图片格式之所以特殊,在于它并不跟gif,jpg等图片格式一样,是一个二进制图片格式,而是采用ASCII码来表示图形——换句话说,它是一个纯文本文件,必须由操作系统对其进行解释才能显示出相应的图片。

    以下是一个xbm文件的内容:

    #define counter_width 32

    #define counter_height 10

    static unsigned char counter_bits[] =  { 0x3c, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x1c, 0x66, 0xc0, 0xc3, 0x18, 0xc3, 0x60, 0xc3, 0x18, 0xc3, 0x1c, 0xc3, 0x18, 0xc3, 0x60, 0xc3, 0x18, 0xc3, 0xc0, 0xc3, 0x18, 0xc3, 0xc0, 0xc3, 0x18, 0xc3, 0x66, 0x66, 0x18, 0x66, 0x38, 0x7e, , 0x7e };

    初看起来,这个文件和图形并没有什么关联,但如果我们新建一个文件,将以上内容复制到文件内并将其保存为test.xbm,然后打开IE窗口,并将该文件直接拖拽到它上面后,我们会惊奇地发现,仿佛变魔术一样,显示出来的并不是这个文件的内容,而是一副图片(见图2)。

    熟悉C语言的读者肯定一眼就能看出,上面给出的xbm文件的内容完全就是C代码中的一个数组定义。没错,xbm文件就是采用了一个数组来表示一幅图片的。

    在上面的文件内容中,#define counter_width 32 定义的是图片的以象素表示的宽度,一般来说,8个象素的宽度可以用来表示一个字符,因此这里的32可以用来表示本图片显示4个字符。

    #define counter_height 10定义了图片的高度,表示该图片中每个字符的高度为10象素。而接下来的数组表示的就是图片显示内容的16进制代码了。

    一个16进制的字节可以表示为8位二进制数据,xbm文件用二进制的1表示一个黑色的象素,用二进制的0表示一个白色的象素,因此,一个字节可以表示8个象素。以上面的xbm文件为例,一个32×10象素的图片就需要40个字节来表示。xbm文件是按行描述的,对上面的例子来说,每4个字节表示了一行。

    因此,如果我们把上述的数组按照4个字节分组进行排列,就会发现字符和数字之间的对应关系。从图3可以看到,由于一个字节能够表示8个象素,而一个图片上的字符宽度也正好是8个象素,因此,对本例来说,按照4个一组的方式排列,很容易得到数组和图片上显示字符的对应关系。

    xbm文件可以表示任意的黑白两色图形,而且非常易于生成,因此不少的asp论坛/聊天室的登陆验证码都是采用这样的方法在asp中动态生成的。不过由于攻击者可以利用这种图形格式的处理过程中的漏洞,制造一个超大的图片而导致系统资源耗尽的情况,在Windows XP的SP2以后,就取消了对该图片格式的默认支持,用户必须通过修改注册表才能获得对该图片格式的支持。

    1.2 其他图片格式的验证码图形的动态生成

    xbm图片文件格式简单,易于生成,但也存在明显的不足——因为图片只能为黑白两色,因此较为容易被自动工具识别。有鉴于此,目前大部分JSP、PHP和ASP.NET网站都利用这些语言本身提供的图形函数在运行时生成图形。

    典型的生成图形的过程包括以下几个步骤:

    1. 生成图形对象;
    2. 用背景色填充图形对象;
    3. 随机生成字符串,随机选择前景颜色,利用程序语言的图形库函数以图形方式向图形对象中写入该字符串;
    4. 向图形对象中增加随机产生的点或者线;
    5. 输出图片文件头,输出图片文件内容。

    下面是一段使用PHP编写可以用来产生验证码的代码:

    //生成验证码图片 
            Header
    ("Content-type: image/PNG");  
        
    session_start
    (); 
        
    $auth_num
    =""; 
        
    session_register
    ('auth_num'); 
            
    srand((double)microtime
    ()*1000000); 
            
    $auth_num_k = md5(rand
    (0,9999)); 
        
    $auth_num = substr($auth_num_k
    ,17,5); 

    $im
     = imagecreate(58,28); 
            
    $black = ImageColorAllocate($im
    , 0,0,0); 
            
    $white = ImageColorAllocate($im
    , 255,255,255); 
            
    $gray = ImageColorAllocate($im
    , 200,200,200); 
            imagefill(
    $im,68,30,$gray
    ); 
       
            
    //将四位整数验证码绘入图片 
            imagestring($im, 5, 10, 8, $auth_num$black
    ); 
       
            
    for($i=0;$i<50;$i++)  
    //加入干扰象素 
            { 
              imagesetpixel(
    $imrand()%70 , rand()%30 , $black
    ); 
            } 
       
            ImagePNG(
    $im
    ); 
            ImageDestroy(
    $im
    ); 

    当然,在具体采用该方法生成验证码时,还可以在代码中通过图形变形等手段让图形变得更难以被自动工具识别。

    另外,注意在上面的代码中,我们将随机生成的用于生成验证码图片的实际数据保存到了Session中,这一步对于验证码的实现非常关键,网上广泛流传的一篇用PHP实现验证码的文章将验证码对应的实际数据存放在页面的hidden Field中,从安全性的角度来说,这种方式将导致验证码对应的实际数据在客户端可见,只需要通过简单的页面分析即可获得,这就完全失去了验证码抵抗恶意攻击的作用。

    1.3 验证码是否正确的验证过程

    产生验证码图片只是验证码技术实现的一个步骤,验证码图片在页面上正确显示后,用户需要识别验证码并提交了相应的内容,验证码技术应该能够判断用户的输入与验证码对应的实际数据是否一致。

    在具体的实现中,一般是将验证码对应的实际数据存放在服务端的Session中,在验证用户输入的代码中通过比较用户的输入和验证码对应的实际数据是否一致来判断用户输入的验证码是否正确。

    仍然以用PHP实现验证码为例,验证用户输入是否正确的代码如下:

    session_start(); 
    $num=trim($num
    ); 
    if($auth_num==$num && $num
    <>"")


       
    echo
     "验证成功"; 
    }

    else



       
    echo "验证失败"; 
    }

    <!--[if !supportLists]-->4 自动测试中

    4        验证码实现的大致原理图

    <!--[if !vml]--><!--[endif]-->验证码给自动测试带来了很大的问题,但也并不是完全不能解决。结合我们在上文讨论的验证码实现的方法,图4给出了验证码实现的大致原理图。 

    从图4中可以看到,从技术的角度来看,至少设计两种不同的方法来实现自动测试工具对验证码的处理:

    <!--[if !supportLists]-->1、  <!--[endif]-->完全从客户端角度考虑,靠模式识别的方法识别出验证码图片对应的字符串;

    <!--[if !supportLists]-->2、  <!--[endif]-->从服务端角度考虑,如果自动测试工具可以获取Session中存储的随机数,也就能正确处理验证码了。

    这两种方法是解决自动化测试中验证码问题的主要方法,我们分别称其为识别法服务端插入法。这两种方法在实现方法上侧重点不同,适用的场合也不同。

    识别法完全不用考虑服务端应用的实现,通过各种技术方法对显示的验证码图片进行“破译”,这样,即使完全不能接触到服务端代码,也能让自动化测试在有验证码的情况下进行下去;但这种方法当然也有其致命的缺点:只能对简单的验证码进行识别,对复杂的验证码,根本就无法识别。

    服务端插入法则从服务端入手,通过提供一个额外的客户端接口,向客户端只需要知道该接口的调用方法,就能通过该接口来获取该页面的验证码图片对应的实际数据,并使用该数据继续测试。

    另一方面,除了技术角度解决问题的方法以外,还可以通过一些非技术的方法来解决验证码问题。

    <!--[if !supportLists]-->4.1      <!--[endif]-->识别法的实现

    识别法适用于不能获得和改变服务器端代码的情况下,在这种情况下,由于服务端代码本身不可获得,或是不能对其进行修改,测试者只能完全从客户端的角度想办法解决验证码的问题。

    识别法的核心是对验证码图片的模式识别算法,该算法的可实现性基本取决于图片本身的复杂程度。以本文前面列举的验证码示例来说,类似GmailHotmail的验证码基本上是无法通过程序来识别的。而最简单的验证码实现,例如ASP下用xbm技术生成的图片,就可以很容易地通过算法来识别;在PHPdotNET等平台上完全使用图形库函数生成的图片,同样可以通过对某个区域内的图片分析,识别出图片对应的实际数字或是字母。

    下面以处理xbm格式的验证码为例,介绍对其进行识别的算法。

    本文的2.1节对xbm文件格式进行了深入的探讨,用xbm实现验证码的方法在ASPdotNET平台上非常常见,由于xbm文件格式的规则性,因此很容易通过程序对其进行识别。一般的识别过程如下:

    • <!--[if !supportLists]-->多次访问带有验证码的页面,分析每次获得的xbm文件和显示的图片之间的对应关系,获得验证码中所有符号对应的十六进制串;
    • <!--[if !supportLists]-->编写识别验证码的代码,识别代码根据获得的xbm文件,将其按照编码方式分组,然后与上一步骤中获得的对应的十六进制串进行比较,这样就可以识别出该xbm文件对应的验证码的实际数据。

    下面这段代码是用于将xbm图片文件识别为相应的验证码内容的C语言代码:

    int getDigital(char dig[10])
    {
          
    const char
     orgdig[10][10] = {
                  {0x3c,0x66,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x7e}, 
    //0
                  {0x18,0x1c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00}, 
    //1
                  {0x3c,0x66,0x60,0x60,0x30,0x18,0x0c,0x06,0x06,0x7e}, 
    //2
                  {0x3c,0x66,0xc0,0x60,0x1c,0x60,0xc0,0xc0,0x66,0x38}, 
    //3
                  {0x38,0x3c,0x36,0x33,0x33,0x33,0xff,0x30,0x30,0xfe},  
    //4
                  {0xfe,0xfe,0x06,0x06,0x3e,0x60,0xc0,0xc3,0x66,0x3c},  
    //5
                  {0x60,0x30,0x18,0x0c,0x3e,0x63,0xc3,0xc3,0x66,0x3c}, 
    //6
                  {0xff,0xc0,0x60,0x30,0x18,0x18,0x18,0x18,0x18,0x18},  
    //7
                  {0x3c,0x66,0xc3,0x66,0x3c,0x66,0xc3,0xc3,0x66,0x3c}, 
    //8
                  {0x3c,0x66,0xc3,0xc3,0x66,0x3c,0x18,0x0c,0x06,0x03}  
    //9
           };

     
           
    int
     i=0, j=0;
          
    int
     ret = 1;

           
    for
    (i=0; i<10; i++)
           {
                  ret = 1;
                 
    for
    (j=0; j<10; j++)
                  {
                        
    if
    (orgdig[i][j]!= dig[j])
                         {
                                ret = 0;
                               
    break
    ;
                         }
                  }
                 
    if
    (ret)
                        
    return
     i;
           }
          
    return
     -1;
    }

    主函数:

    char
     picc[500], t[40], od[10];      
    char
     separators[] = ",";
    char
     *token, *endstr;

    int
     i=0, j=0;

    //获取需要识别的图片中的数据描述部分,内容为
    //0x3c, 0x3c, 0x18, 0x3c, 0x66 …
    //将其存放在字符串picc中
    …………

    //分解获得的串

    token = (
    char *)strtok(picc, separators); /* Get the first token */
    if(!token)
    {
          
    return
    ( -1 );
    }
     
    while
    ( token != NULL )
    {
          
    if(!strcmp(token , ""))           
    //处理为“空”的内容,将其替换成0x00
                 t[i] = 0x00;
          
    else

                 t[i] = strtol(token, &endstr, 16);
                 i++;
           token = (
    char *)strtok(NULL, separators);
    }

    for(i=0; i<4; i++)                         
    //一共4个数字,分别调用getDigital函数进行处理
    {
          
    for
    (j=0; j<10; j++)
           {
                  od[j] = t[j*4+i];
           }
           lr_output_message("%d", getDigital(od));
    }

    其他通过服务器代码绘图方式实现的识别码识别相对麻烦一些,但原理上都差不多,无非是将获取到的图片进行分析,通过识别方法判断其对应的符号。

    <!--[if !supportLists]-->1.2      <!--[endif]-->服务端插入法

    如果可以控制和修改服务端代码,就可以使用服务端插入法。该方法在服务端提供一个可被客户端使用的接口,只要客户端传递过来自己的SessionID,该接口就返回此时正确的Session,这种方法就可以很容易地让自动测试工具直接获取到正确的应该提交的验证码内容。从测试的角度来说,这种方法就等于是在系统上增加了一个测试接口,从而提高了系统的可测试性。

    服务端插入法的实现并不复杂,在任何一个平台上都能很容易实现,在此就不再赘述了。服务端插入法可以针对任何类型的应用使用,但这种方法也有明显的不足:

    <!--[if !supportLists]-->1、              <!--[endif]-->如果是已经上线的应用,网站不太可能会允许保留一个这样的接口,因此,该方法一般用于还未上线的WEB系统,如果要在已上线的WEB系统上使用该方法,则必须通过管理上的方法提高该方面的安全性;

    <!--[if !supportLists]-->2、              <!--[endif]-->采用这种方法,在性能测试时,由于该方法需要额外请求一次才能获得实际的验证码,相对于实际的用户操作来说,访问带有验证码页面的请求会多一次,因此在获得的测试结果上会有些许的差异。

    <!--[if !supportLists]-->1.3      <!--[endif]-->解决自动测试中验证码问题的非技术方法

    其实,测试并不只是单单的技术问题,除了上面给出的识别法和服务端插入法,其实,通过非技术的方式也能让自动化测试在具有验证码的系统上成功应用。当然,这些非技术方法应用的前提是,测试团队必须具有足够的能力和机会影响系统的实现。如果完全没有方法接触到服务端代码或是完全不能修改服务端代码,以下的方法就都不能应用了。

    下面,让我们跳出技术的范围,换个角度来看看如何解决验证码的问题:

    <!--[if !supportLists]-->1、    <!--[endif]-->屏蔽法

    屏蔽法是最容易想到的一种方法,方法的核心就是:在被测系统中暂时屏蔽验证功能。这种方法最容易实现,对测试结果也不会有太大的影响(当然,这种方式去掉了“验证验证码”这个环节,如果该环节本身存在功能上的问题,或是本身就是性能的瓶颈,那就一定会对测试结果造成影响了)。但这种方法也有一个问题:如果被测系统是一个实际已上线的系统,屏蔽验证功能会对已经在运行的业务造成非常大的安全性的风险,因此,对于已上线的系统来说,用这种方式就不合适了。

    <!--[if !supportLists]-->2、    <!--[endif]-->后门法

    后门法不屏蔽验证码,但在其中留一个后门,在代码中设定一个所谓的“万能验证码”,只要用户输入这个“万能验证码”,就能通过验证,否则,还是按照正常的验证方式进行验证。这种方式仍然存在安全性的问题,但由于我们可以通过管理手段将“万能验证码”控制在一个小的范围内,而且只在测试期间保留这个小小的后门,相对第一种方法来说,在安全性方面有了较大的提高。

    <!--[if !supportLists]-->1.4      <!--[endif]-->各种方法的比较

    本文提供了多种用于解决具有验证码的WEB系统在自动测试时遇到问题的方法,这些方法既包含技术性的方法,也包含非技术性的方法。但由于每种方法的出发点不同,因此这些方法也就具有各自不同的优缺点和适用场合。本节我们对本文提到的各种方法进行比较,分别给出其优缺点和适用的场合。

     

    技术性方法

    非技术性方法

     

    识别法

    服务端插入法

    屏蔽法

    后门法

    优点

    不需要修改代码,也不需要在代码中增加额外的接口和后门,在服务端代码不可接触到的情况下,是唯一的选择

    理论上来说可以解决任何验证码的问题,而且不需要修改已有的服务端代码

    简单修改现有代码就能让自动测试顺利进行,开销小

    实现方式不复杂,对现有代码改动小,安全性相对有保证

    缺点

    存在技术限制,只能对相对简单的验证码图片进行分析识别,对复杂的图片无法进行识别

    存在一定的安全隐患,如果被攻击者获知测试接口,验证码就会失去作用

    存在很大的安全问题,对于未上线应用还可应用,对于已上线的实际应用,该方法不可行;况且,由于该方法需要对代码修改的内容太多,导致发布时可能发生某些验证码被不正确屏蔽的情况

    如果被攻击者探测得到万能验证码,则验证码会失去作用

    适用场合

    <!--[if !supportLists]-->1、  <!--[endif]-->服务端代码不可接触到或是不可进行任何修改

    <!--[if !supportLists]-->2、  <!--[endif]-->验证码采用xbm等较简单的方式实现

    未上线系统,或是在测试条件下安全性要求不是特别高的系统;

    开发阶段,未实际上线的系统

    可在实际应用系统上应用

    应用建议

    纯粹的客户端识别解决方案成本较高,建议主要采用服务端方式实现

    在管理上需要增加对测试接口的管理,系统在发布时需要保证去掉测试接口

    在发布管理时,一定要有合理的方案保证发布时所有被屏蔽的验证码能够得到恢复

    为了保证上线系统的安全,该方法一般需要结合密码管理方法使用,通过定期更换万能验证码、控制其知晓范围等手段保证安全

    <!--[if !supportLists]-->2        <!--[endif]-->小结

    针对WEB系统的验证码对自动化测试带来的挑战,本文详细分析了WEB验证码常见的实现方法,并根据分析提出了几种不同的解决方案:识别法、服务端插入法、屏蔽法和后门法。这几种方法各有其优缺点和适用场合,因此本文也给出了这几种方法之间的对比,并给出了各种方法的应用建议。

    当然,本文的重点是介绍解决WEB系统的验证码对自动化测试带来问题的方法,在实际的自动化测试过程中,除了需要了解本文所介绍的方法外,还需要了解相应的自动化测试工具的具体应用方法,虽然不同的测试工具在提供的功能上大同小异,但在具体的使用层面上,不同的工具还是有较大差异性的,请读者自行查阅相应的测试工具文档,从工具的文档中获取相应信息。

     
391/212>
Open Toolbar