我们不得不佩服冯诺依曼和早期的计算机科学家们,不只是因为计算机这个伟大产物的诞生和发展,更主要的是,这个行业中的任何分支都似乎有无尽的可能性,让一些大牛们终其一生去探究。当然,最让我佩服的是,无论表现上多么的丰富,无论这一行业如何的变化和发展,它的原始方式却依旧没有变化,早已经被早期的计算机科学所限定(事实上不是限定,而是被证明最为有效)。这就像大多数程序员都知道的一个道理,技术的发展速度越快,对那些最基本原理的理解就越为重要。事实上不仅在技术上,即便是计算机和软件行业的管理上,依然遵循着这些计算机的科学的基本原理。这行业本身就是实业,当然也是服务行业,没有行业背景,不尊重行业规则的管理,从严格的行业市场来说,是失败的——这里自然不包括我国国企和政府部门这种有足够预算保障的项目,当然也不包括如某些外包行业中的中国人擅长的“人”的管理。这里只是简单的从操作系统角度上讨论一下测试项目中和自动化测试中一些可以借鉴的地方。
最早的测试其实和最早的编程是一样的——不仅在出现的时间上,在力度和思维方式上也是一样的,因为它们本来就是一个整体。计算机发展的早期,最珍贵的是资源,并不像现在大部分的软件开发一样在堆积木。发明计算机的那段时期,几乎就是不断测试不断调整的过程,和计算机科学的发展是一样的。事实上一个像模像样的操作系统基础代码几千行而已。甚至早期程序员在写代码前必须考虑的清清楚楚,简简单单的代码所带来任何效果和影响,都要理解透彻,着手写代码的时候,事实上测试的思路就已经同时指定出来(最早的测试驱动开发?呵呵)。当然那时候不该叫做开发,只能叫做编程,因为还没有达到可以工厂化生产的程度。当软件达到了可以工业化生产的程度,代码和工程的量级爆炸般的增长,质量参差不齐的从业人员不断增加,才不断的靠经验的积累,形成了所谓的项目管理。实际的工作中,这样的管理包括项目和人。当然,IT行业是服务行业(至少我一直这么认为),测试更是服务中的服务,也就是说,测试的根本,还是在于对项目和人的管理和提供的服务。自动化是手段,并不是目的,不管自动化的地位多高,它的根本目的没有改变,测试是它的载体。就绕到一开始提到的,测试和开发在计算机发展的一开始,就是一个整体,现在来讲,也依然说的通,只是无论了开发还是测试,都因为工厂化的发展规模庞大,所以很多时候需要各自的管理或者“小组作战”。微软的测试投入力度很大,很多大公司的测试投入也很大,无论技术还是人员,但是有一些公司如facebook没有所谓的测试人员,只能说,概念上的质量保证以不同的方式和逻辑分布到了不同的地方,和项目管理一样,无论有再多抽象的模型和流程,事实上最适合自己的测试管理,只有看自己的项目才能决定。
自动化的提出,也没有明确的时间界线,事实上就跟“云”这个概念是一样的,几十年前就有这样的思想,只是硬件的发展成就了当代的云发展。每次硬件的发展都会带来软件的革命,窗口,鼠标,网络,移动,触屏,体感,这些不只促生了软件技术和管理发展,测试管理和自动化也同样与时俱进。刚入行的时候,总是认为向往一些很牛的东西,当时感觉ole和com这些就已经是最早的自动化,随着不断的沉淀,才了解到这些也都是发展的产物。如果让我现在说自动化的开始是什么时候,我的回答就是刚发明计算机的时候。当然也许几年后我的答案也跟着发展,但是现在是这个。刚开始有计算机的时候,必须手工的将纸带装入,之后机器才能进行运行,但是处理器太珍贵了,不能让处理器等待手工的装入;另外,随着硬件的发展,机器运行效率提高,手工的装入耗时却没有改变,也就意味着手工操作占的时间比率越来越高,机器等待的相对时间越来越多——所以才有了分工,才有了程序来管理“装入”,才有了程序管理任务作业,这些构成的整体,其实就是操作系统。所以自动化,也就是自动代替手工的过程,本身就是操作系统的一个目的,也就是为什么我认为自动化是在计算机发明的时候就已经产生了。
测试的目的呢?它到底是一个什么样到角色呢?如果产品和项目的质量有标准,那就是质量保证和评估(需求),如果质量没有标准,那就是产品和项目发展的一种手段和必需到途径。软件所存在的问题,无论从设计上还是从开发上,大都来自三个地方,个人问题(个人开发和设计问题),人和人之间的问题(沟通和合作),环境问题(软件和所处环境)。我一开始提到的早期的程序员(很优秀)和他们到思维方式,能解决这三个问题中第一个和第三个的大部分问题,第二个人和人的问题也能解决一部分——如果这样到话,那么是不是大多数的软件问题都可以通过优秀程序员的工作解决呢?这是不现实的,因为工厂式生产中,有更多大前提,时间,预算,各种约束等,我们真正需要的,是在预算和时间到允许下,将产品交付和完成,测试和质量保证自然也要达标,而且产品的开发和测试并不是脱节的,相互约束并可以相互促进,因为本来就没有严格到界限,分开只是某些时候更适合某种管理方式。所以这时候再说测试管理和自动化测试,思路相对就清晰了:给定的时间和财力预算的情况下,给项目最大程度的质量方面到支持,并尽可能验证和改进项目开发方式和以及流程——看起来好像把什么都占了,其实确实是这样,只是从质量和保证的角度而已。所以整体上来说,测试的价值并不在于创造,而是保证,优化和更新。至于自动化呢,当然它只是测试的一个子集(尽管如测试驱动开发和自动化架构方面会不同程度的深入到产品和项目中),自动化不是测试的目的,是测试的一种手段和途径。如果自动化没有在缩减预算(或者折中)的前提下提高软件的质量,那么自动化就毫无意义,这样的折中在不同项目中权值不高,力度当然也不尽相同,一些武器系统或者航天系统中,不允许任何一点失误的出现,这种时候小于一定研发资金份额的测试投入都是允许的,因为一次失败就意味着整个投入打了水漂;典型的大型超市中UNIX+oracle的系统,必须有容错的处理,不能因为小的插曲影响整体的运作,这也就意味着允许出现预期内的错误,那么投入在这部分中的预算的必要性,就没那么强了。这两种极端的方式,当然采用自动化去测试更为方便和合理,自动化适用的范围有多大?什么时候适用呢?
一般来说不同的公司情况不同,对测试和自动化的理解也都不相同,通常来说,自动化用在:1. 反复操作的相对稳定的系统或软件中(迭代、回归等);2. 手工难以模拟的运行环境(压力、负载等);3. 一些对高精度的测试结果或者手工难以获取的数据的测试(性能、评测等)。当然这里并不包括一些辅助工具和一些环境部署方面的自动化,因为它们并非针对产品质量的,但是却同样属于自动化的一部分。
事实上,测试的范畴是完全由产品决定的,自动化也是在其中尽其所用。不同的产品和项目测试的范围大都不同,但是大概的思路都差不多——由大而小。这和自动化不同,自动化必须找到突破点走通一条路才能实施。抛开流程不说,范围一般这样去界定:先将产品去进行定位,然后按不同的类别去划分,之后每一个划分都添加对各自的测试约束,比如我现在要制作一款主题浏览器,暂时只有windows版本,支持xp和其之后的所有系统。首先说它是一个windows上的软件,那么就要有安装卸载和升级,性能方面要有各项性能指标的测试(GDI,CPU内存占用,句柄等)和压力测试,内存泄露;作为浏览器,它要实现的自己的功能,这些功能太多需要细化这里不讨论;当然浏览器是JS的宿主环境,对JS的支持也要去测试(流行的HTML5也越来越多的被测试);用户会使用浏览器进行各种登陆,所以安全性很重要,安全测试上除了用户的个人信息外,一些敏感数据也是重点;有了用户的数据,就需要测试容错和健壮性,崩溃后对用户的数据恢复等;由于支持多个windows平台,所以平台兼容性也是重点;现在的浏览器与一些硬件关系密切,需要测试对硬件的兼容和支持,比如GPU加速,无线网卡,摄像头等(可能会涉及到不同品牌设备);由于浏览器涉及到安全性,所以需要测试对现有的安全产品的兼容性,比如某山,某斯基,某星,太多某;另外,浏览器产品太多,必须对其进行同类产品的兼容性检测——至少IE系列和其他主流浏览器都要测试;如果浏览器打算提供部分接口供外部网站开发人员进行网站测试,这部分接口开放之前也要进行测试(ms的com,chrome的driver等);当然还有对操作系统的影响,windows系统很多时候会被一些软件干的千疮百孔,即使我们的软件不做同样的行为,至少需要自行的检测或者修复;其他灰色地带测试等等。所有的这些都是这款软件需要做的测试。这时候的自动化呢,也要进行分而治之,因为并不会有一个大的统一测试架构,每一个范畴都可能要进行小范围的突击。
怎么去执行测试管理和自动化测试,同样也可以从操作系统方面得到一起启发。同样,早期的计算机在使用时,需要使用者将自己的纸带装入,越来越多的人开始使用计算机,使得纸带装入和熟悉计算机的花销加大,结果就是在硬件没有提升的前提下,产生了分工——专门有人负责纸带的装入,使用者只需要将纸带交到他手里就可以了,继而有了所谓的流程——不同分工并且有交互,各自负责相关的部分,这时候负责纸带装入的人,发现了把所有的纸带做成纸带卷,可以减少装入的次数提交自己的工作效率,负责写程序的,专注于写出更好的程序来,简单的团队协同工作开始形成。
软件测试管理,很大程度上,是处理好团队协作的事情。将测试目标分而治之,流程化到每一个小组,团队间协同工作,不同的人扑在精通的位置上,组内相互可以做到部分backup,这样就是一个较为理想的团队。每个人都是一个线程,每个小组就是一个任务,避免异步产生的锁定,提高资源共享的高效性,才能尽可能发挥团队的战斗力。
团队合作中,沟通很重要。一个小小的改变,可能会影响到组内的每一个人。无论一个技术水平很高的高级SDET,还是指执行手工用例的tester,都避免不了对组织的依赖。那么一个团队如何去做决策?反过来,依赖于每一个人。个人的想法直接快速,但是片面容易引发问题;开会投票表决会浪费很多时间,效果也不明显。这时候,除了leader外,团队也需要一个具有测试“架构”决策能力的骨干,做到折中和适当的舍去。有时候我们需要让组内每个人都尝试决策组内的一些事情,慢慢提高大家的整体能力,这和学习技术是一样的。当然免不了一些领导不愿意看到手下人的决策能力变强,一些人也不愿意跟自己同一组的人的能力超过自己,创造合理竞争的气氛和“每个人都是经理”的制度可以在某些程度上缓解这种情况,当然,组员们不能只对工作进行抱怨,当抱怨的同时尽可能拿出自己的建议和可行性的计划,工作上的事情公开,将负面影响降到最低。
一些项目的规模,可能达到千人年的庞大,但是每个组的规模却不宜过大,5个人左右为最佳,避免预定会议的麻烦,尽可能减小每个人风格不同带来的影响,而且4、5个人的工作环境,是最佳的——大部分软件工作者在4个人的时候,会最自然的专注到自己的工作上,交谈的情况最少(很奇怪,但是研究是这样的),气氛也相对轻松。
如果参与过操作系统的开发,会了解到有两点容易被忽略却极为重要的元素,其中之一也就是我一开始提到过的,尽早的设计全面,在测试中也就是我们常说的尽早测试——当然如果都能像早期程序员一样开始敲代码前大脑里已经将测试逻辑包含进去,那么所谓的测试驱动就是一个说法而已了;另一个就是日志,不管是日志系统,还是简单的调试信息,日志都是不可或缺的,调试的工作量的庞大是很多人不敢想象的,甚至微软一度为一个开发配两个测试,日志这样的机制,在测试管理中,其实是另一个关键的元素和成功的条件,那就是文档。还记得刚进这一行的时候,被问最多的就是文档看的怎么样了,文档写的如何。在测试组干几年,也许你没有见过同事什么样子,也没有听过同事的声音,甚至代码也没有见过,但是文档,是肯定见过的。在测试管理中,文档比用例的重要性要高——他们的区别相当于设计书和产品的区别。哪些需要文档化?操作系统日志中,一般包含系统日志,应用程序日志等等,测试管理的文档化中,依然是要看项目的具体情况,总的来说有一些东西是必须要文档化的,它们有产品说明,产品设计架构,产品测试概况,测试组织结构,测试在不同阶段的测试计划和重点,测试执行约定,各种报告模板,一些特殊测试的内容列表(如兼容性,安全性等),自动化设计架构,自动化接口文档,产品测试流程,用例规范,灰色地带列表等。
基本上操作系统在测试上给予的提示都是零零散散的,并没有统一的整体,这也难怪,本来操作系统的发展就是一点一滴来的,只有构建在系统之上的软件和系统,才可以一次就把架构考虑清楚,因为已经站立在巨人之上了。
下面还有一些测试管理中的杂项问题,虽然不是主旨,也都可以有些参考。第一个就是自动化测试如何去构建和实施。这里当然不会具体的讨论到某个技术或者某一个产品和系统,只是讨论一些误区和正常的思路。一般所谓的自动化测试架构,是用来解决自动化测试问题的,所以存在一个适用的情况。不管高级的SDET去写,还是开发去写,还是用现成的工具和破解的自动化软件,原则也都只有一个——适用。适用的条件是啥?可行,可操作,够预算。一种自动化方法只有可以解决测试的问题,可以稳定操作,并且在预算之内,才有条件作为适用的方法,选择所有适用的方法,并将其扩展成一个自动化测试架构。和操作系统一样,自动化架构通常包括了操作驱动部分,验证部分,调度部分,日志部分,报告部分,用例开发部分,用例解析部分,其中最难的就是操作驱动和验证部分,也就是适用条件中的“可行”。大部分项目或者产品,自动化的门槛就是找不到“可行”的地方,失去这个突破口,自动化架构中的其他部分也就没有什么存在的意义。“可行”就相当于计算机硬件中的指令,是软硬件的桥梁,没有这个指令,软件就没办法驱动硬件进行工作。实际的测试工作中,一般这个入口可以通过开发时预留接口、开发相关代理、开发配套工具等方法实现——当然指的是那些为了提高某种体验而放弃外部测试接口的项目,通常的项目界面上是标准接口,那么自然不存在“可行”的问题,固定好逻辑就可以很快搭建一套自动化的测试架构;代码的测试相对来说可行的纠结程度并没有那么高,因为大部分都可以通过技术手段解决,单元测试也好,接口测试也好,还是覆盖率测试也好,都有很多可选的已有工具,只要对语言特征很了解,对代码逻辑够熟悉,代码的测试就相对好执行一些,一些专门的白盒测试公司,大多数也是采取模板匹配的方法,相信深谙编译原理的大牛们,肯定对这些不屑一顾。性能测试一般以自动化为主,可能主流的工具用的会相对多一些,某些方面有时候也需要自己去指定,“可行”度一般较高。
核心人物是另一个要讨论的杂项,一个组的核心人物就像操作系统的内核,完成大部分核心工作。这里当然不是指leader,尽管一个负责的leader应该完成一个小组70%的工作。这里所说的核心人物,可是说算作组内的中流砥柱,他并不一定负责组内事物的管理,但是所在小组中的核心工作任务他最为熟悉和上手,就是常说的“大拿”,业务和工作上,一个组必须要有这么一个人。对于这样的人,他的工作执行权力需要适当放大,但是工作量需要适当调整。怎么去合理的安排“大拿”的工作,对一个小组的工作成果影响很大。但是并不意味着不需要其他人,用最少的人在最短的时间内尽可能的多完成工作,并且不会身心疲惫,这并不是不可能,需要将两个关键点把握好,其中之一是物尽其用,协同工作中把每个人放置在最合适的位置上,这里的合适不光指专长,还包括工作状态和心情,当然是相对而言;还有一个关键点,就是领导的调度能力。操作系统有各种的调度算法,目的在于最有效的使用计算机资源。领导需要了解自己组内的各种资源,并进行合理的调度,如果一个小组的所有员工都满足招聘时的JD要求,那么这个组如果无法很好的完成工作,95%的问题是出现在这个负责调度的领导身上。资源不在多少,在于怎么调度来达到最优,好的程序员即使1M的内存也可以写出好的程序,即使如此预算也不可能像硬件发展一样可以用来挥霍。中国的社会压力很大,大把大把的程序员和测试人员,而且测试人员的收入也少的可怜,所以至少在我看来,所谓的人头预算在测试组应该不是多大的问题。
时间问题是最后一个要讨论的杂项,其实国内大部分领导在这上面投入是最多的。外界的约束中,时间和预算是最大的两个,很多人不得不面临各方面的压力——时间太紧,即使不断加班也解决不了困境;预算不够,连基本的团建费用都没有,哪怕是一个冰棍;外行老大瞎指挥,看不懂代码却来指指点点。首先,先要解决这个问题,第二就是在现实已定的情况下,怎么去制定计划。
解决这个问题,一般就是沟通。沟通能解决这个问题是有原因的,资源(时间、预算和人头)是申请的,如果你的老大是内行而且是高手,那么只要不是刁难,他能够批复的资源,绝对是在合理的范围内(IT这行业刁难的事情相对很少了);如果你的老大是外行或者像某些国企的草包,又或者是某政府部门的烧钱高手,那么按IT行业的标准去申请资源,不能说九牛一毛,但绝对不是困难;如果你的老大是外行却不舍得花钱,那么这也不是问题,这样的人胆小贪心,但是绝对不傻,他很清楚的知道如果项目搞不定,损失最大的是他自己,所以只需要把可能存在的问题和风险预估出来,并给出对结果的影响程度,批复资源的时候他自然会考虑到这些。这里有一种情况没有讨论到,就是项目重要性的问题,项目如果是块肥肉,资源申请起来相对容易,如果是一个不知道几手的项目,或者临近被抛弃的项目,所谓的沟通可能解决的问题不大,如果找不到一个让老大们重视起来的理由,资源的申请就有了上限,这时候能做的就是像很多创业公司团队一样组内奋斗做出彩头来。
现在有很多管理类软件和系统,甚至一些移动端的app也开始支持事务的管理和计划,能够按照用户的输入进行提醒并给出任务完成情况的进度表示,一些漂亮的图表当然也是吸引用户的噱头,这些都属于项目管理的范畴,本质上没有差多少。但是事实上这些工具的效用并不大,某种程度上算作闹铃和备忘,对于管理来说就是纸上谈兵,很多领导就算看了一堆数据也搞不懂数字后面的含义,又怎么能给出可行性的决策呢?
我习惯上将项目进度管理分成两大类,就像操作系统中有硬时钟和软时钟一样。时间相对固定长久不变的,需要严格按照安排去进行,以保证目标的定期完成,这种情况下buffer的制定和合理使用就是关键所在,因为通常这类情况属于流程严格、协同作业相对规范的,保证了流程的稳定是最关键的,有时候也习惯的将这种情况比喻成做“京官”,做好治安就可以了,只要不出大事,就能升官,大多数外企和小资员工都处于这种管理之中;另外还有一种,就是不断的变化,甚至连目标都是三天两头的变化,这种变数太多的情况下,所谓的计划和管理挑战性同样也大,他们关注在不同的地方,需要在短期内达到最优(贪心原则?),拿到成果,计划对于实际工作反而是后置的,你永远都看不到文档的随时更新,休假之后回来感觉自己已经脱离了组织,大部分创业公司属于这一类。一些原则的制定,可以帮助领导者尽快投入决策,当然讨论的范畴是人为可控的,一些不可预期的天灾人祸的影响不包含在内;一些诸如各种请假,各种管理矛盾甚至在某衙门盖章这类事情对进度的影响,暂时也不包含在内——很多公司有专门的部门处理这些事情,至于部门如何划分每个公司不同,有些有专门打官司的,有些有专门洗脑的,有些有专门公关的等等。
我提的第一个原则,是深入项目原则,一个领导不深入了解自己所带的项目,他所带的团队就不会优秀。即使我提到的两大类公司招聘员工时要求侧重点不同,但是深入项目,哪类都需要,哪怕是空降的领导,也需要尽早的深入到项目中——当然空降对团队工作是极其敏感的,不必要时很少采用这种方式,一个连编译语言和脚本语言都无法分清的领导,去带领一个纯C或者C++的底层项目,我觉得这不是赶鸭子上架的问题,是上宇宙的问题;第二个原则是折中,曾经有一个鱼和熊掌的问题的讨论在IT界很流行,其实折中的问题在这个行业比比皆是,当然这里依然用操作系统举例子,不管是调度作业算法还是内存管理,最终广为采用的大都是折中的方法,或者带有权值的进行;折中是最优化的一种手段,有时候折中为了最大化盈利,有时候为了最小化损失,所以领导进行折中的前提是明确的知道项目的状态和各种方法的优劣;第三个原则是资源的最高利用率,也就是说,在安排进度的时候,让任务尽可能平均等待在员工手中,而不是让员工在等待分配任务,或者任务分配不均导致出现了问题却找不到原因,当员工知道什么时候主动认领最适合自己的任务并给出正确的预估时间时,资源的利用率达到最优。
到这里,基本上测试管理和自动化测试当中一些可以从操作系统中得到借鉴的主要部分已经讨论的差不多了,严格来说这种讨论是没有开始也没有结束的,甚至过程都不连贯。随着计算机行业的发展,测试的管理和实施也逐渐成为一门学问甚至学科,然而这个领域中大部分结论来源于归纳和总结,并非讲讲故事就可以入行的。让人欣慰的是,这个行业发展到今天,本根性的东西却没有太多变化,无论测试管理和自动化测试,总会不断的从一些最基本的原则中找到可以提升的地方。