《产品研发过程实践》(22) 测试人员

做为一个测试人员,首先你需要明确自己的责任何在?我很愿意把测试人员看成是球场上的守门员,虽然我们不是依靠测试人员来取得胜利,但是如果一个差劲的测试团队,将使得项目离开胜利越来越远。你是团队的最后一道防线了。请站好自己的位置!

我一直说,如果我的精力仅仅允许我在项目中做一件事情,那么我做需求工作,如果允许我做2件事情,我做需求和测试,如果允许我做三件事情,我做需求、测试、和框架设计;这是测试在我心目中的地位!

中国明显缺乏优秀的测试人员。我从事软件行业8年以来,接触的测试人员,测试团队换了一波又一波,但是真正让我觉得很放心的测试人员,只有一个,我很高兴,在去年的时间中,为得实找到了一个良好的高级测试工程师,这是我去年中令我最高兴的3件事情之一(一件是我找到了唐明浩和李兆松,唐明浩在测试领域中的优秀素养让我倍加放心,只要她进行的测试的项目,总是令我很放心,以至于评审她的测试点和测试大纲,是一件让我非常愉快的事情;李兆松是一个非常具有前途的工程师,虽然到目前为止,我还没有看见李兆松完全地发挥出来,但是我相信自己的眼光,具有非常清晰思路,做事明了,具有想法的人员,将来必定能够让我眼界大开的,期待中……,一件是我不顾团队中成员的反对,起用刘海琳,正是刘海琳的宽阔思路和严谨的工作作风,使得Syncin能够很顺利地向前推进,而且几乎没有占据我多少精力,刘海琳的将来也是值得期待的啊……一件是通过我们的努力,我们战胜了不少竞争对手,看着自己的产品逐渐发展起来,多少是让人有自豪感的。)但是就是在这样的环境下,我们还是认为测试是项目中最不重要的一环,测试团队的工资普遍低于开发团队,一个人员如果在开发中并不出色,往往会往测试团队中一塞,仿佛那里是流放地。但是正是这种若有若无的测试,正在摧毁着我们工作热情,折磨着我们的客户,我们的团队。

那么测试团队应该如何作呢?我的概念是:

首先,测试团队(至少是他的Leader),需要了解整体的测试方式,在项目初期就有必要,而且是非常大的必要切入团队,即使参与需求的讨论也是不浪费资源的一种做法,这将使得测试团队更了解客户的需求,能够了解软件的测试重点(我们从来没有足够的资源,来进行完美的测试,那么明了重点何在就显得非常重要了),并且,在需求阶段,他也能从可测试性的角度提出自己的意见,如果一个需求模模糊糊的,测试人员是最敏感的,比如“用户输入正确的内容,然后点击保存……”这种说法,将会令一个测试人员很头疼,这不是扯淡吗?什么叫正确的内容?什么叫不正确的内容?这一点必须搞清楚。

然后,在团队成员进行框架设计的时候,我们的测试主管,一般在进行一些测试方案和测试点设计的工作,比如对于性能性和稳定性测试要求,如果没有测试方案,那么我们如何认可测试的结果呢?比如你用一台PC机运行WebLoad,并发100个企图去压垮一台SUN服务器,这简直就是扯淡,几乎可以确定的一点是,这台PC机受不了了,服务器还是老老实实地站着,结果就是,如果你仅仅通过并发数来衡量系统,你会发现你的系统几乎坚如磐石,如果你使用交易/秒的参数来衡量系统,你会发现这个数据明显偏小。同时,测试点的设计,是根据重要性对系统的重要点进行排列,比如我需要从功能性角度在哪几个地方进行明确的测试,等等;

然后,在团队进行设计的同时,如果需要进行有组织的自动化测试或者有组织的单元测试,那么还需要规划出来自动化测试或者单元测试的框架,来容纳将来的测试代码。并且展开测试大纲的撰写。我们撰写测试大纲,类似于我们的设计文档,我们总是希望测试大纲能够完善,于是后期只要找几个人员(哪怕什么都不懂的),按照测试大纲进行测试就可以了。这是一种理想的状态,但是商业上的事情,我们总不能依靠理想状态来生活着吧。事实上,我们在按照前置条件,过程,后置条件等等安排测试用例的时候,我们应该多少有点觉悟,有时候,你还是需要人员的主观能动性的。并且通过良好的反馈和沟通渠道把发现的问题反馈出来,并且补充进去。测试大纲为我提供的作用是,他是一个规范化的容器,能够不断容纳我们的各种想法,并能够使得这种想法,能够得到确实的落实。

说到这里,我想起一个笑话,但是这个笑话是真实的,这多少有点匪夷所思。呵呵。起因是这样的,某一个部门由于找不到合适的测试工程师(根本原因是认为测试工程师谁都能干,无所谓,简单!),于是缺少测试工程师的部门经理很头疼,而且测试的内容主要是电信领域的信令,说测试工程师一般不了解(其实我认为,不了解就去了解吧,一个协议是很难了解,但是也到不了不能理解的地步吧),于是,想出一个好办法:让项目组自身的开发工程师承担测试任务,部门经理从测试大纲上来控制,确保测试大纲的完整性,然后交由开发工程师相互之间进行测试,来完成测试任务。这个观点让第一次听见的我几乎瞠目结舌,这首先是企图让项目组承担部门管理的失误,如果一个部门管理上文化有问题,导致测试工程师无法到位,就交由开发工程师进行测试,并且承担相应的责任,这是典型的让别人替自己把关的事情。项目组所需要合适的人来进行项目,如果缺失某种人员导致项目的失败,首先资源分配者必须承担责任,而不是团队成员来承担责任。而且从实际管理角度来讲,也是不恰当的,我们面对的不是棋子,你要他往哪个方向走,他就一定会往某个方向走的,开发工程师对此如何看待?他们是否真的有能力做好这件事情(我不认为一个优秀的开发人员,必然是一个合格的测试人员)?我可以想像一下后果:OK,设计是我们大家做出的,代码是我编写的,首先开发工程师会更关注自己的代码,而不是别人代码出现了问题(这是人之常情);当然了,我们将来可以在规则上做出某种责任归属问题,比如某个模块出现了问题,那么开发者和该模块的测试者同时承担责任,这样就可以提高测试者对于测试模块的关注程度了,但是对于一些集成起来的Bugs,谁来负责?而且,由于这种方式,对测试大纲需要进行非常严格的控制,不然你责任如何归属(我是开发人员,不是测试人员,我可以执行测试,但是,要我对测试结果负责,必须是我能够保证我已经执行了某个确定的测试用例,你才能说这是我的问题啊)?那么结果就是两个,要么项目经理兼职做测试主管,要么提一个人起来做测试主管,很简单的结果,不是吗?那么我就不明白了,为什么要那么复杂地解决一个问题呢?这也会造成考核上的一些问题,因为开发工程师的岗位说明书上,没有测试别人代码的职责,你如何考核?等等,说白了就是一点,这种方法,基本上就是胡扯。提出这种解决方案的部门经理,不认为自己多少有点搞笑吗?反正我绝对不会执行这样的方式,就象我不会用技术来解决沟通问题一样,我也不会用所谓的项目流程来解决People manage的工作。而且,把测试的结果完全寄托在测试大纲的完整性上,无异于把自己放在一个危险的境地中,这恐怕过于相信自己的用例设计实力了。我可以容忍小项目组中,需求设计开发人员一路走下来,但是我无法接受开发测试合二为一的做法。如果这样,最简单的方式,就是说服一个哥们,干一段时间专职的测试好了(你可以和他说:靠,哥们,大哥对不起你,我无能,找不到合适的测试工程师,你帮哥们顶一阵子,3个月以后,如果还没有人到位,大哥来替你),要么你就干脆自己冲上去摆平这件事。而不是提出一些类是而非的解决方案,然后问题就是下面人来承担了。这是我所比较鄙视的做法。当然了,有一些公司本身就没有测试,坚信用户就是我们的免费测试人员,呵呵,我也看过也做过。这就没有什么好说的了。这样无顾忌得看待自己的客户,我觉得你有义务把自己的特长贡献给公务员领域(尽快尽快,将来恐怕也不好干呢)。

接着,项目进行开发了,一般来说,我们总是按照某一个周期进行集成和发布,这时候,测试也将对新出现的功能进行测试。一般来说,开发团队需要在下一次版本提交的时候,修复这些Bug。而且原则上说,这些Bug修复的优先级是高于代码的构造的。我总是不希望把一些没有修复Bug的版本,当做一个正常版本发布,因为这会导致过程估算的误导,认为我们项目已经进展得非常顺利了,但是实际上,在最后可能会埋下一个雷的。同时,测试工程师需要反馈,在测试过程中,发现测试大纲的某一些不完善的地方,或者某些用例实际上是可以合并的,对测试大纲进行修整和改进。这也是必须的。我们承认自己可能犯错,但是这些错误需要提供一个正常的渠道进行修改。在不断的提交版本的间隙进行这方面的修改是一个良好的时间。这将使得测试大纲逐渐地更加符合项目,并且这些修改,将使得我们能够对后期项目集成测试的时间进行更准确的估算。

如此循环,一直到项目的构造基本结束,全部模块一起集成起来了,这时候会进行全面的测试,这种测试会以一定的周期进行,比如一周进行一次。这时候,由于已经进入到后期,所以,在非常紧急的时间压力下,我们可能会采用每天下午4:30,进行一次Bugs Review,来确定这些Bug的修改人,以及这些Bug修复的时间等等(在一定程度上,这种方法的确能够提高团队对于Bug修改的重视程度,而且,可以使得团队对于Bug了解更深入一些,同时,可以避免做一些无用功,防止修改了半天,发现最好在另外一个地方修改,并且,由于在项目后期,所以很多Bug未必就是编码期间的Bug,有时候可能出现需求Bug或者设计Bug,这时候,需要尽快决定修改方式来推进)。每天就昨天Bug修改进行一次反馈。当然,在全部周期中,我不太愿意采用这种方法,因为害怕这种会议如果长期使用,慢慢得可能变成一种形式,在平常开发中,我还是愿意采用周例会制度。

进入最后,一般来说,我们会根据Bug衰减的速率来预测测试过程和修复Bugs的过程是否正常,一般来说,Bug应该呈现出2/3的缩减率开始减少(在每个周期内),这样的Bug图表基本上的正常的,如果Bug突起突落,那么很不正常,还需要进一步测试(当然这是建立在良好的Bug填报制度的基础上的,如果Bug填报的制度不完善,那么如何总结都是胡扯)。一般来说,如果是严格的要求的话,一般来说,在1-2个周期的全面测试过程中,仅仅出现2-5个微小Bug,其他没有什么太多的Bug出现,那么这个版本基本上就可以提交了。当然,国内的大多数项目,基本上到不了这个地步,首先我们给予测试留下的时间太短,一般来说,如果真的要达到这种地步,需要留下和设计以及开发相同的时间,测试人员和开发人员之比需要是1:1,基本上可以到达,但是一般我们使用的时间只有1/4,能够让整体流程顺利运行起来,就不错了。这是成本所导致的必然,所以,请各位测试经理和研发经理注意,如果你的产品要求质量很高,那么请至少按照以上比例来安排测试时间和人员。

以上基本上没有涉及性能性测试、稳定性测试以及灾难测试的东西,下面我简要的就我在工作中的做法,做一些说明,这一点在专业的测试人员面前无异于班门弄斧,但是为了完整性起见,还是写下一些比较合适。

性能性测试一般我们如此来进行:首先建立业务模型,比如一个BBS系统,我们根据以前的类似系统的参数可以知道,平均每个用户在网站上会停留10分钟左右,那么在这10分钟中,我们假设用户会进行发表2个新贴子,浏览30-40个贴子,需要登录一次。OK,那么我们就把这种业务做为一个总的“事务”,然后根据总体的性能要求(比如希望每个网页在不考虑传输的情况下,基本上在5秒左右完成打开)。这样我们知道了如何在压力工具上设计事务,也知道我们的目标是什么了。接下来,我们就该建立一个基本的环境,虽然从理论上来说,使用TCPP数值可以完成不同服务器性能之间的换算,但是这一点我在具体的性能测试中,发现其中不是直线换算关系,所以,如果可能,我尽量使用实际的服务器(当然,你的系统的目标服务器如果是IBM小型机之类的高端服务器,那么你还是老老实实和设备提供商的工程师进行性能方面的讨论吧,按照他们的建议来进行性能测试比较好一些),而不使用低端服务器来模拟高端服务器。而且网络的结构也类似于正式环境。然后开始测试了,一般来说,我们会首先压上20-30个并发(按照一般PC机的性能,一般每台PC机器发起10个并发),取一次数据,然后压50、100、200个并发(这对于每天处理百万级PV的系统来说,基本上够了,如果访问量更大,适度增加,但是记住一点,压得太高的并发,实际上意义不大,因为最后对我们来说,有价值的数据不是并发量--这是一个无法衡量的数字--我们所需要是的每秒业务量的数据),然后开一个表格,把统计出来的并发数量,相应时间,平均每个业务处理时间拿出来。

我举一个例子,比如一个系统,一个业务模型中包括50个业务(这是真实业务,比如有的网站中,一个Frameset中包含了5个Frame,你不能把这个算成5个业务过程,只能算一个),然后用100个并发来压,平均每个业务跑10次。假设在500秒内跑完了全部的并发操作,这样一共跑了50000个业务,平均每秒处理业务数量就是100个(这对于一般的业务系统来说是个比较高的数值)。

然后,我们就可以计算了,假设这个服务器来说,大致的访问时间是8:00-17:00(也就是10个小时),那么在10个小时中,一共有36000秒,每秒处理100个业务,也就是每天基本上可以处理360万笔业务。为了应付尖峰时期,我们对360万除以1.5的经验系数,也就是这套系统基本上可以应付240万的业务访问。如果是互联网应用来说,这个数值基本上可以直接对应到日常统计所使用的数据,看看这个数值和其他业务系统来比,性能如何;如果是业务系统,你就需要观察一下,平均每个用户每天处理的业务模型了,这样的业务模型相对来说,就不是上面那么简单了。但是也是使用相同方式来建立模型和大致估算。

同时值得关注的另外一个数值就是每个响应在这样的压力下,平均响应时间是多少。比如上面我们说过是希望在5秒以内,我们就取90%以上访问在5秒以下的那个压力来计算就可以了。

这种统计方法的一个好处是,相对来说比较容易操作,而且数值和客户的使用密切相关;而且对于开发来说,他提供了一种瓶颈的判断方式,比如我们发现性能不能满足要求,那么我们就应该寻找在业务模型中,花费时间最大,而且交易量最大的那个业务着手处理,比如一般来说登录都比较慢,但是他未必就是值得投入最大精力去解决的,因为这一般来说,在业务环中占的比重不大,即使提高得比较多,也未必能够提高很多总体参数。当然了,如果你真的觉得登录速度很重要,那么单独做为一个指标来做,也是适合的。

而且,在性能测试中,一定要注意CPU和内存情况,如果内存一下子全部吃掉了(这一般来说,可能性不大),或者在数据库服务器上,CPU占有率超过了60%,都是值得注意的,在压力环境下,如果出现这样的情况,服务器持续运行时间如果比较长的话,可能存在部分问题。还是适度降低一些比较好一些。

下面,就性能测试讲一些改进的方式,一般来说,数据库访问应用中,对于性能影响最大的现实例子包括,没有使用Connection Pool(不过我觉得,现在还这么干的人,恐怕不是很多的吧,太幼稚的错误了);无节制地取出大数据量,然后在内存中进行分析,而不是使用恰当的做法,使得复杂操作能够在数据库内完成,只取出你需要的数据(数据库IO对性能的消耗,在大数据量的情况下,会占绝大多数的性能损耗),这一般出现在开发时间小于2-3年的开发工程师身上;由于对数据库SQL不熟悉,从而把某一个数据集取出来以后,然后根据其中的某一部分的数值,再次进行检索,这将引起极其大的开销,和适当的撰写SQL来想比,将导致数量级别上的性能损耗,这一般出现在开发时间少于1年的开发工程师身上(偶尔在一些老手的程序中也会发现,这实在有点不负责任了);没有适当使用数据参数绑定,使得性能下降,这在绝大多数团队的开发中都存在……一般来说,你使用数据库监控工具,去分析某一个时间段中的查询,会发现很多问题的。如果是Java程序方面的性能问题,一般来说,你使用一些性能测试工具去跟踪执行,同样也会发现瓶颈所在。要说的一点是,这些工具只是告诉你性能瓶颈在何处,具体如何来做,还是需要依靠有经验的开发工程师的。

性能测试的结果一般来说,对于一台SUN低端服务器做为APP Server,DB被分拆在另外一个服务器上,那么每秒业务量80是应该能够比较轻松做到的。当然,这需要你的业务足够扁平,如果你的一个业务处理非常多的事情,那么你应该反思一下,你是否真的那么需要在一个业务中,做那么多事情了。对于性能来说,框架设计固然能够打下一个基础,但是在编码过程中,造成的损耗也是不可忽视的。比如在一个典型的业务处理系统中,在框架设计中,每秒业务量基本上达到360-380,但是,在系统出现的时候,实际处理业务量降低到100左右。下降得非常厉害。而且这个项目在过程中还是比较重视性能的,要不然可能下降得更厉害了。所以,PM尽量不要去说,我们的业务系统复杂啊,我们的业务大啊之类的话,所以需要非常好的服务器,首先考虑考虑你的业务系统是否有提高的必要。当然我不赞成无限制地去做性能提升,毕竟后面提升的难度越来越大了,但是如果不做一次系统性能的调优,那么实在有点说不过去呢。当然,如果你的系统仅仅20万每天的访问量,即使使用一台低端服务器,也没有太大必要做了,这种访问量,如何做都不会死人的。

稳定性测试方式和性能测试很多相似,但是一般来说,如果时间足够,我们会使用轻载情况下,比如5-10个并发,持续压2周,如果不发现系统问题(比如内存的持续上扬等等),基本上可以认为问题不大。当然,在业务设计中,你需要更仔细一些,尽量能够覆盖住客户的全部操作比较好一些。不要仅仅跑2个业务,跑死了也没有用的。另外一种是重载情况下连续运行3天左右,这主要是因为我有时候发现系统在轻访问量的情况下,反应还不错,但是压力一上来,经常会发现一些奇怪的问题,所以我也倾向于使用重载情况下的测试。当然,稳定性测试的时候,尽量保证系统的平稳运行,不要因为别人给你把机器关掉之类的事情发生,很郁闷的。呵呵,想起来一点,以前有一个哥们为了下班能够下载游戏或者电影,但是怕别人把机器给他关了(下班不关机器,如果被抓,可是比较讨厌的啊,是需要通报的),于是一年四季在自己PC上贴一张纸“稳定性测试,勿动!”,结果一年下来,连保洁的阿姨都不敢替他擦机器了,他的机器显得比别人脏很多啊,呵呵,现在还记得那张忽忽悠悠的纸张,飘动在机器之上,隐隐约约从中可以看见那个哥们的一个烂人模样啊。哈哈。

破坏性测试,难度相对就很高了。绝大多数在系统运行过程中,发生的奇怪问题,都是某一个地方意外出现问题以后,而发生的。比如,一个短信Proxy程序,曾经有一段时间,在和网关失去连接以后,会持续连接,系统会变得很不稳定。等等,这需要测试人员分析系统的各个组成部分,然后使用某些手段,来制造一些异常,来看看问题何在了。当然,在一些协议性测试工作中,这种工作就相对来说很多了,给协议机发送各种错误的协议等等,来模拟各种网络错误,这就是必须的了。呵呵,这一点我没有太多建议,因为这需要单个Case来讨论了。只能说一点,如果必要,你就是做一个错误发生器,对于关键应用来说,都是值得的。因为系统如果上线以后,从现场重现这种错误,难度极大(首先,客户不允许停机来处理Bug,首先必须恢复系统,其次,一旦系统恢复了,除了常规的系统日志,应用日志,你再也没有其他的手段了,只能在相同环境中重现,即使在其中花费1周时间来发现错误,都是很常见的时间,这样成本就高得可怕了,而且这类问题多了一些,会使得我们的客户,我们的开发人员信心急剧下降,士气低落,相比之下,还是事先做一些事情比较好)。我弟弟做了N年的嵌入式开发,他们的测试工程师经常在外设还在读写的时候,突然断电或者突然拔掉数据线,如果发生问题,就当Bug汇报,并且露出阳光灿烂的笑容,很难想像一个一个刚毕业不久的小女孩干出这么粗鲁的事情,很让人惊讶啊,不知道会不会造成心理阴影,形成虐待的倾向。但是这也是必须的,至于用书把回车键(或者其他任何键)压住,然后回家了,回来发现应用程序出错,就是家常便饭性的工作了。

好了,说了很多关于测试的工作,其他也没有什么好说的了。好的程序不是测试出来的,这一点是真理,但是另外一个真理是,好的程序背后必然有一个好的测试,这也是真理。


文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags:
评论: 0 | 引用: 0 | 查看次数: 3695
发表评论
你没有权限发表评论!