谷歌如何测试-章节1:谷歌软件测试的介绍
我一直有个疑问,谷歌是如何测试软件的。我不知道我回答了多少次这个问题,我也不记得给了多少个不同版本的回答,但是这个回答随着我在谷歌的时间越长,而不断演化;我了解到更多的各种测试方法的细微差别。我把它放在脑海里,以便我能写一本书,那时Alberto,也建议我写这本书。
然而,我在继续等待。我的第一个问题是我不是适合写这本书的人。在谷歌有很多比我先在谷歌工作的人,他们应该先写这本书。我的第二个问题是我是Chrome和Chrome OS的测试负责人,我仅仅了解的是谷歌测试的一部分。还有很多的谷歌测试我需要去学习。
在谷歌,软件测试是“工程部”的一部分,这个部门涵盖开发人员和测试人员的工具链、发布引擎、单元测试到探索性测试。有很多共享的工具和测试体系,这些都作用于网页相关的特性,例如搜索、广告、应用程序、youtube,和我们在网页上能做一切其他事情。谷歌解决了很多速度和规模方面的问题,这让我们,尽管是个大公司,发布软件的速度仍然很快。正如Patrick Copeland在这本书里的前言里指出的,这种神奇的快速的发布速度,相当部分是因为测试团队的存在,才能如此迅速的。
关键点:At Google, softeware testing is part of a centralized organization called Engineering Productivity.
当2010的12月份,Chrome OS发布后,我开始介入更为繁重的其他产品。这是这本书的开始,我写了第一篇博客做实验下,博客名为“How Google Tests Software”。六个月后,这本书终于完成了。在这六个月内,我了解了更多的谷歌所做的测试,比我这两年在谷歌做的测试还要多。现在我的同事们正在阅读这本书来作参考指引。
这本书不仅仅是用来介绍大公司如何测试软件的。我在微软,当Alan Page, BJ Rollison,和Ken Johnston写“How we Test software at microsoft”的时候,我获得很多他们写这本书的第一手的资料。微软在测试领域是顶级的。他把测试提高到成为软件工程精英的一项荣誉。在各种宣传后微软测试人员成为最抢手的人员了。他的第一个测试主管,Roger Sherman,吸引了来自全国各地的测试领域方面志同道合的人来到微软。这时是软件测试的黄金时代。
然后,微软就写了本书,把所有测试的东西文档化。
那时,我没能最够早的介入微软的这本书里,但是我获得了第二次机会。我来到了谷歌,这时谷歌的测试是在上升期。工程部从几百人迅速扩展到1200人。关于成长的烦恼,Pat在他的前言里有说到。谷歌测试博客每月有成百上千的访问量。GTAC(谷歌自动化测试协会)已经成为测试行业最重要的一个会议。Patrick很快得到提升,有几十个主管向他反馈和汇报。如果你想让软件测试复兴,谷歌无疑是在这场软件测试复兴的震中。
这意味着谷歌的测试也值得写成一本大部头书籍。问题是,我不写大部头书籍。然而,谷歌是以他的简单和直接的方式而著称的。这本书因而也不会写成大部头的著作。
谷歌如何测试,包括了对于谷歌测试人员的核心信息,以及我们如何处理大规模、复杂的问题。这本书将有你从其他地方看不到的东西。如果你觉得这本书对于你了解我们怎么测试还不够的话,那么请Google它,互联网上会有更多的收获。
谷歌测试软件的方式,很可能会成为许多公司的测试方式;因为越来越多的软件会逐渐从桌面软件迁移到会联网上。如果你已经读了微软的书,请不要以为会在谷歌这本书上找到很多相似点。除了作者的数目相同外,这两本书都有3个作者,事实上,每本书记录的都是一个大型软件公司的测试实践,其他的不会有太多相同。
Patrick Copeland在前言里已经介绍了谷歌的测试方法是怎么来的,随着公司的成长,谷歌的测试也在不断发展。谷歌就是一个工程师的大熔炉。谷歌的文化和创新会使,无效的技术会被丢弃或者改进。由于测试队伍的膨胀,新的实践和想法不断地被尝试;有用的会被谷歌采用。谷歌测试人员是愿意尝试任何东西的,并且会很快丢弃无用的技术。
谷歌时一个在创新和速度上构建起来的公司,他会当产品有用时就发布代码;然后不断迭代改善早起发布的东西(最大化的进行反馈)。在这种环境下的测试,必须是灵活的;需要太多的前期规划或持续未回的技术,是行不通的。有时,测试是和开发交织在一起的,导致这两者很难做区分;但有的时候,它又是完全独立的,以至于开发者都不知道测试的存在。
纵观谷歌的成长,他的快速的脚步已经放缓了一点。我们可以花一年的时间做一个操作系统;我们每隔几星期发布客户端应用程序,例如Chrome;每天都更新web应用。在这种环境下,我们尽力让测试不是教条化的、也不是过程繁重的、劳动强度大的和费时的。有一点可以肯定的是:测试不会给创新和开发制造麻烦。至少它不会做两遍。
谷歌在测试方面的成功,不能归结为是项目小或者是软件简单。谷歌软件测试的规模和复杂度和任何其他的公司是一样的。从客户端操作系统,到web应用,到移动,到企业,到商业和社会,谷歌几乎在每个行业都有涉及。我们的软件是大型的、复杂的;他有上百万的用户;我们为了hackers,我们的大部分源代码都是开源的;我们的代码在数百个国家运行着;在此之上,用户希望谷歌的软件是简单易用的。因此谷歌的测试人员机会每天都面对各种测试挑战。
无论谷歌做法是否正确,但是有一点可以肯定:谷歌的测试和我所知道的其他的任何一家公司都是不同的。而从桌面到云端的变迁,有可能会使整个行业会越来越流行类似谷歌的实践方法。我和我的伙伴们希望能通过这本书抛砖引玉,让大家看到谷歌怎样在这个产业里面对发布可靠的软件这一艰巨任务的做法。也许谷歌的做法有他的不足之处,但是我们仍想对全世界的测试社区来出版和公开他;这样他也能不断的改善和发展。
谷歌的做法是有点不合厂里的:我们只有很少的专业测试人员,而我们的竞争对手们常常有个专门的队伍。谷歌测试没有上百万个人。我们是小型的、精锐的特种部队,依靠优越的战术和先进的武器装备,来获得战斗的胜利。和军方的特种部队一样,正是因为是稀缺资源导致我们形成了自己的秘密武器。这种稀缺迫使我们更明确。从功能特性到测试技术,我们已经学会了如何创建高影响力、低阻力的活动来追求我们的质量。也正是这种稀缺测试资源,是的测试资源高度被重视,让聪明的人们积极的自律和参与到测试中去。当人们问我我们成功的要诀时,我给他们的第一个建议是:不要雇佣太多的测试人员。
那谷歌是怎么用少量的人来测试的呢?简单来说,在谷歌,编写代码的人承担着质量的责任。质量不再是一些测试者的问题。每个编写代码的人都是一个测试人员,并且质量是整个团队的问题。在谷歌谈到开发和测试的比例,就像谈论太阳表面的空气质量。因为如果你是一个工程师,你就是一个测试人员。如果该你的头衔是测试工程师,那么你是一个推行给那些不擅长做好测试的推动者。
事实上我们产出世界级的软件,也证明了我们的方案是值得学习的。也许在其他的组织里,其中有部分会有用。当然,也有部分需要得到改善。以下是我们总结的公式。在最近的几章里,我们将深入细节来展示:我们是如何将测试实践与以开发人员为中心的文化来融合的。
质量不等于测试
“Quality cannot be tested in”虽然是老生长谈,但是他却是真实的。从汽车到软件,如果他没有正确的构建出来,那么他永远都不可能正确。就像任何汽车公司因为螺栓质量问题而召回一样,代价有多昂贵。从一开始就做正确,否则你就是制造了一个永久的麻烦。
尽管如此,他既没有听上去的那么简单,也没有听上去的那么准确。尽管说质量不是测出来的,但是没有测试,也不可能提高质量。那怎样在没有测试的情况下,创造高质量的产品呢?
解决这个难题的一个简单方案是:不要把开发和测试作为独立的专业。测试和开发是可以齐头并进的。写一点代码就测一点代码。多谢一点代码,就多测一点。测试不是独立的活动;他是开发过程的一部分。质量不等价于测试。通过把测试和开发融合在一起,直到无法区分彼此,来达到对应的质量区别。
在谷歌,这是我们的目标:把开发和测试融合,而不是单独进行开发。关键是谁来做测试。因为在谷歌专业测试人员比例非常低,所以唯一的可能就是开发人员做测试了。谁会比写代码的人更适合做测试?谁会比写代码的人更容易找到bug?谁会在一时间避免写出有bug的代码。谷歌可以让这么少的测试人员的原因,是因为开发人员自己对代码负责。如果一个产品出现问题了,第一点问的是哪个开发人员造成了这个问题,而不是测试人员没有查到他。
这意味着质量更多的是预防,而不是检测。质量是个开发问题,而不是测试问题。在一定程度上我们能把测试嵌入到开发中去,我们已经创建了一个递增迭代的流程,能让如果任何一个增加导致漏洞很多的时候,让它回滚回来。我们不仅仅是预防很多客户的问题,我们也能保证在减少了专业测试人员的情况下,不会有召回产品之类的错误。在谷歌,测试的目标是确定如何预防问题的。这种开发和测试能融合在一起,适合谷歌的开发心态密切相关的,每次代码评审时,都会问“你的测试在哪啊”来提醒开发人员需要做好测试。
角色
为了实现"you build it, you break it",在典型的开发角色之外还有其他的角色。特别是,让开发人员有效地执行测试的工程师角色应该存在。在谷歌我们创建了一种角色,他的工作是负责让其他工程更有效更高质量工作。这些工程师,常常标榜自己是测试人员,但是他们实际的任务之一就是提高效率。他们让开发人员更高效的工作,也避免因为马虎开发而导致的重复工作。质量是效率的一个大的部分。我们将花费大量的时间在后续的章节里来讲述这些角色。因此这里只做一个简要介绍。
software engineer(SWE)是典型的开发人员角色。SWE写面向用户的代码。他们创建设计文档,选择数据结构和整体架构,同时他们花费大量的时间来编写和Review代码。SWE写大量的测试代码,包括TDD,单元测试(这些我们会在本章后面有介绍,特别是small, medium, large tests)。SWE从编写代码、修复bug到修改代码,相关的质量都要负责。是的,如果一个SWE修改了一个函数,这个修改时一个测试失效,或者是需要添加新的测试,他们必须自己编写那个测试。SWE花费百分百的经历在编写代码上。
software engineer in test(SET)也是一个开发人员的角色,只是他集中在可测性上,以及产出测试架构。SET review设计,并且紧密关注于代码质量和风险上。他们重构代码来让他更可测,并且写单元测试框架和自动化。他们是SWE的合作伙伴,但是相比增加新功能和提高性能而言,更关注于提高产品质量和测试覆盖率。SET花费百分百的时间在写代码,但是他们是为了代码质量服务的,而不是为了编写新功能服务的。
test engineer(TE)是和SET相关的角色,但是关注点不同。他是首先关注于用户的测试,其次才是开发人员的测试。一些TE花费大量的时间写自动化脚本和代码来驱动和模拟用户。他们组织SWE和SET的测试工作,解释测试结果,驱动测试执行,特别是在项目的后期,来推动大量版本的发布。TE是产品专家,质量顾问和风险分析师。他们很多人写代码,也有很多人写很少的代码。
从质量角度来看,SWE负责功能和功能特性的质量。他们主要负责容错设计、故障恢复、TDD、单元测试、和SET一起写测试来检测他们的他们。
SET是提供测试功能的开发者。提供一个框架能通过模拟实际工作环境(一个涉及到存根、mock、fake的程序),并提交管理开发check in代码的队列。换句话说,SET写代码来方便SWE来测试他们的功能。
显然,SET主要集中在开发人员上。他们的目标是能让开发人员简单的写测试代码,来提高品质。关注于用户的测试是TE的工作。TE是对开发人员辛勤工作的一个检查。发现的任何明显的bug表明早期开发人员所做的测试时不充分的,或草率的。当这种bug很少时,TE就能花大量精力来确保软件在常见的用户场景中,是否满足性能目标,是否安全,是否国际化等等。TE进行大量的测试和与其他TE、测试临时工、测试人群啊、dogfooders, beta用户啊等等来管理和协调。他们沟通各种存在的风险啊,功能复杂度啊,避免失败的方法啊等等。
组织结构
在我工作的大部分组织里,开发和测试是作为同一个产品团队里的成员的。在组织层面上,开发和测试都对该产品团队的负责人汇报。一个产品就是一个队伍,每个人都是在一个页面上。不幸的是,我从来没有见过这种结构有效果。高级管理人员往往来自项目管理和开发团队,而不是来自测试团队。这样导致,往往优先次序是完成功能的优先级更高,而不是核心质量的优先级更高。作为一个单独的团队,测试是趋向于服从开发的。很明显,这会导致发布出充满bug的产品。
谷歌的汇报结构则是划分为Focus Areas或者FAs。有一个FA,负责客户端(Chrome,谷歌工具条等等)的Geo(谷歌地图等),广告、应用程序、移动业务等。所有的SWE则汇报给FA的董事。
SET和TE打破了传统行业的规则。测试是以一个独立的平行团队存在的,被叫做Engineering Productivity(工程部)。测试人员是被租借到产品团队,来提高质量,并且给缺乏测试或者存在不可接受的错误率的功能提问题。因为我们不向产品团队汇报,因此我们不能简单的被认为是参与程序。我们自己决定可靠性、安全性等优先级。如果一个开发团队想让我们做测试,必须事先商量,而且我们可以随时说不。
这种结构帮我们控制了测试人员人数很少。一个产品队伍不能随意的降级测试人员的技术级别,或者雇佣更多的测试人员来做那些简单的活。工程部根据产品的优先级、负责度和需求来分配测试人员。显然,我们可能分配时不合理,有时候我们也会出现分配不合理的情况;但是总体来说,它在要求的测试资源和实际需要的资源当中取得了平衡。测试人员的这种租借状态,也利于从一个项目迁移到另一个项目,不仅仅保持了新鲜感,而且能确保好的想法快速蔓延到整个公司。例如在Geo产品使用的一个测试技术或者测试工具会当这个测试人员迁移到Chrome后被使用。通常一个测试人员在一个产品呆上18个月,那以后,他或她就能去另一个团队。可以想到这种会出现多面手的测试人员。谷歌是一个充满了既懂客户端、web、浏览器和移动技术的测试人员。因为谷歌的产品和服务现在已经很紧密的绑在一起,测试人员能去公司的各个项目,并拥有相关的专业知识。
Crawl, Walk, Run
谷歌能在很少的测试人员的情况下达到很好的结果的,一个关键方法是:我们很少尝试一次性的发布一个大的功能集合(也就是很多的功能点)。事实上,我们构建产品的核心,并且在发布的时候确保他能对尽可能大的人群有用,然后得到他们的反馈和迭代。我们的Gmail就是这么做的,产品一直维持beta版本长达4年。这个beta版本是用来告知用户该产品还在完善中。而这个beta标签是在我们达到我们预期目标一个真正用户的正常运行时间的99.99%时,采取掉该标签的。我们在处理android生产G1时,也是这么干的。需要特别说明的是用户为这个产品的早期的版本付钱了,而该产品的功能必须足以使用户这么做。因而早期的版本并不意味着是个产品低劣的版本。
注意:谷歌常常构建一个最小化的有用的版本作为初始版本,然后快速迭代后续的版本来适应内部和用户的反馈,并每小步仔细的改进质量。产品经历了canary(金丝雀?) 、开发、测试、beta测试、发布渠道后,才给用户使用。
事实上,为了能够实行我们所说的beta渠道的发布,一个产品必须通过一系列其他的渠道来证明他是值得的。例如chrome,我花了2年的时间在这个产品上,用了各种渠道来收集反馈和建立我们队产品质量的信心。这些过程类似下面这些:
Canery Channel:这个是用来每日构建来确定是否适合发布的。就像煤矿里的金丝雀,如果每日构建失败了,那么他表明我们的过程已经变得混乱了,我们需要重新审视我们的工作。一般说来,工程师是通过这个渠道检验后的版本来工作的。
*注:安卓团队更进一步,他们的手机一直持续不断的运行daily build.因为他们不喜欢检入糟糕的代码而不能打电话回家
Dev Channel(开发渠道):这是开发人员用来每天工作的渠道。通常是以每周来构建成功的应用,并通过一定的测试(我们后续会讨论)。所有的工程师都要求执行Dev Channel build,并用它来工作和持续测试。如果一个Dev Chanel构建不适合工作,就会返回到Canary channel。那将是不妙的状况,会促使整个团队的进度要重新评估。
Test Channel(测试渠道):