《Google软件测试之道》摘录

如下是最近看的一本书《Google软件测试之道》里的一些摘录,收获不少。web

一、讨论测试开发比并无什么意义,若是你是一名开发人员,同时也是一名测试人员,若是你的职位头衔上有测试的字样,你的任务就是使那些头衔上没有测试的人能够更好的去作测试。面试

二、只有在软件产品变得重要的时候质量才显得重要。算法

三、假如你被要求去实现一个函数account(void *)返回一个字符串中大写字母A出现的次数。若是候选人上来就直接开始写代码,这无非在传递一个强烈的信息,只有一件事情须要去作而我正在作这个事情,这个事情就是写代码。SET不会遵循这样的世界观,他们会先把问题搞清楚。数据库

      这个函数是用来作什么的?咱们为何要构建它?这个函数的原型看起来正确吗?咱们指望候选人能够关心函数的正确性以及如何验证指望的行为。一个问题值得更多的关注!候选人若是没头没脑地就跳进来编码,试图解决问题,在对待测试问题上他一样会没头没脑。若是咱们提出一个问题是给模块增长测试场景,咱们不但愿候选人上就直接开始罗列全部可能的测试用例,直到咱们强迫他停下来。其实咱们只是但愿他先执行最佳的测试用例。浏览器

      SET的时间是有限的。咱们但愿候选人可以回过头来寻找最有效的解决问题的方法,为先前的函数定义能够作一些改进。优秀的SET在面对拙劣的API定义的状况下,在测试的过程当中也能够把这个API定义变得更漂亮些。安全

普通的候选人会花几分钟经过提问题和陈述的方式来理解需求文档,例如如下几点。服务器

  • 传入的字符串编码是什么:ASCII,  UTF-8或其余的编码方式?网络

  • 函数名字比较槽糕,应该是驼峰式(CamelCased)的?须要更多说明描述,仍是这里应该遵循其余的什么命名规范?架构

  • 返回值类型是什么(或许面试官忘记了,因此我会增长一个int类型的返回值在函数原型以前)?并发

  • void*是危险的。咱们应该考虑更合适的类型,如char*。在一些编译时刻类型检查能够为咱们提供一些帮助。

  • 若是只有一个A的状况,计数结果是多少?它对小写字母a也计数吗?

  • 在标准库中不是已经有这样的函数了吗(为了面试的目的,伪装你是第一个实现这个函数功能的人)?

更好的候选人则会考虑的更多一些。

  • 考虑下扩展性:或许返回值的类型应该是1个64位的整形,由于Google常常涉及海量数据。

  • 考虑下复用性:为何这个函数是针对大写字母A进行计数的?一个好的办法是参数化,使得任意的字符均可以被计数,而不是使用不一样的函数来实现。

  • 考虑下安全性:这此指针都是来自于可信任的地址吗?

最佳的候选人会这样考虑。

  • 考虑扩展

          这个函数会在Shared data(译注:数据分区,是数据库存储分害J( partition)的一种方式。水平分割是一个数据库的设计一准则,数据以记录行的方式存储在不一样的物理位置,而不是经过不一样列的方式存储。或许这才是调用这个函数最有用的形式。在这个场景须要考虑一些什么问题吗?针对整个互联网的全部文档运行这个函数,该如何考虑性能和正确性?

          若是这个子程序被每个Google查询所调用,并且因为外部的封装层面已经对参数作了验证,传递的指针是安全的,或许减小1个空指针的检查会天天节省上亿次的cpu调用周期,井缩短用户的响应时间。最少要理解所有参数验证所带来的潜在影响。

  •     考虑基于常量的优化

        咱们能够假设输入的数据是已经排好顺序的吗?若是是那样,咱们或许能够在找到第个大写字母B以后就快速退出。输入的数据是什么结构?多数状况下都是A吗?多数是字符的混合,仍是只包含字毋A和空格?若是那样,在咱们比较指令的地方或许能够作些优化。当在处理大数据,甚至小数据的时候,在代码执行的时候对于真实的计算延迟也会有比较显著的亚线性变化。

  • 考虑安全性

    在许多系统上,若是这是一段对于安全敏感的代码,能够考虑更多的非空的指针作测试,在某些系统上,1是一个非法指针。

    增长一个字符长度的参数,用以保证代码不会运行到指定字符串以外的部分。检查字符串长度,这个参数的值是否正常。那些不是以null结尾的字符串是黑客们的最爱。

       若是指针指向的数据能被其余的线程修改,这里就有潜在的线程安全问题。

       咱们是否应该使用try/catch来捕获异常的发生?或者若是未能如预期那样正常的调用代码,咱们或许应该返回错误代码给调用者。若是有错误代码的话,这些代码通过良好的定义并有文档吗?这意味着候选人在思考大型代码库和运行时刻的上下文环境方面的问题,这样的思索能够避免错误代码的重复和遗漏。

四、在Google,若是测试运行失败须要清除的知道测试代码在作什么,不然这个测试就应该被禁止掉,或者被标记为怪异的测试,或是忽略这个测试的运行失败,这个问题若是发生了,这是编写出坏代码的SWE的责任,或是代码审查时给予经过的投票的SWE或SET的责任。

五、使用白盒测试知道哪些用例是无效的:

一般状况下,普通的候选人会这样作。

  • 他们会比较有条理地或体系化地提供特定的字符串(如不一样的字符串大小)而不是随机的字符串。

  • 专一于产生有意义的测试数据。考虑如何去运行大型测试和使用真实环境的数据作测试。

更优秀的候选人会这样作的更多一些。

  • 在并发线程中调用这个函数,去查看在串扰(cross talk )、死锁和内存泄露方面是否存在问题。

  • 构建长时间持续运行的测试场景。例如在一个while(true)循环中调用函数,并确保他们在不间断地长时间运行过程当中保持功能正常。

  • 在构建测试用例、测试数据的产生方法、验证和执行上保持浓厚的兴趣。

六、Selenium在浏览器内部使用JavaScript实现,而WebDriver使用浏览器自己的API集成到浏览器内部。两种方法各有优劣。例如,Selenium能够在瞬间打开一个新的Chrome浏览器,但却不能上传文件或者很好地处理用户交互,由于它是JavaScript实现,必须限定在JS沙箱以内。因为WebDriver构建在浏览器里面,它能够突破这些限制,但打开个新的浏览器却比较痛苦。在咱们都开始为Google工做的时候,咱们决定把这两个集成到一块儿。

七、风险分析

  • 哪些事件须要担忧

  • 这些事件发生的可能性有多大?

  • 一旦发生,对公司产生多大影响?

  • 一旦发生,对客户产生多大影响?

  • 产品具有什么缓解措施?

  • 这些缓解措施有多大可能会失败?

  • 处理这些失败的成本有哪些?

  • 恢复过程有多困难?

  • 事件是一次性问题,仍是会再次发生?

八、对于一个web测试页面,一个文本输入框,一个计数按钮,用于计算一个字符串中大写字母A出现的个数。请设计出一系列字符串来测试这个web页面。

      一些候选人头扎进去开始罗列测试用例,这每每是一个危险的信号,说明他们尚未充分思考这个问题。根据咱们的经验,追求数量而非质量的倾向,是一种低效的工做方式,所以会给负面评价。经过观察候选人在找到答案以前思考和解决问题的方式,能了解他们不少东西。

        更好的是那些会提出一些问题,来作进一步澄清的候选人:大写仍是小写?只是英语吗?计算完成后文本会被清除吗?屡次按下按钮会发生什么事情?诸如此类。在问题被澄清以后,候选人开始列举测试用例。重点观察他们是否使用一些疯狂的作法。他们只是在试图破坏软件,仍是同时在验证它能正常工做?他们知道这二者的区别吗?他们是否能从最显而易见的简单的输入开始,尽快地发现大bug?他们能清晰地列出测试计划或数据吗?在白板上随机摆放字符串不能反映出思路的清晰性,他们极可能毫无测试计划,或者只有很粗糙很随意的测试计划。

        一个典型的列表以下:

不管丢失上述测试和总结哪几个都是一个很差的征兆。

更好的候选人会超越输入选择,讨论更加高级的测试问题。他们可能会作如下的事情。

  • 质疑界面的外观、调色板和对比度。如“这些与相关应用风格一致吗?”,“视力困难的人能使用么?“等

  • 担忧文本框过小了,建议加长以便显示更长的输入字符串。

  • 考虑这个应用可否在同一台服务器运行多个实例。会发生多个用户的串扰吗?

  • 提出疑问“数据会被记录吗”,输入串可能包含地址或其余身份信息。

  • 建议使用真实数据进行自动化测试,如从词典或书本里选择。

  • 提出疑问,“计算足够快吗?在大负载下呢?”

  • 提出疑问,“该页是可发现的吗?用户怎么能找到该页面呢?”

  • 输入HTML和JavaScript,看是否会破坏页面渲染。

  • 询问是对大写仍是小写的A计数,仍是都包括。

  • 尝试复制和粘贴字符串。

还有一些想法更加高级,反映了富有经验的、宝贵的测试思惟,可以比问题走的更远。他们可能会这样作。

  • 意识到计算会经过URL-encoded HTTP GET请求传递到服务器,字符串可能会在穿越网络时被截断。所以,没法保证支持多长的URL 

  • 建议将此应用参数化。为什么只对字母A一计数呢?

  • 考虑计算其余语台中的A(如埃A或变音符号)。

  • 考虑该应用是否能够被国际化。

  • 考虑编写脚本或者手工采样来探知字符串长度的上限(例如,经过2的指数递进算法),而后确保在此区间内功能正常。

  • 考虑背后的实现和代码。也许有一个计数器遍历该字符串,另一个跟踪已经遇到了多少个A累加器)。所以,能够在边界值附近变化A的个数和字符串的长度来进行测试。

  • 提出疑问,"HTTP POST方法和参数会被黑掉吗?也许有安全漏洞?”

  • 用脚本建立各类有趣的排列组合和字符串特性如长度、A的个数等的组合,自动生成测试输入和验证。

     了解候选人使用多长的字符串作为测试用例,这一般能暗示他们工做时的表现。若是候选人只是通常性的知道使用“长字符串”(最多见的答案),但却没法就特定场景进行技术性的分析,这是一种糟糕的迹象。更懂技术的候选人,会询问字符串的规格说明,进而围绕极限点进行边界值测试。例如,当极限点是1000的时候,他们会尝试999. 1000和10010最好的候选人还会尝试2^32,以及许多其余有趣的值,例如2和10的次方。重点在于候选人表现出对真正重要的数字值的理解,而不仅是使用随机数值——他们须要对底层的算法、语言、运行时和硬件都有所了解,由于这些正是错误最常常出现的地方。他们还应当基于可能的实现细节尝试不一样的长度,并考虑到计数器、指针及抓环的边界错误。最优秀的候选人还会意识到系统多是有状态的,测试必须将先前的输入考虑在内。所以,屡次输入同一字符串,或者在长度为1000的字符串以后输入一个长度为0的,这些就属于重要的使用情形。

      在Google,鉴于快节奏的发布周期,规格说明常常变来变去,能够有不一样的理解和修改。若是候选人能指出“5个字符的最大长度”这种描述是有点奇怪的,有可能会使用户感到疑惑,这正反映了他们能从用户角度思考。若是候选人不假思索地接受了这个描述并匆忙动手,那他们在实际工做中也颇有可能如此,结果是自费力气验证了错误的行为。那些能反驳或者质疑规格说明的候选人,每每在工做中有优异的表现。固然,也要注意反驳或者质疑的方式。

九、加入一个新项目的头几个星期,我主要用来倾听而不是发表意见,深刻理解团队很是重要,要学习产品的架构,了解团队的最新动态。我不能接受一位医生在观察我不到五分钟的时间就给我开乓抗生素类的药诗之:。一样地,我也不指望个测试团队能够接受,我一开始就提出的什么解决方案。在进行诊断以前你必须先要学习。

      我感受人们有时候作事只是由于看到别人这么作,或者他们测试某个特性的时候只是作那些他们知道怎么作的东西。若是你不问他们为何,他们本身也不会费心思考这事儿,由于他们已经把那些做为了一种习惯。

十、咱们作的每件事都有明确的目的。咱们质疑全部的事情:测试用例、每项自动化测试。其实咱们正在作的不少事情就通不过这种审视。若是自动化不能带来明确的价值,咱们就废弃它。全部的事情都是价值驱动的,这才能成就团队。若是要我给新晋测试经理什么建议,我会告诉他们:大家作的每一件事都要创造价值,可以持续地创造价值。

 十一、个人测试人员个个都是通才。具体来讲,每一个人都能作手工测试,真的是每一个人都能。探索式测试足深刻学习理解一个产品的最佳途径。我永远不会让  一个测试开发工程师成为一个框架开发者。我但愿他们深刻产品并了解如何使用它。每一个测试人员都必须强调用户。他们必须是专家级的用户,通晓整个产品的每一个细节。在个人团队,咱们把如稳定性测试、电源管理、性能测试、压力测试和第三方应用程序的快速检查都留给自动化测试完成。举个例子,没有人可以手动发现相机的内存泄露或在各个平台下验证一个单一特性的功能——这丝都须要自动化。大量重复性的工做不适合手工测试,或者一些须要机器才能达到的高精度测试就必须经过自动化测试来完成。

十二、Google的测试流程能够很是简练地归纳为:让每一个工程师都注重质量。只要你们诚实认真地这么作,质量就会提升。代码质量从一开始就能更好,早期构建版本的质量会更高,集成也再也不是必须的,系统测试能够关注于真正面向用户的问题。全部的工程师和项目都能从堆积如山的bug中解脱出来。

1三、Google在测试方面的秘方:(James)那就是测试人员所拥有的技术能力(包括计算机科学的专业文凭)、测试资源的稀缺从而得到开发人员帮助和不断进行测试优化、优先考虑自动化(这样才能让人去作那些计算机作很差的事情),以及快速迭代、集成和得到用户反馈的能力。其余公司要想效仿Google的作法,应该从这四个方面作起:技能、稀缺性、自动化和迭代集成。这就是Google测试的“秘方”,照方抓药吧!

1四、任何角色都不该被过度强调。团队的每一个人都是在为产品工做,而不是为了开发过程当中的某个部分。开发过程自己就是为产品服务的。除了作出更好的产品,流程的存在还有其余的目的吗?用户爱上的是产品,而不是开发产品流程。

1五、测试的价值是在于测试的动做,而不是测试产物。

        ​相对于被测代码来讲,测试工程师生成的测试产物都是次要的:测试用例是次要的:测试计划是次要的:bug报告是次要的。这些产物都须要经过测试活动才能体现价值。不幸的是,咱们过度称赞这此产物(好比在年度评估时,统计测试上程师提交的bug数量) ,而忘记了被测的软件。全部测试产物的价值,在于它们对代码的影响,进而经过产品来体现。

    ​    ​独立的测试团队,倾向于把重点放在建设和维护测试产物上。若是把测试的目标定位在产品的源码上,整个产品都将受益。所以,测试人员必须把产品放在第一位。