(原文来自 James Bach 的博客:http://www.satisfice.com/blog/archives/1577
朱少民 等译,译文最早刊登在 微信公众号:软件质量报道 )
“集成测试”是一个我(James Bach)用的不太多的术语,不是因为它不重要,反而因它是一个基础性概念而已经融入到许多其他工作概念和测试技术中去了。不过,上周我决定尽可能快速来解释集成、集成风险和集成测试的概念。这个部分我推荐给所有重要的测试人员。我称之为“再造测试”,因为每个人都可能为自己再创造测试的概念,在这点上引发了的激烈争论。(请见James的第一部分的博客留言:http://www.satisfice.com/blog/archives/1570 )
如果你有兴趣致力于获得测试方面的通用语言,相信这是我们可以拥有的最佳方式。正如我们每一个人都努力明晰我们的想法,随着时间的推移,不同社团对于合理的测试体系都会趋向事实上的共识。
让我们开始吧……
有几种不同类型的测试,它们之间互相包含或者重叠、甚至可能算得上集成测试的代名词,包括有:回归测试、系统测试、领域测试(Field Testing)、互操作性测试、兼容性测试、平台测试和基于风险测试等等(译者注:这里不一定对,读者不要糊涂)。实际上,大多数测试无论它叫什么名字,究其实质也是属于集成测试的。
以下是我给集成测试的定义,这个定义基于我自己的分析,基于与RST(Rapid Software Testing)老师(主要是MichaelBloton)的诸多交流,还受到本文第一部分众多博客评论的启发。需要说明的是,这里所有的结论和定义是在快速软件测试的框架下给出的,也就是你不必同意我的观点,除非你声明你使用了RST技术。
什么是集成测试?
集成测试是:
- 由潜在风险所引发的与集成有关的测试。
- 专门设计用来评估与集成有关风险的测试。
注释:
1、“引发(Motivated by)”和“专门设计”,似乎意思上有重复,其实不然。举个例子,如果你知道在你附近有个犯罪分子逍遥法外,即使你并不知道他在哪、也不知道他长什么样,你也还是会变得更警惕和谨慎起来。但是,如果你知道他的相貌、他的衣着、他的行为特征或者他的位置,那你就会有针对性的采取一些具体措施或者离他远远的。同样,一个新的集成产品完成后,各种类型的测试都需要执行,有些测试可能并非专门针对未被发现的集成缺陷,或者也会针对那些因为整合通常会导致的各种缺陷类型进行全面测试,比如执行组件间最大限度交互行为的操作等。
“集成测试”是可以代表任何一种有“集成语境(上下文)”的测试行为,或者是在任何情况下应用一项特定的“集成测试技术”。
这是基于风险的测试管理和基于风险测试设计的区别的一种特殊情况,前者在有潜在风险的地方分配资源,但不强制要进行什么测试;而后者则是精心设计那些测试,以发现产品某些特定的问题。
2、“潜在风险”与“风险”不完全相同。“风险”是指坏事情要发生的危险,至少可以从三个方面来看:一个坏事情发生的概率、该事件一旦发生后所带来的影响以及它们(概率或影响)中有一项是不确定的。潜在的风险是指有很大不确定性的风险(换句话说,就是不知道产品里有怎样的缺陷,或者不知道如果某种缺陷出现了会发生怎样糟糕的事情)。测试的关注点就在于消除不确定性的风险,这种风险常在开始的时候作为潜在的风险来猜测(采用天马行空猜测法、墨守成规猜测法或非常了解信息的分析,以确定Bug可能会出现在哪里)。
案例:假设我是第一次做测试,在测试某软件,我不知道它会如何来处理那种高强度的输入,但是这种压力(高强度的输入)往往会导致其失败,那就属于“潜在风险”。再假设我曾经做过压力测试,我对于软件产品如何处理压力非常了解,那么潜在风险就转换成了高风险(如果我发现有好几个与压力有关的BUG),或者转换成低风险(如果该产品以十分恰当的方式处理了压力)。
什么是集成?
牛津英语词典给出的定义是:“一个通过融合独立的部件或元素来组成或者创作一个整体,组合成浑然一体,也就是组成完整的整体或者是全部的集合”。
基于此,我们可以做一个关于产品的“集成”技术的简单定义:
动词:是从部件开始构建产品的过程。
名词:一种由部件构成的产品。
现在,基于系统通论,我们给出如下结论:
集成,在某些方面或者某种程度上来说:
1、是由部件构成的:
- 来自不同的资源部件;
- 为不同目的而生产的部件;
- 在不同时期产生的部件;
- 有不同属性的部件
2、创建或表现为部件的内部环境:
- 内部部件间的相互作用
- 部件间的相互依赖
- 与外部环境的相互作用和依赖的部件
- 这些在外部来说是不可见的
3、具有与部件有关的属性
- 依赖于部件
- 区别于不同部件
因此,你只能通过仔细观察部件来了解有关集成的一切信息。
这就是为什么存在集成风险。在复杂或者重要系统里,集成测试是非常重要的,特别是在某些部件被修改之后。
这可能就需要获得足够的关于集成的知识,来标识风险(说得更明白点,就是可能可以通过它找到所有重要的集成缺陷)而不需要执行集成测试。也许你可以用单元测试的方法来做,虽然这个做法对一些案例是有效的,但是不太切和实际。因为大多这些案例中,部件可能是产生于不同的程序员自己的主观臆断,毕竟很难模拟真实环境下的集成,或者单元测试更倾向于关注工作单元“能”做什么,而不是“实际需要”它做什么。比如,假设单元测试一个计算器,那就需要“能”做许多事,但是可能计算器的“实际需要”只是被要求计算50以内的加法,而不是做所有的事情。
集成测试,虽然在从某些意义上来说是复杂的,但是有可能反而简化了测试工作,因为有些部件遮盖了其他部件的行为,这样测试的工作是只需要关注最后的输出就可以了。
注释:
1、“在某些方面或者某种程度”意味着那些对集成测试的观点(主张)属于启发式的解释。在某些特定的情形下,这些观点很有可能会以有趣或者重要的方式进行应用,但也可能不会。显然,就像前面所说的“部件之间相互作用”,更严格来说就只整合起来的部件可能是没有完全“独立”的,都会与其他部件相关,也可能是在不同方面或者不同程度上的相互关联。作为一个试探性的轻微警告:“如果需要集成什么,就先要知道不同部件间是怎样的相互关系和依赖关系,这些讯息有可能非常重要”。
用“在某些方面或者某种程度”作为概括性修饰语,就可以简化其他文字不必再加其他修饰词了。
2、“基于部件完成构建”并不意味着部件是预先存在的产品,或者是单独存在的产品,或者在集成过程中不会再被改变。而想表达的是我们可以把这些部件看成是产品的组成部分,以及它们是如何与其他组成部分相互作用的。
3、一个产品拥有的某种属性,但是它的部件是没有的,或者部件的属性与产品的属性不同,是以不可预料或者未知的方式而存在的。举个简单的例子,一个三脚架是具有稳定性的,但是它的任何一个脚都不具有稳定性,这个稳定性是因为他们共同作用而具有的。
4、解体也会造成集成的风险。当把某个组成部分拿走,或者分离出来,那就产生了一个新的集成,而分离造成的风险与把它们集成在一起的风险是一样大的。
5、产品的属性和行为显然很大部分是取决于它的组成部分,而且也可能取决于其它因素,比如组成部分的状态、外部/内部环境的配置和状态、以及这些事情操作的隐含的规则(最终,在物理层面上(但更直接的)则是计算环境的通信和处理协议)。
。
6、环境指的是外部的某些对象(对象是指产品或者产品的组成部分),包括与对象交互的诸因素。一个特定的环境可能是在内部是指某些方面,或同时外部是在其他方面的。
内部环境是一个由产品控制的环境,产品的组成部分才能够访问它。它在产品的内部,但是从某些组成部分的视角去看,是在它们的外部。例如,对火花塞来说,发动机的气缸内部是一个环境,因为作为整体,它又不是在汽车的外部,所以它是一个内部环境。技术常常就是由多层嵌套环境所组成的。
外部环境是产品运行的环境,但又不受产品控制。
控制不是“全有或全无(all-or-nothing)”那样的事情,而是有不同层次和类型的控制。正是因为这个原因,不总是有可能去严格确定产品的确切范围、产品的各个方面,或者可能会重叠的环境。这使得测试工作,尤其是安全性测试,非常具有有挑战性。很多恶意的黑客行为正是基于发现那些开发者认为是外部环境,而其实质是内部环境的漏洞。
7、当一个事物影响另一个事物时,交互就出现了(这里的“事物”可以是部件、环境、整个产品或者其他任何东西)。
8、当一个事物要求另外事物来执行(或不执行)某个动作或者具有(或不具有)某种属性,为了让前者以表现某种方式的行为或执行某种请求,这就是依赖。
9、整合不是只有全部整合或没有整合两种,而是由不同程度和类型的整合。一个产品会意外的被整合在一个产品中,因为它使用了没有人注意到的部件。这也许是松集成,就像壁虎可以抛弃它的尾巴,或者就像浏览器是里的一个插件。也可能它是紧集成,就像我们从一个产品中取出代码加到另一个产品的不同地方,一面运行一面编辑。(或者当你消化食物时)它可以对其部件的现有接口进行保护、阻止、重新设计或删除。以上对“集成”的定义和声明,是一种启发式模式,一种透视镜,我们透过它可以更好地了解产品和它失败的原因。不同的人可能会将不同的事物视为其组成部分、环境或产品,那都没有关系。可以自由“移动这个透镜”,也可以尝试对集成这个概念的不同的透视角度。
一个集成问题的例子
这张图显示了一个典型的集成缺陷:竞争性依赖(Dueling Dependencies)。在上面的两个面板,两个构件正快乐的在自己的环境中工作。工作中,互相之间没有意识到有对方,我们称它们为独立计算机。
但是,当把它们安装在同一台机器上,可能就会变成互相依赖于需要排斥对方。虽然构件本身并不冲突(这里假设蓝A箱和蓝B箱没有重叠部分)。通常这类的依赖关系会很少有相关文档,也许开发人员在集成之前完全不了解。
也许这可以通过单元测试来发现它们……,但是集成测试进行地更早,其工作更容易、成本更低。