一、集成测试

  • 术语

集成测试是继组件测试之后的又一个层次。集成测试假定交给这个层次的测试对象已经经过了组件测试,并且任何组件内部的缺陷都已经尽可能地被纠正。

  • 集成

开发人员、测试人员和专门的集成团队然后将这些组件组合成更大的单元。这个过程被称为 “集成”。

  • 集成测试

一旦组装完成,你必须测试集成的组件是否能正确地相互作用。这个过程被称为 “集成测试”,其目的是为了找到集成组件之间的接口和互动的故障。

  • 测试基础

在这个层面上,所有描述软件结构和软件系统设计的文件,特别是接口规范、工作流程和顺序图,以及用例图,都要作为测试基础来参考。
你可能会问自己,既然所有的组件都已经单独测试过了,为什么还要进行集成测试?我们的案例研究说明了必须要解决的各种

案例研究: VSR-II DreamCar模块的集成测试

VSR-II DreamCar模块是由一些基本组件组成的。
在这里插入图片描述

这些组件之一是CarConfig类,它负责确保车辆配置(基本型号、特别版、额外的附加物等)是允许的,并负责计算结果的价格。该类包括calculate_price()和check_config()方法。该类使用CarDB类从数据库中读取所需的车型选项和价格数据。

前端使用get_config()读取当前的车辆配置,并将结果呈现给终端用户,以便在图形用户界面上进一步调整。对当前配置的修改使用update_config()返回到后端,然后check_config()检查配置是否被允许,并适当地重新计算价格。

  • 集成测试是关键

正如上面的例子所说明的,组件测试不能保证组件之间的接口是无故障的。这就是集成测试层面对整个测试过程的关键所在。潜在的接口故障必须在那里被发现,并隔离其原因。

  • 系统集成测试

上面的例子还表明,在集成和整合测试过程中,还必须涵盖与外部系统环境的接口。当与外部软件(或硬件)系统的接口被测试时,这个过程通常被称为 "大集成测试 "或 “系统集成测试”。
系统集成测试只有在系统测试完成后才能进行。在这种情况下,风险在于开发团队只能测试有关界面的 “他们的一半”。而 "另一半 "是外部开发的,因此随时可能发生意外的变化。即使系统测试通过了,这也不能保证外部接口总是按照预期的那样工作。

  • 测试环境

集成测试还需要测试驱动程序为测试对象提供数据,并收集和记录结果。因为测试对象是复合单元,没有与外界的接口,而这些接口不是由它们的组件部分提供的,所以重新使用为单个组件测试创建的测试驱动是有意义的。

  • 测试目标

集成测试的目的显然是为了找到接口故障。如果两个组件的接口格式不匹配,所需的文件丢失,或者开发者编程的组件不符合规定的划分,那么在第一次尝试集成时就已经出现问题了。这样的故障通常会在早期通过失败的编译或构建运行被发现。

  • 集成策略

为了最大限度地提高测试效率,应该以什么样的顺序集成组件?测试效率是用测试成本(人员、工具等)和有用性(发现故障的数量和严重程度)之间的关系来衡量的,对于特定的测试层次来说。测试经理负责为手头的项目选择和实施最佳的测试和集成策略。

单个组件的完成时间可能相隔数周或数月。项目经理和测试经理不会想等到所有相关的组件都准备好后再进行一次集成

处理这种情况的一个简单的临时策略是按照组件完成的(随机)顺序来集成。这包括检查新到的组件是否应该与已经存在的组件或子系统集成。如果这个检查是成功的,新的组件可以被集成并进行集成测试。

  • 自下而上的集成

测试从不调用任何其他组件的基本组件开始(除了操作系统的功能)。较大的单元是由经过测试的组件逐步建立的,然后再进行集成测试。

二、 系统测试

  • 术语

一旦集成测试完成,下一个就是系统测试。这个层次的测试是检查完整的、集成的系统是否真正满足了其指定的要求。在这里,你可能也会问自己,为什么在成功的组件和集成测试之后,这个步骤是必要的。原因是:

  • 系统测试的原因

低级别的测试从软件制造商的角度检查技术规范。相反,系统测试是从客户和最终用户的角度来看待系统。系统测试人员检查指定的要求是否已经完全和适当地实现。
许多功能和系统属性来自于系统组件的相互作用,因此只能在整个系统层面进行观察和测试。

  • 测试基础

测试基础包括在系统层面上描述测试对象的所有文件和其他信息。这些可以是系统和软件的要求,规格,风险分析(如果有的话),用户手册,等等。

  • 测试对象和测试环境

一旦集成测试完成,你将面对一个完整的、可以运行的系统。系统测试在尽可能类似于系统生产环境的环境中检查完成的系统。所有的硬件、软件、驱动程序、网络、第三方系统和其他将成为其工作环境一部分的组件都需要安装在系统测试环境中,而不是存根和测试驱动程序。

  • 系统测试需要自己的测试环境

为了节省时间和金钱,系统测试通常在生产环境本身进行,而不是在单独的系统测试环境中进行。这是个坏主意,有各种原因:

系统测试肯定会暴露出故障!这些故障可能会产生高度的负面影响!这些故障会对客户的生产环境产生非常不利的影响。客户现场的崩溃和数据丢失可能是昂贵的,应该不惜一切代价避免。

测试人员对影响客户生产环境的配置和参数的控制有限。如果你在客户系统的其他部分运行时进行测试,这会巧妙地改变你的结果,使你进行的测试极难重现(见3.6.3节)。

  • 测试目标

如前所述,系统测试的目标是验证完成的系统是否满足指定的(功能和非功能)要求以及满足的程度(见3.5.1和3.5.2节)。系统测试可以识别由于错误的、不完整的或不一致的实现需求而造成的缺陷和不足。它还应该识别未记录的或被遗忘的需求。

  • 数据质量

在依赖数据库或其他大量数据的系统中,数据质量是重要因素,可能需要作为系统测试过程的一部分来考虑。数据本身成为 “测试对象”,它们需要适当地检查一致性、完整性和最新性。

在太多的项目中,对需求的澄清和记录要么是零散的,要么是完全忽视的。这使得测试人员很难知道系统实际上是如何工作的,并且加倍难以可靠地揭示故障。

三、验收测试

到目前为止,我们所看到的测试类型都是由软件制造商和/或开发团队在软件交付给客户之前进行的。
在系统启动之前(特别是在定制软件的情况下),它要经过额外的 “验收测试”。这种测试是从客户/终端用户的角度进行的,是客户直接参与或实际负责的唯一测试。

验收测试的典型变体是:

  • 用户验收测试
  • 系统操作者的验收
  • 合同和法规验收测试
  • 现场测试(即α和β测试)
  • 验收测试也可以在较低的层次上进行,通常分布在多个测试层次上:
  • 现成的软件可以在集成或安装时进行验收测试
  • 组件的用户友好性可以作为组件测试过程的一部分进行验收测试
  • 新功能的验收可以在系统测试前使用原型来检查。
  1. 验收测试需要多全面?

验收测试的范围是基于风险的,并且是高度可变的。在定制软件的情况下,风险水平很高,因此全面的验收测试是必不可少的。在光谱的另一端,如果你正在安装现成的软件,只需安装软件包并测试几个典型的使用场景就足够了。但是,如果软件包访问了其他系统的接口,那么这些独立系统之间的交互也必须进行测试。

  1. 测试基础

测试基础包括所有从用户角度描述测试对象的文件–例如,用户和系统要求,用例,业务流程,风险分析,使用系统的流程描述,表格,加上报告和系统维护和管理流程的描述。如果测试是基于法律或其他正式法规,通常被称为法规验收测试。

  1. 合同性验收测试
    在定制软件的情况下,客户将(与制造商合作)进行合同性验收测试。根据测试结果和开发合同规定的准则是否得到满足,客户将决定是否接受交付的产品。该合同也可以是两个公司内部部门之间的(不太正式的)协议,作为联合项目开发产品。

  2. 验收测试标准
    开发合同中详细说明的验收标准将作为测试标准,所以这些标准必须被清楚明确地定义。如果相关的话,任何法律规定、监管标准或安全条例都是验收标准的一部分。
    在实践中,软件制造商通常应该在内部系统测试中使用适当的测试案例检查这些验收标准。然后,验收测试可以通过重复这些系统测试的子集来完成,向客户证明合同要求已经得到满足。
    我们的提示

  3. 客户现场的验收测试
    与在软件制造商的测试环境中进行的系统测试不同,验收测试是在客户自己的验收测试环境中进行。这两种环境之间的差异可能导致无故障的系统测试案例在验收测试中失败。安装和配置程序是验收测试的一部分,通常被称为运行验收测试。验收测试的环境必须尽可能地与系统要使用的生产环境相似。然而,要避免在生产环境中进行验收测试,因为这有可能会破坏关键的生产过程。
    你可以使用你用于系统测试的相同方法来得出合适的验收测试和测试标准。如果你正在测试管理性的IT系统,你还需要测试在一个典型的时间段和/或计费期发生的业务案例(例如,每月的计费周期)。

  4. 用户验收测试
    验收测试的另一种是用户验收。如果客户实际上不是最终用户,这种测试就特别重要。

考虑到所有的用户群
不同的用户群一般会对新系统有不同的期望。如果用户群拒绝该系统–例如,因为他们认为该系统 “不方便”,这可能意味着整个实施被拒绝,即使该系统按照其功能规格运行。因此,针对每个用户群进行验收测试是很重要的。这样的测试通常是由客户组织的,客户可以根据既定的业务流程和用户场景来选择最合适的测试案例。
我们的提示 尽早向终端用户展示样机

如果在验收测试阶段出现了严重的问题,那么除了系统的表面现象外,通常已经来不及改变什么了。为了避免这种灾难,在开发过程中尽早让选定的最终用户评估产品原型是一个好主意。

  • α和β测试

这种测试被称为 "α "或 "β "测试。阿尔法测试是在开发者的测试环境中由角色在开发组织之外的人进行的,而贝塔测试是在客户现场进行的。

现场测试不能取代制造商的内部系统测试(尽管有些制造商认为它应该)。只有在系统测试证明软件足够稳定的情况下,你才应该发布软件进行现场测试。

  • 测试类型

前面几节详细介绍了软件开发过程中需要涵盖的测试层次。这些测试的重点和目标因级别不同而不同,所以不同类型的测试必须以不同的彻底程度进行。我们对以下基本类型进行区分:

功能性和非功能性测试
基于需求和结构的测试

四、回归测试

对程序进行修改后重复测试的过程被称为 “回归测试”。
回归测试利用现有的测试用例来检查所做的修改是否产生了新的故障,是否有无意的副作用。换句话说,其目的是确保修改后的系统中未被改变的部分仍然像修改前那样工作。
最简单的方法是在新版本的程序上执行现有的测试。

  1. 回归测试和测试自动化

为了使现有的测试案例对回归测试有用,它们必须是可重复的。这意味着手动测试用例必须有足够的文件。用于回归测试的测试用例将被定期和经常使用,因此注定要进行测试自动化。回归测试案例的自动化是非常有用的(见第7.2节),因为它确保了精确的可重复性,同时降低了每个测试重复的成本。

  1. 回归测试的范围

哪些现有的测试应该被用来确保成功的回归测试?
因为我们要检查现有的功能是否被(无意中)破坏了,我们基本上需要重新运行所有涵盖这个预先存在的功能的测试。

如果很少(或没有)自动化测试,因此你必须手动执行回归测试,你将不得不选择手动测试中最小的子集。为了选择合适的测试用例,你必须仔细分析测试规范,看看哪些测试用例与哪些原有的功能有关,哪些与新的、修改的功能有关。

如果你有自动化测试用例,最简单的策略是简单地对新产品版本重新执行所有的测试用例:
返回 "通过 "结果的测试用例表明组件/功能没有改变。这可能是因为没有进行所需的改变,或者是因为 "旧 "的测试用例没有足够精确地制定,以涵盖修改后的功能。在这两种情况下,相应的测试用例需要被修改,以确保它们对新功能的反应。

  • 完全回归测试与部分回归测试

在实践中,运行所有现有测试的完整回归测试通常成本太高,花费时间太多,特别是当(如上所述)涉及手动测试时。

因此,我们正在寻找一些标准,以帮助我们决定哪些遗留的测试用例可以被忽略而不损失太多信息。在测试环境下,这需要在最小化成本和接受商业风险之间做出妥协。以下是选择测试用例的常见策略:
只重复在测试计划中被赋予高优先级的测试。
撇开功能测试的特殊情况。

将测试限制在某些特定的配置上(例如,只测试英语版本,只测试特定的操作系统,以及类似的)。
将测试限制在特定的组件或测试级别。

这里列出的规则主要适用于系统测试。在较低的测试级别,回归测试的标准可以基于设计文档(如类的层次结构)或白盒信息。

总结

软件开发生命周期模型以章节、阶段或迭代的方式构造软件开发过程。两种基本的模型类型是 "顺序的 "和 “迭代/递增的”。

顺序开发模式的特点是开发活动以线性(即顺序)方式进行。

迭代/增量模式产生定期的扩展和/或改进的产品发布,使客户和系统的用户能够及时反馈。这种方法缩短了产品上市的时间,也降低了开发出的产品不能满足客户期望的风险。所有的敏捷开发方法都被归类为迭代/递增式的。

V模型是一个重要的顺序开发模型,它定义了组件、集成、系统和验收测试级别。它区分了验证和确认,并提供了良好的测试实践原则,可以应用于任何开发模式:

越早发现缺陷,纠正它的成本就越低。因此,V型模型要求在每个开发阶段结束时进行验证程序(如审查)。这有助于防止后续缺陷的扩散。

组件测试检查单一的软件组件。集成测试检查这些组件的协作情况。功能和非功能的系统测试从用户的角度检查整个系统。在验收测试中,客户检查产品在合同方面的验收情况,以及用户和操作人员的验收情况。如果系统要安装在多个环境中,现场测试提供了一个额外的机会,通过运行产品的预发布版本来获得系统的经验。

在产品的整个生命周期中,维护和增量开发不断创造出新的软件产品版本。每个新版本都要进行测试,这种回归测试的范围取决于相应的风险分析的结果。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐