reading-notes

张俊的读书笔记

View project on GitHub

s3977865

作者: Alan Page / Ken Johnston / Bj Rollison 
出版社: 机械工业出版社
原作名: How We Test Software at Microsoft
译者: 张奭 / 高博 / 欧琼 / 赵勇 
出版年: 2009
页数: 400
定价: 55.00元
装帧: 平装
丛书: Microsoft核心技术丛书
ISBN: 9787111277538

豆瓣链接

How We Test Software at Microsoft

第一部分 关于微软

第1章 微软的软件工程

拓展大型且高效的业务

最开始的几个版本,每个产品都各自独立开发并发布。这种偏重于产品独立发布的模式通常称为PUM(Product Unit Manager,即产品部门经理)模式, 这在微软内是最常见的。

在PUM模式下,一个产品部门单一组织及管理他们需要的(或至少可以获得的)所有工程资源。他们通常没有依赖其他部门的地方,除非另一个部门提供了一些比较成熟的技术。PUM 模型比较适合那些需要迅速发布的产品并能灵活应对竞争对手,但它不适于资源的集中和共享,例如产品编译或测试自动化工具的生成等。在这种模式下,重复性工作和团队间交流的开销是较高的。

1

共享团队模式

当产品以及产品类别日趋成熟时,其团队通常也随之变大,并自然而然地想通过集中管理来提高效率和降低成本。这种模式有很多名称,但共享团队模式可能是最好的名称。在此模式下,产品的公共功能的开发测试被集中在一个共享团队,其它的产品团队必定依赖于这个共享团队,不然的话,他们的产品功能就难以开发成功。

1

工程类职种的划分

产品工程师是实际参与产品创造和发行的员工。这些产品包括硬件、软件、和相关服务。微软工程角色可分解成以下10个产品工程职种(disciplines):

  • 软件测试:软件开发测试工程师(Software Development Engineers in Test,SDETs ),通常称呼为测试人员(Tester),有时也叫软件测试员。SDETs负责为微软所有产品维持高标准的测试和质量保证。
  • 软件开发:软件开发工程师(SDEs)常常被称为软件开发员。SDEs写的软件程序造就了微软产品以及软件产品的升级。
  • 项目经理( PM ):在微软,Program Manager(简称PM)是一个相当独特的角色。该角色结合了项目管理、产品计划、和设计的要素。项目经理的工作包括给一个新产品的技术方面下定义,并监督产品的发展过程。
  • 运营(Operation):运营部门(Ops)是微软信息技术(IT)的一部分。运营部门管理和维护着微软的在线服务,以及企业内部从网络到服务器的IT基础设施。运营部门和产品部门有着紧密的合作,以求在软件服务架构方面能降低生产成本,和使我们的软件加服务更加可靠。
  • 可用性和设计(Usability and Design):可用性体验和设计(Usability Experience and Design, 简称UX)结合了我们宣传的产品设计和产品可用性的两个角色。设计师关注的是前端用户对软件在视觉和功能方面的体验。可用性则在关注视觉和功能方面的体验的同时,还研究用户怎样使用现有的产品和新样品,然后在产品发展过程中把分析结果用于改进产品。
  • 内容(Content):在我们外部网站上,内容仍称为用户帮助和教育(User Assistance and Education)。这一职位侧重于设计和提供包括用户界面(UI)文字、网络信息、培训、模板、栏目、书籍、测验和帮助文件等各类用户帮助,以便用户从微软的产品中获得最多程度的信息。改名为“内容”是强调微软需要专注于所有不同产品、运载工具的信息内容。
  • 创意(Creative):创意职位最多存在于游戏组。在这个职位的工程师开发和改善微软在个人电脑上使用和在Xbox游戏机上使用的尖端游戏软件。创意职位包括游戏设计师以及游戏艺术设计者。
  • 研究(Research):研究包括软件开发和测试两种角色。软件开发工程师和软件开发研究工程师的差异是软件开发研究工程师的重点放在研究,发表论文,和培养新的技术,而不是按照时间表发行产品。
  • 地域化/本地化(Localization):国际项目工程(Internatioanl Project Engineer, 简称 IPE)曾被称为本地化。本地化重点在于把微软软件的文字翻译成多种语言,并使微软软件适用于不同的国家和地域文化。国际项目工程人员还负责根据具体的地域市场需求,而修订微软的软件的展示和功能。
  • 工程管理(Engineering Management):工程管理是由管理多个职种,比如测试、开发、项目管理等团队的经理们组成的。他们的头衔通常是产品部门经理(PUM)、总经理(General Manager)、或部门经理(Group Manager)。

第2章 微软的软件测试工程师

微软测试工程师的职称并非一直都是SDET

2005年以前,微软实际上用过两种不同的测试职称:软件测试工程师(Software Test Engineer - STE)软件开发测试工程师(SDE/T)。在有些部门,SDE/T职称表明该员工从事测试工具方面的开发工作,在其他部门则意味着,SDE/T拥有计算机科学学位并写过许多测试自动化程序。表2-1列出了SDE/T和STE各自的职责。

表格2-1 SDE/T 和STE的任务

1

学习怎样成为一名微软的SDET

1

微软工程师的职业发展

不管哪一个职种,说到底都只有两种选择:做独立贡献者(Individual Contributor, IC)或做主管经理。所有低级别的工程师都从独立贡献者做起。每一个职业生涯都有一个主要的转折点。对主管经理来说,这个转折点可能是从管理几个工程师的主管到管理其他主管的经理;对个人来说,可能是从影响一个产品到影响一个系列产品。这些转折点被称为职业发展阶段(Career stages)

微软的“技术院士(Technical Fellow)”是独立贡献者职业阶梯上的最高级别。这个头衔相当于管理职业阶梯的高级副总裁。“杰出工程师(Distinguished Engineers)”则相当于公司的副总裁。两者在软件业界被视为其所属专业领域里的精英,经常参与诸如制定业界标准的活动。

测试职种的发展道路

表2-2 从SDET 独立贡献者开始的职业发展历程简介

职业阶段名称 软件开发测试工程师 软件开发测试工程师2 高级软件开发测试工程师 首席软件开发测试工程师 合伙人软件开发测试工程师  
对用户的影响力 从产品支持服务部门和其他的渠道来探访用户的反馈,从而阐明产品功能并写出测试用例 直接与用户交流,从而提供有建设性的产品功能反馈和开发测试用例 对用户关心的产品整合和特定使用场景,角色的创建提供方案,以达到客户期望 具有直接建立用户关系的技能,促进用户和产品部门之间的交流 领导覆盖整个产品线的客户需求的深度理解,从而促进产品设计
对测试的影响力 阐明产品功能如何运行以避免模糊不清的要求 提供有建设性的反馈意见以提高产品规范和技术设计 识别有可能引入漏洞的高风险设计模式 在主要产品上领导测试方法和技术的创新 在整个产品线上领导测试方法和技术的创新

表2-3 从SDET管理开始的职业发展历程简介

职业阶段名称 软件开发测试主管 软件开发测试经理 软件开发测试总监
职业阶段 经理 经理的经理 -
产品范围 产品功能:一个SDET主管的工作范围通常是一组产品功能,或是自成一个小的子系统的非常复杂的产品功能或者是组件,或是一个简单的产品。产品功能的例子包括语音识别服务器,C#编译器,Microsoft Office PowerPoint的图形引擎和IP栈。 产品:一个SDET经理的工作范围通常是一个主要的产品,或是构成一个产品的非常复杂的产品功能,或是一条简单的产品线。SDET经理是产品线的主要贡献者。产品的例子包括Word、 Microsoft Money、和Windows内核。 产品线:一个SDET总监的工作范围包括代表一个损益中心的产品线,或是一条产品线下的非常复杂的系统和结构。产品线的例子包括Windows、 Office、 MSN 和Microsoft Exchange。
招聘职责 领导一个组的招聘流程 积极地优化整个团队的招聘流程和实践 领导一个覆盖整个产品线的全面有效的招聘计划

表2-4:测试管理职称

职称 团队大小 组织的深度
软件开发测试主管和高级软件开发测试主管 2 - 10 1
测试经理,高级软件开发测试经理,软件开发测试经理 15 - 50 2
部门测试经理,首席测试经理,测试总监 30 - 100 3-4
部门总经理,测试副总裁 200+ 4-5

第3章 工程生命周期

微软的软件工程

传统的软件工程模型

瀑布模式

每一个阶段的结束同时也是下一个阶段的开始。工作流程按照指定的顺序进行。

1

这个模式的好处是,当你开始一个新的阶段的时候,前一阶段的所有工作都已完成。这个模式的另一个潜在好处是,它能够强制你在动手写程序以前尽可能多的进行思考和设计。

如果测试的时候发现了一个由于设计缺陷而导致的bug,你该怎么办呢?设计阶段已经―结束‖了。这个明显不灵活性使瀑布模式饱受批评。

螺旋模式

―螺旋‖是一个包含四个主要阶段的迭代过程:确定目标、风险评估、工程实现、和下一迭代规划。

  • 确定目标: 为项目的当前阶段确认和设定特定的目标。
  • 风险评估: 确认主要风险、减少风险及应急计划。风险可能包括超支或资源问题。
  • 工程实现:是完成工作的阶段,包括需求、设计、开发、测试,等等。
  • 下一迭代规划:对项目评估,并开始计划下一轮的―螺旋。

1

重复使用原型(prototype)来让风险最小化是螺旋模式的另一重要概念。初始模式构建于早期设计之上并接近最终产品的特性。在后续迭代过程中,原型可以帮助我们评估工程系统的优缺点和风险。

软件开发团队可以通过初始规划、设计、以及创建产品的原型版的方式来实现螺旋模式。接着他们收集用户对已完成部分的反馈,分析数据以评估风险,并决定下一步的工作。这个过程持续进行直到产品完成或者项目因风险过高而取消。

敏捷开发

螺旋模式的规划和风险评估环节对于许多大型软件产品来说是至关重要的,但对其它很多软件项目来说却太过繁琐。敏捷开发模式侧重于轻灵和小步递进的开发方法。大致具有以下特征:

  • 频繁而短暂的迭代:敏捷团队致力于快速发布软件,并且有做到这一点的纪录。
  • 强调面对面的交流和协作:敏捷团队注重队员相互间和与顾客之间的交流。
  • 对产品要求变化的适应力:敏捷团队灵活机动,他们擅于应对在产品开发周期中的任何环节顾客要求的变化。短暂迭代允许他们频繁地对变化区分优先次序和应对。
  • 贯穿始终的质量责任制:在敏捷开发团队里,单元测试广泛地为开发人员所用。很多人使用TDD(Test-driven Development,即测试驱动的开发方法)。这是一种开发人员先写单元测试程序,然后再实现产品功能以通过该测试的开发方法。

里程碑模式

1

里程碑进度计划建立了项目发布的时间表,也包含了关键的过渡安排和中期版本(例如Beta版和业内预览版)的时间表。里程碑进度计划帮助每个团队了解整个项目的期望值和现状。

里程碑模式的优点是里程碑不仅仅是写在日历上的一个日期。要完成一个里程碑,必须满足具体的、事先定义好的阶段结束标准(Exit Criteria),下面简称阶段标准。阶段标准通常包括以下几条:

  • 关键功能编程完毕:即使尚未完全测试,但关键功能已经实现
  • 中期测试目标达到:如代码覆盖目标或测试完成率目标达成
  • Bug(缺陷)目标达到:如无第一类严重(P1)Bug或无―当机的Bug
  • 非功能目标达到:如性能、负荷测试完成且无严重问题。

各阶段的标准随着每一个里程碑的推进而日趋严格,直到团队达到了最终发布产品的标准。表3-1是一个里程碑项目的各阶段标准示例。

1

质量里程碑(MQ)

Bug的积压,不完整的文档和―将来某天‖必须修补的不可靠的测试,全都可以计入―技术负债。在软件开发中,我们经常不得不妥协。许多妥协最终成了―技术负债‖。技术负债很难对付,我们不理它的话,它不会自己走开。所以,我们必须做点什么。通常我们尝试在干别的某件事情或是在日程表的某个少有的空闲时间试图解决它。这样做的效率如同杯水车薪。

很多微软团队处理技术负债的另一个方法是引入―质量里程碑(MQ)。这个里程碑阶段存在于产品发布以后,下一版本产品开发开始之前,它为开发团队提供了一个修补bug,重新设计测试方法以及修补那些在前一个开发中被搁置的问题的机会。

敏捷开发在微软

功能小组(Feature Crews)

功能小组是一个小型的、跨职种的小组,由3至10个来自不同职种部门(通常包括开发、测试和项目管理)的人组成。这个小组自主地从头至尾负责整个系统中的一个功能块的实现。典型的小组结构是一个项目经理,三到五个测试人员,三到五个开发人员。他们协同工作,用较短的周期设计、实现、测试和整合该功能到整个产品中。

1

这个团队的关键元素是:

  • 足够独立,甚至有团队自己的方式方法。
  • 可以从定义、开发、测试和整合等方面来全方位推动一个产品模块,直到能直接向顾客展示其价值。

表3- 1 功能小组质量门槛示例

1

第二部分 关于测试

第4章 软件测试用例设计的实用方法

实践良好的软件设计和测试设计

测试设计需要从计划和问题解决方面来决定做哪些测试,以及哪种测试在验证功能和确认错误路径处理得当上是最有效的。测试设计中最重要的方面之一是能预见用户的需要和期望,然后创建能够恰当地处理这些需要的测试。

使用测试模式

在“Testing Object-Oriented Systems: Models, Patterns, and Tools”一书中,Robert Binder收录了37种测试设计模式和另外17种针对自动化测试的模式。

测试模式共享的常用形式是模板。Robert Binder的测试设计模板包括了10个不同的属性。微软内对测试设计模式感兴趣的测试工程师通常使用一种基于他的模板的简易模板。这个模板包括以下几个属性:

  • 名称 提供一个容易记的名字——在对话中可以被谈及
  • 问题 提供一句话来描述这个模式所能解决的问题
  • 分析 描述问题的领域(或者提供一小段对问题领域的描述)并回答这个技术如何比简单地随意选择式的方法要好。
  • 设计 解释这个模式如何被执行(模式如何从设计转变为测试用例)
  • 预言 解释期望的结果(也可以包括在设计这一部分中)
  • 用例 列出这个模式如何发现程序缺陷的例子
  • 缺陷和局限 解释在什么环境和情况下,应避免使用这个模式
  • 相关的模式 列出任何相关的模式(如果有的话)

表4-1 边界值分析测试模式

column0 column1
名称 边界值分析法(BVA)
问题 软件中的很多错误发生在数据域的边界。比如,使用 > 而不是 >=, 或者相差为一的索引错误(是以0为基准的索引,还是以1为基准的索引)
分析 根据很多问题都倾向于集中在输入极值附近的基本原理,选择变量输入域在边界或接近边界的测试用例。在安全测试中一个经典的例子是创建一个很长的字符串作为输入来探测可能的缓冲区溢出。更普遍的是,在边界情况下不安全的行为经常是程序员不能预见的。他们更倾向于专注在表面上的情况。
设计 对于每一个输入量, 确定允许的最小和最大值(min and max)。设计一套测试用例来测试最小值,最大值,最小值减1, 最大值加1。(注意BVA有时候被定义为包括最小值加1和最大值减1)。测试用例应该包括: 组件的输入量;要被执行的分区边界;测试用例的期望输出
预言 最小值和最大值应该通过。在这个范围以外的值应该失败并有对失败情况的恰当处理
举例 对允许范围是1到10之间的一个数字的输入域,测试0,1,10和11
缺陷或局限 边界并不总是明确的。需要有对被测产品相关领域的知识或者参照源代码才能做有用的边界值分析。如果输入域包含特殊的值(指在允许范围内的值,但是应用程序处理它们的方法不一样),BVA可能会错过和这些值相关的问题。
相关模式 等价类划分法

估计测试时间

1

用好的和坏的数据测试

测试用例一般包括验证测试(使用期望的输入来验证产品功能的测试)和错误避免测试(使用预期之外的数据来检验产品是否能适当处理的测试)。

黑盒测试、白盒测试和灰盒测试

  • 黑盒测试 (Black box testing)是指一种设计测试用例的方法,它不需要知道任何关于应用程序内部是如何实现各种功能的知识。 根据一个应用程序的用户只关心这个应用程序是否满足了他们的需求,而不关心(他们也不应该)这个应用程序是如何被设计和实现的原理,黑盒测试的方法是一个有效的方法去模仿和预估用户会如何使用这个产品。
  • 白盒测试则是通过对应用程序内部代码或者用户看不到的模式进行分析,并以此设计测试用例。
  • 灰盒测试(有时也称为玻璃盒测试),设计测试首先是从用户关心的角度出发的(即黑盒测试),然后再利用白盒测试方法保证测试用例能够有效并全面的覆盖被测对象。

第5章 功能测试相关技术

等价类划分

ECP(分(equivalence class partitioning)技术,简单地说就是一种工具,使得测试工程师能够以系统化的方式评估一个功能点中每个参数的输入和输出变量。

首先,它有助于我们系统化地降低从所有可能的测试中遴选的测试的数目,但仍然为我们提供了高度的信心:在同一个子集中的其它变量或变量组合会重复地给出相同的期望结果。

ECP技术的另一个优势在于我们可以通过从给定的测试子集中随机选择元素用作测试数据,以有效地提高数据的覆盖率,因为在特定的合法或非法子集中任何一个元素都会产生与同一个子集中其它元素相同的结果(前提是数据已经正确地被分解成离散的子集,而且也没有偏差的软件行为)。

变量分解

最初,我们必须把数据分为两类。合法类数据包括这样一种变量元素集,即这些数据在通常环境下返回正的结果。非法类数据包括这样一种变量元素集,即这些数据应产生错误条件。

可以帮助我们把数据分解为在合法和非法类中的离散集合的四个启发式方法包括:值的范围、变量相似组、唯一值和特殊值。

  • 范围:在数据的邻近集合中最小值和最大值间的任何数据点应产生相同的结果。例 如,你可以从1 到999 间输入一个整数。合法的等价类是>=1 和<=999。非法的等价类范 围包括<1 和>999 的整数。
  • :只要元素被等价地处理,那么元素组是允许的。例如,车辆的元素列表通常决定 了征税的类别,包括:卡车、小汽车、摩托车、房车和拖车。如果卡车、小汽车和房车属于 相同的征税类别,那么这个元素组认为是等价的。
  • 唯一值:在类或子集中的数据可能以不同于同一类或子集中的其他数据的方式被处 理。例如,数据1 月19 日,2038,3:14:07 在处理时间日期数据的应用中是唯一的。它应被分 解为离散的子集。
  • 特殊值:条件必须提供或必须不被提供。例如,在SMTP 协议中,字符”@”是一个特 殊字符,不应该作为e-mail 名称或域名的一部分。

等价类划分实战

在图5-2 所示的“下一个日期”程序需要输入三个整数,代表了阳历中特定的月、日 和年。同时以月/日/年的格式返回下一个阳历日期。

1

1 1

合法类日期范围是在9/3/1752到9/13/1752。英格兰和她的殖民地直到1752年才采用阳历,因此他们排除这十天以同步以月亮为参照的历法。

等价类划分测试

1 1

ECP技术的应用需要花费更多的时间,但是这对于等价类的划分非常有益。当该技术被正确应用时,它可以做到如下:

  • 迫使测试人员对功能集和用于输入输出参数的变量数据进行更细致的分析。
  • 帮助测试人员识别之前被忽视的边角案例
  • 提供明显的事实,以表明哪些数据集被测试过,如何测试的
  • 系统性地增加测试的有效性,以有助于减少风险
  • 通过逻辑性地减少冗余测试来提高效率

边界值分析

BVA或边界测试是特别有用的检测以下类型的错误:

  • 错误的数据类型的人工约束
  • 错误地分配关系运算符
  • 数据类型的封装
  • 差一(Off-by-one)错误

边界测试的定义

Paul Jorgensen建议用于基本边界值分析的测试数量可以用6n+1包括健壮性边界测试的最小值-1和最大值+1数值,这里的n等于独立参数的个数。

月份、日期和年份的极限输入数值分别是1和12,1和31以及1582和3000。用Jorgensen的6n+1公式来进行健壮性边界测试,输入变量的边界测试数量是(6*3)+1或19个测试,在BVA测试矩阵中具体表示,见表5-4。

1

第6章 结构测试技术

与那些既能应用于设计黑盒测试也能应用于设计白盒测试的功能测试方法不同,结构测试技术是一种白盒测试设计方法。以白盒的观点来设计测试是基于程序的内部结构和具体实现。

1

块测试(Block Testing)

函数的基本结构测试方法使用了一些简单技术,包括语句测试块测试。语句测试的目的是执行一个函数中的所有语句。与之相对应,块测试则执行成组的连续语句或不包含分支或函数调用的语句块。

块覆盖测量无分支的连续语句组的数量。导致控制流程转向分支的条件语句可以包含若干块。

Example1 函数

1

Example1 函数显示了块覆盖和语句覆盖测量的基本差异。在这个例子中有5条语句,但只有4个基本块。一个condition参数的值为false的测试具有40%的语句覆盖,因为只有两条语句被执行了。但是块覆盖将会是75%,因为这个测试执行了总共4个代码块中的3个。当然,如果condition参数的值为true,那么语句覆盖和块覆盖都能达到100%。

块测试是用于单元测试的一种普遍方法,它非常适合于迅速地评估某函数的基本功能。对于设计用于执行switch/case语句和异常处理程序控制流程的测试来说,它也是一个很有价值的技术。

第7章 用代码复杂度分析风险

复杂问题

我们用一种寻找高复杂度代码的办法来预测缺陷出现的地方。复杂的代码容易产生更多的缺陷,简单的代码少些。

回路复杂度

回路复杂度(cyclomatic complexity)的度量方法,这种方法由Thomas McCabe开发,它是辩别函数中线性独立路径(或者判断)数目的度量方法。一个没有包含条件操作(比如条件语句,循环,或者三元算子)的函数在整个程序中只有一条线性独立的路径。条件语句在程序流中加入了分支也就在函数中创建了另外的路径。

代码清单 7-1 简单的回路复杂度

int CycloSampleOne(int input)
{
    int result;
    if (a < 10)
        result = 1;
    else
        result = 2;
    return result;
}

这段代码被表示成图7-1 中的控制流程图。

1

基于控制流程图,McCabe 识别出计算回路复杂度的公式是一个边(edges)-节点(nodes)+2 的函数。

图7-1 中标记从A 到D 的节点代表了函数中的语句。用之前提到的公式,函数中 有4 个节点,4 条边或者说节点中的路径。分析表明这个函数的复杂度是2(边(4)-节点 (4)+2=2)

面向对象的度量

最流行的面向对象度量是由Chidamber和Kemerer33创造的,即通常所说的CK度量。CK度量包括了以下的内容:

  • 每个类的权重方法(WMC) 一个类中方法的数目
  • 继承树的深度(DIT)一个类所继承的类的数目
  • 对象类之间的耦合(CBO) 一个类引用其他类的方法或者实例变量的数目

在面向对象的编程中,扇入(fan-in)和扇出(fan-out)度量分别用来计算有多少类调用到某一个特定的类和有多少类被某一个特定的类调用。例如,如果一个类包含的方法被其他5个类调用而且这些方法也调用了其他10个类,那么它的扇入就是5,扇出就是10。

对于复杂代码该怎么办呢? 如果是新代码,高复杂度意味着这段代码需要重新分解。

第8章 基于模型的测试

基于模型的测试(MBT – Model-based testing):采用模型迫使我们将复杂的事物分割成许多清晰,易理解的单元。最终让我们更好的理解整个问题。

建模的基本要点

一个模型可以是对系统的任意描述。一个典型的行为模型中会有一个开始状态,一个或多个 转变,以及一个结束状态。在图8-3 中,开始状态是9,中间过程是减去4,结束状态就是 5。

FSM(Finite State Machine)有限状态机是一个专有名词用来描述一系列的状态和中间的变化过程。它很自然地表达了由状态和中间过程所代表的功能。图8-3 是为数学表达式“9—4” 所做的FSM。

1

图8-3 表示9-4 的有限状态机

1

采用模型测试

图8-5显示了一个有三个按钮的应用程序。第一个按钮打印“Hello”到一个文本框中,第二个按钮打印“World”到一个文本框中,而第三个按钮则清除所有的域。当应用程序开始运行时,无论两个文本框的状态在应用程序终止的时候是怎样的,它们都是空的。

1

1

对状态转换进行随机行走(猴子测试),期望的状态可能会如表8-2中所示。

1

用于 API 测试的模型

1

猴子测试

随机游走:

1

语法模型

1

第三部分 测试工具和系统

第9章 缺陷和测试用例管理

缺陷工作流程

1

撰写缺陷报告

表9-3好缺陷报告的特点

1 1 1 1 1 1

此外,缺陷数据库中普遍使用的字段还有:

  • 如何发现(How Found):什么测试活动发现的错误?
  • 问题类型(Issue Type):是编码错误,设计的问题,文档的问题,等等?
  • 缺陷类型(Bug Type):缺陷类型可能是安全、性能、功能、压力等等。
  • 资料来源(Source):谁发现的错误?测试、开发、内部用户、测试用户、或其他人找到缺陷?

图9-2显示了一个例证:Visual Studio Team System软件缺陷跟踪系统。

1

缺陷会审

缺陷的优先顺序通常设定值如下:

  1. 必须修正(Must Fix)尽快修正这个缺陷。缺陷影响产品在这一领域的进一步进展。
  2. 应修正(Should fix) 此缺陷应该尽快解决,在产品发布前,在这一里程碑末,或在下一轮开发之前。
  3. 有时间就修正(Fix if time) 这是一个小缺陷,可推迟取决于产品开发的阶段。

测试用例管理

图9-5 测试用例模板例子

1 1 1 1

图9-6显示一个开放的测试用例。

1

第10章 测试自动化

Keith Stobie和Mark Bergman在他们1992年的论文“How to Automate Testing: The Big Picture”中用缩写“SEARCH”来描述测试自动化的组成部分。“SEARCH”代表的是设置(Setup)、执行(Execution)、分析(Analysis)、报告(Reporting)、清理(Cleanup)和帮助(Help)

  • 设置 设置指的是将软件准备好,让实际的测试操作可以开始执行。
  • 执行 这是测试的核心,包括检验软件功能的特定步骤,充分的错误处理,或者一些其他的相关工作。
  • 分析 分析是确定测试通过还是失败的过程。这是最重要的步骤,也常常是测试中最复杂的步骤。
  • 报告 报告包括分析结果的显示和传播,例如日志文件、数据库、或者其他分析过程所生成的文件。
  • 清理 清理阶段将软件返回到已知状态使得接下来的测试能继续执行。
  • 帮助 指的是使测试用例在其生存周期中保持可维护性和健壮性的帮助系统。

表10-2 常见的托管代码测试属性

1

表10-3 推荐的测试日志所必备的元素

1

表10-4 测试结果的种类

1

大型自动化测试系统

简单的自动化测试只需要启动一个程序或一段脚本。大型的自动化测试则依赖复杂的构造框架(framework)确保一轮测试(test pass)产生格式一致、通用的测试报告。图10-4显示了包含SEARCH所有内容的自动化测试基础设施(infrastructure)。构造完好的自动化测试系统应该使得完成整个测试套件的执行就像是按一下按钮。

1

第11章 非功能测试

  1. 属性测试:可依赖性、可重用性、可测 性、可延展性和可适应性等等。所有这些都能用来帮助评估和理解超越功能以外的产品质量。 可扩展性(程序能应付过载的能力)和安全性(系统应对非授权改动图谋的能力)是微软团 队内两个接受测试最多的属性。
  2. 性能测试:性能测试的目标是发现重大的系统瓶颈。
  3. 压力测试:在预期的和重负载条件下的表现和处理容量增大的能力,通常被归类在性能测试下面。广义上,压力测试经常包括了负载测试、平均无故障时间(MTBF - mean time between failure)测试、低资源测试、容量测试、或重复性测试。这些不同测试的方法和目的之间的主要区别是:
    • 压力测试 一般来说,压力测试的目的是要通过模拟比预期要大的工作负载来让只在峰值条件下才出现的缺陷曝光。压力测试是要发现软件的弱点所在。内存泄漏、竞态条件、数据库中的线程或数据行之间的死锁条件、和其他同步问题等等,都是压力测试能发掘出来的常见缺陷。
    • 负载测试 负载测试是要探讨在高峰或高于正常水平的负载下,系统或应用软件会发生什么情况。例如,一个网络服务的负载测试会试图模拟几千名用户同时连线使用该服务。性能测试一般都包括测量峰值负荷下的响应时间。
    • 平均无故障时间(MTBF)测试 MTBF测试是测量系统或应用软件在出错或当机前的平均运行时间。这一测试有几个变体,包括平均无错时间(MTTF)或平均无当机时间(MTTC)。技术含义略有不同,但实践上,这些词汇都是一个意思。
    • 低资源测试 低资源测试是要确定当系统在重要资源(内存、硬盘空间或其他系统定义的资源)降低或完全没有的情况下的状况。重要的是要预估将会发生什么,例如为文件存盘而无足够空间、或一个应用程序的内存分配失败时将会发生什么。
    • 容量测试 与负载测试非常相似,容量测试一般是用来执行服务器或服务测试。目的是要确定一台或多台计算机能支持的最多用户数目。容量模型通常建立在容量测试数据基础上。有了这些数据,营运团队(Operations)就能定计划什么时候增加系统容量:要么增加单机资源,如RAM、CPU和磁盘空间等;要么干脆增加计算机数目。
    • 重复性测试 重复性测试是为了确定重复某一程序或场景的效果而采取的一项简单而“粗暴”(brute force)的技术。这个技术的精髓是循环运行测试直到达到一个具体界限或临界值,或者是不妙的境况。举个例子,一个操作也许会泄漏20字节的内存。这并不足以在软件的其他地方产生任何问题,但如果测试连续运行2000次,泄漏就可以增长到4万字节。如果是提供核心功能的程序有泄漏,那么这个重复性测试就抓到了只有长时间连续运行该软件才能发现的内存泄漏。通常有更好的办法来发现内存泄漏,但有时候,这种简单“粗暴”的方法也可以很有效。
  4. 兼容性测试:应用程序兼容性测试(Application compatibility testing)一般注重于应用程序之间或所测试的目标系统与其他应用程序之间的交互。
  5. 安全测试

吃我们自己的“狗食”

“在微软,当我们谈到‘吃我们自己的狗食( Eating our Dogfood)’时, 我是指,‘在你让 任何人吃你的狗食之前,你必须自己先尝尝。” - 史蒂夫·鲍尔默于 2003 年10 月21 日Office发行大会上

第12章 其他工具

代码改动量

改动(churn)是一个特定术语,指的是在一段时间内,一个文件或模块中的代码变化的总量。代码改动有很多种计量方法。以下列出最常用的一些计算方法。

  • 修改的次数:总计此文件被修改了多少次。
  • 增加的代码行数:在某一个特定时间点后,总计有多少行代码被添加入此文件
  • 删除的代码行数:在某一段选定的时间跨度,此文件中总计有多少行代码被删除。
  • 修改的代码行数:在某一段选定的时间跨度,在此文件中总计有多少行代码被修改过。

1

源代码变更追踪

1

每日构建

对大多数组而言,整个产品的源代码每天至少编译一次。微软每天生成新版本的习惯已延续多年,Agile 社区也大力支持频繁的代码签入(check in),不断地集成,连续地构建。构建过程包括编译(将源代码转换为二进制格式的文件), 链接 (将许多二进制文件结合在一起),和运行应用程序所需的任何其他步骤:如构建安装程序和部署到新版本发布服务器上。

测试小组通常运行一套冒烟测试(smoke tests)。更常见的是,这些是大家熟知的构建验收测试 (BATs – Build acceptance tests)或构建验证测试 (BVTs - Build verification tests)。

表 12-2 BVT属性

1 1

静态分析

如下图所示。除了检测许多共同的编码缺陷外,FxCop检测出许多违背编程和设计规则的现象:

1