集成测试

楔子

现在,有一个Django项目到了提测阶段,要对项目的登录集成测试。

urls.py

from django.conf.urls import url, include
from django.contrib import admin
from web import views
urlpatterns = [
    url(r'^login/', views.login, name='login'),
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from django.http import JsonResponse

def login(request):
    """ 登录 """
    if request.method == "POST":
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'zhangkai' and pwd == '666':  # 就当是数据库验证
            return JsonResponse({"login_status": True})
        else:
            return JsonResponse({"login_status": False})
    else:
        return render(request, 'login.html')

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>

<form action="" method="post">
    <input type="text" name="user" placeholder="username">
    <input type="password" name="pwd" placeholder="password">
    <input type="submit" value="走你">
</form>
</body>
</html>

为了方便,先将settins.py中的django.middleware.csrf.CsrfViewMiddleware中间件注释掉。

那么现在借助一个测试工具postman来进行测试。

上述结果,跟我们在浏览器输入结果是是一样的。

而整个测试流程看起来应该是这样的:

把整个server端的程序当成集成测试对象进行测试,看是否与预期结果一致。

那么通过这个示例简单的对集成测试有了基本了解,再来看集成测试都有哪些细节需要掌握。

什么是集成测试

  • 集成测试是在单元测试的基础上,将所有函数按照概要设计要求组装成为子系统或系统所进行的测试。
  • 集成测试也叫组装测试或者联合测试、子系统测试或部件测试。
  • 集成测试和单元测试所关注的范围是不同的,因此,它们在发现问题的集合上包含有不相交的区域,不能使用集成测试来替代单元测试,反之也是一样的。

那集成到底是集成什么东西呀?就是集成项目中的部分代码。比如说部分代码可能是函数,也就是部分函数集成,或者是集成不同的模块,再或是不同的子系统,就是把这些部件集合起来做测试。

那要测试什么呢?这就涉及到了集成测试的重点。

集成测试的重点

集成测试的重点包括两部分:

  • 单元间的接口,指的是代码间的相互调用,我们传递一些参数来判断测试调用有没有问题。
  • 集成后的功能,不同的功能之间是否会产生相互影响?还是那句话,集成测试关注的是部分代码的逻辑有没有问题,相互调用有没有问题。

集成测试的层次

从最底层的单元测试到最终的产品,其中所有各层测试都要通过集成测试来完成,一般呢,可以把集成测试划分为三个级别:

  • 模块内的集成测试,可以理解为不同的函数间的集成。
  • 子系统内的集成测试,可以理解为不同的模块间的集成。
  • 子系统间的集成测试,可以理解为不同的子系统之间的集成。

层次受软件的架构、开发的过程影响。

由于不同的层次出现之后,在不同的层次关系、相互调用关系,都会影响我们在做集成测试时采用的测试策略。

集成测试的策略

在做集成测试时,一般可以采用下面这些策略来针对不同的测试环境:

  • 大爆炸集成。
  • 自顶向下集成。
  • 自下向上集成。
  • 三明治集成。
  • 基干集成。
  • 分层集成。
  • 基于功能的集成。
  • 基于消息的集成。
  • 基于进度的集成。
  • 基于风险的集成。

将重点关注加粗部分的策略,后几种策略主要了解它的测试思路。

大爆炸集成策略

在大爆炸集成方式中,首先对每个模块分别进行单元测试,然后再把所有单元组装在一起进行测试,最终得到符合预期的软件系统。

上图,首先对模块的A、B、C、D、E、F、单独做单元测试,也可以看到在单独做单元测试的时候,可能需要搭配相应的桩(Stub)和驱动(Driver)。完事之后,把这些单元组装到一起进行测试。

优点

大爆炸集成可以迅速(如果执行没有问题的话)完成集成测试,并且只要极少数的驱动和桩模块设计,它需要的测试用例也是最少的。

缺点

这种一次性组装方式试图在辅助模块的协助下,在模块单元测试的基础上,将所测模块连接起来进行测试。但是由于程序中不可避免地存在模块间接口、数据结构等其他方面的问题,所以一次试运行成功率不大,导致测试效率比较低,

其次,在发现错误的时候,其问题定位和修改都比较困难。即使被测系统能够被一次性集成,但是,还是会有许多接口错误很容易的躲过集成测试而进入到系统测试范围内。

那大爆炸这这种集成方式适用于哪些项目呢?

大爆炸集成方式的适用范围

  • 一个维护型项目(或功能增强型项目),其以前的产品已经很稳定了,并且新增的项目只有少数几个组件被增加或者修改。
  • 被测系统比较小,并且它的每个函数都经过充分的单元测试,也就是充分的挖掘了其中那些隐患。

自顶向下集成策略

自顶向下的集成测试策略采用了和设计一样的顺序对系统进行测试,它在第一时间内对系统的控制接口进行了验证。

该策略首先集中测试顶层的组件,然后逐步测试处于底层的组件。该策略可以有深度优先策略和广度优先两种策略可以选择。

深度优先策略

可以看到,自定向下中的深度优先,首先实现一个驱动d1测试A,然后逐步的向下加入B,然后加入E、加入C、加入D、最后加入F,并在每个环节搭配桩,然后逐步的完成整个组件正确性。

广度优先策略

广度优先策略在总体上套路不变,只是由深度优先换为广度优先了。如果你观察上面两幅图绿色的线路清晰区分了深度优先和广度优先它的测试流程。

优点

该策略在测试过程中较早的验证了主要的控制和判断点。如果选用按照深度优先方式,可以首先实现和验证一个完整的软件功能。也就是从从头到尾顺序把这一连串的所有模块都测试完。

功能的可行性得到较早的验证,还能够给开发者和用户带来成功的信息。

最多只需要一个驱动,减少了驱动器开发的费用。

支持故障隔离。

缺点

桩的开发和维护时本策略的最大成本,另外,底层组件行为的验证被推迟了;随着底层组件的不断增加,整个系统越发复杂,导致底层组件的测试不够充分,尤其是那些被重用的组件。

自顶向下集成测试方式的适用范围

适合产品控制结构相对清晰和稳定,产品的高层接口变化比较小,产品的底层接口未定义或者经常可能被修改,产品的控制组件具有较大的技术风险,需要尽早的被验证。

自底向上集成策略

该策略是从程序结构的最底层的组件开始组装和测试的。

组件自底向上进行组装,对于一个给定层次的组件,它的子组件(包括该子组件的所有下属组件)已经组装并测试完成,所以不再需要桩。

如上图,由A、B、C、D、E、F5个组件进行集成,我们按照自底向上的集成方式进行集成测试。首先将B、E做了集成,同时将D、F做了集成,那么红线标注的部分是可以同时进行的(也可以不同时),完事之后,将顶部的A、C加进来再集成到一起。

当然,在需要的时候,仍然需要一些桩和驱动的插入。

优点

该策略允许对底层组件行为的早期验证,可以在任何一个叶子节点已经就绪的情况下进行集成测试。

在集成测试开始阶段可能会并行(如上图的BCDF)的进行集成,在这一点上比使用自顶向下的策略效率高。另外,它减少了桩的工作量,毕竟在集成测试中,桩的工作量远比驱动的工作量大。但为了模拟一些中断或者异常,可能还需要设计一定的桩。

最后,它也支持故障隔离。

缺点

驱动的开发工作量也很庞大。对于高层的验证被推迟到了最后,设计上的错误不能被及时发现,尤其是对于那些控制结构在整个体系中非常关键的产品。

自底向上集成测试方式的适用范围

底层接口比较稳定、变动较少的产品。

高层接口变化比较频繁的产品。

底层组件较早被完成的产品。

那么,能否将自底向上和自顶向下这两种策略综合一下呢?可以的,那就是接下来要说的三明治集成测试方式。

三明治集成策略

三明治集成策略将系统划分为三层,中间一层为目标层,在测试的时候,对目标层的上一层使用自顶向下的集成策略;对目标的下一层使用自底向上的集成策略,最后测试在目标层会合。

优点

集合了自底向上和自顶向下这两种策略的优点。

缺点

中间层在被集成前测试不够充分。

适用范围

大部分软件开发项目都可使用该策略。

最后,上层更多的是偏重于高层的组件开发,我们可以采用自顶向下的策略集成;而下层偏重于具体的组件实现,我们采用自底向上的策略来集成;中间部分可能就是一些接口实现了,完事上下层在中间层会合;完事之后,我们可以在它们的最外成采用大爆炸方式集成也是可以的。

其他集成策略

基干策略

在很多系统中,尤其是在嵌入式系统中,一般可以分为两个部分:内核(基干)部分和外围部分。这两部分经常会被不同的项目组开发,它具有如下特点:

  • 内核部分提供了系统最基本的功能和服务。
  • 外围部分以内核为基础,不能脱离内核而独自使用。
  • 内核具有很高的耦合性(组件之间的相互调用比较复杂),那么在试图设置桩的时候将非常困难,导致成本问题。
  • 外围部分可以分为应用子系统和控制系统,应用子系统内耦合性不大,而控制子系统内具有较高的耦合性。

内核部分可以理解为操作系统,外围部分可以理解为应用软件。

基干集成的步骤:

  • 识别外围的应用子系统部分、控制子系统部分、基干部分;
  • 这对基干中所有的组件(毕竟耦合性很高),我们可以采用大爆炸集成,形成基干子系统,并使用一个驱动检查经过大爆炸的基干。
  • 对控制子系统进行自顶向下的集成。
  • 对各应用子系统进行自底向上的集成。
  • 对于基干子系统,控制子系统和各应用子系统进行大爆炸形成整个系统。

基干继承的优点:具有三明治集成的优点,更适合于大型复杂的项目集成。

而缺点呢,必须对系统的结构和相互依存性进行仔细地分析;必须开发驱动和桩,并且由于被测系统的复杂性导致驱动和桩开发工作量的加大;由于采用了大爆炸策略,因此会导致有些接口测试不够充分。

分层集成策略

通过增量式集成的方法验证一个具有层次体系结构的应用系统的稳定性和可互操作性;一般通过功能把系统划分成不同功能层次的子系统,子系统内部具有较高的耦合性,子系统间的关系具有线性层次关系;适用于有明显层次关系的系统。

分层集成的步骤:

  • 划分系统的层次。
  • 确定每个层次内部的集成策略,该策略可以使用大爆炸集成,自顶向下集成,自底向上集成和三明治集成中的任意一种策略。
  • 确定层次间的集成策略,该策略可以使用大爆炸集成,自顶向下集成,自底向上集成和三明治集成中的任意一种策略。

常见的协议就非常的具有明显分层概念,比如OSI7层。

基于功能的集成策略

该策略是从功能角度出发,按照功能的关键程度对组件的集成顺序进行组织,目的是尽早的验证系统关键功能。

基于功能集成的步骤:

  • 确定功能的优先级。
  • 分析优先级最高的功能路径,把该路径上的所有组件都集成到一起,必要时使用驱动和桩。
  • 分析下一个关键功能,继续上一步骤,直到针对所有功能都进行了集成。

优点是:采用该方法,可以尽快的看到关键功能的实现,并验证关键功能的正确性;由于该方法在验证某个功能的时候,可能会同时加入多个组件,因此在进度上比自底向上,自顶向下或三明治集成要短;可以减少驱动的开发,原因与自顶向下的集成策略类似。

缺点是对有些接口的测试不充分,会忽略部分接口错误,可能会产生比较大的冗余测试。

基于消息的集成策略

许多系统其工作原理是基于状态变迁,内部组件间的接口主要是通过消息来完成的,因此验证消息路径的正确性对于这类系统是比较重要的,基于消息的集成就是针对这一特点而设计的一种策略。

PS:消息就是结构体(struct)

一般用于通信类的软件。

基于消息集成的步骤:

  • 从系统的外部看,分析系统可能输入的消息集。
  • 选取一条消息,分析其穿越的组件。
  • 集成这些组件进行消息接口测试。
  • 选取下一条消息,重复前两个步骤,直到针对所有消息都进行了集成。

优点是,采用这种策略可以尽快的看到关键消息的处理实现,并验证关键消息处理的正确性;由于该方法在验证某个消息处理的时候,可能会同时加入多个组件,因此在进度上比自底向上,自顶向下或三明治集成要短;可以减少驱动的开发,原因与自顶向下的集成策略类似。

缺点是对有些接口的测试不充分,会忽略部分接口错误,可能会产生比较大的冗余测试。

基于进度的继承策略

进度压力是每个软件开发项目都会遇到的问题,基于进度的集成就是在兼顾进度和质量两者之间寻找一个均衡点;该集成一个最基本的策略就是把最早可获得的代码拿来立即进行集成,必要的时候开发桩和驱动,在最大程度上保持与开发并行,从而缩短项目集成时间。

优点是具有较高的并行度;能够有效缩短项目开发集成的时间。

缺点是可能最早拿到的组件之间缺乏整体性,只能进行独立的集成,大致有些接口必须等到后期才能验证,但此时的系统很可能已经非常复杂了,往往无法发现有效的接口问题;桩和驱动的工作量变得很大;由于进度的原因,组件可能不稳定,导致测试的重复和浪费。

它的适用范围是进度优先级高于质量的项目。

基于风险的集成策略

基于风险的集成是基于这样的一个假设,即系统风险最高的组件间的接口往往是错误集中的地方,因此尽早的验证这些接口有助于加速系统的稳定,从而增加对系统的信心。

风险就是容易出错,然后出了错影响很大。

优点是最具有风险的组件最早进行验证,有助于系统的快速稳定。

缺点是需要对各组件的风险有一个清晰的分析。


 

posted @ 2019-11-29 11:41  天之坚毅  阅读(737)  评论(0编辑  收藏  举报