测试理论

欢迎使用Markdown编辑器写博客

一、基本概念
定义:软件测试是为了发现错误而执行程序的过程,“寻找错误”是测试的目的
使用人工或自动手段运行或测定某个系统的过程,其目的在于检验它是否满足规定的需求或是否弄清预期结果与实际结果之间的差别
软件测试是一种重要的软件质量保证活动,测试过程中的活动包括分析软件和运行软件,是在软件投入运行前,对软件需求分析、设计规格说明和编码的最终复审,是软件质量保证的关键步骤。

测试:找错误(证明程序有错)
调试:该错误(使程序正确)

软件测试的目的:
(1)测试是程序执行的过程,目的在于发现错误
(2)一个好的测试用例在于能发现至今未发现的错误
(3)一个成功的测试是发现至今未发现的错误的测试
(测试的成功与失败在于能否发现错误,测试不能表能软件中不存在错误,只能说明软件中存在错误)

    通过对软件错误的原因和分布进行归纳,来发现并排除当前软件产品的缺陷,对在需求和设计过程中存在的问题查缺补漏,从而确保软件产品的质量;

软件测试的原则:
(1)所有的测试都应追索到用户的需求:系统中最严重的错误是导致程序无法满足用户需求的错误;
(2)尽早的和不断的进行软件测试:需求和设计时初心的缺陷占很大的比例;缺陷的修改成本随着阶段的推移而急剧上升;缺陷具有放大的特点

     (3)不可能完全的测试
     (4)80-20原则:测试发现的错误80%很可能起源于20%的模块中,应孤立这些疑点模块重点测试。
     (5)注意测试中的群集现象:在所测程序段中,若发现错误数目多,则残存数目也比较多
     (6)避免测试自己的程序
     (7)设计周密的测试用例
              软件测试的本质就是针对要测试的内容确定一组测试用例
              测试用例至少包括:
              执行测试用例前:应满足的前提条件
              输入
              预期输出
              设计测试用例时应包括合理的输入条件和不合理的输入条件
     (8)回归测试:程序修改错误后必须进行回归测试,避免引入新的错误
     (9)严格执行测试计划:排除测试的随意性

软件测试的对象:
(1)软件测试贯穿于定义与开发的整个期间
(2)软件测试的对象
需求规格说明
概要设计规格说明
详细设计规格说明
源程序
软件测试分类

是否执行被测试软件:

静态测试:不运行被测程序本身,而是通过在对软件进行分析、检查和审阅达到测试目的

  方法:代码审查;代码走查;桌面检查;技术评审

动态测试:值通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能。由三部分组成:编写测试用例、执行测试结果、分析程序的输出结果。

黑盒测试:功能测试/数据驱动测试,是在已知产品所应对应具有的功能的前提下,通过测试来检测每个功能是否都能正常使用。

白盒测试:结构测试/逻辑驱动测试,是在知道产品内部工作过程的前提下,可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行。

按照软件测试的策略和过程分(都是动态测试):

单元测试:单元测试的对象软件设计的最小单位——模块。单元测试的依据是详细设计描述,单元测试应对模块内所有重要的控制路径设计测试用例,以便发现模块内部的错误。单元测试多采用白盒测试技术,系统内多个模块可以并行的进行。

集成测试:组装软件的系统测试技术,按设计要求把通过单元测试的各个模块组装在一起之后,进行集成测试以便发现与接口有关的各种错误。

系统测试:是在真实或模拟系统运行的环境下,为验证和确认系统是否达到需求规格说明书规定的需求而对集成的硬件和软件系统进行的测试

验收测试:按照项目任务书或合同、供需双方约定的验收依据文档进行的整个系统的评测,决定是否接受或拒绝系统

按测试内容分:

功能测试:根据功能需求进行测试,以确定软件与软件功能需求的一致,功能遗缺和多余

性能测试:评价一个产品或组件与性能需求是否符合的测试

一、性能测试类型

  性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。负载测试和压力测试都属于性能测试,两者可以结合进行。通过负载测试,确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接受的性能点,来获得系统能提供的最大服务级别的测试。

  2.负载测试(Load Testing)

  在给定的测试环境下,通过在被测系统上不断增加压力,直到性能指标超过预定指标或某种资源使用已经达到饱和状态,目的是了解系统性能容量和处理能力极限。负载测试的主要用途是发现系统性能的拐点,寻找系统能够支持的最大用户、业务等处理能力的约束。
  负载测试是在固定测试环境,在其它测试角度(负载方面)不变的情况下,变化一个测试角度并持续增加压力,查看系统的性能曲线和处理极限,以及是否有性能瓶颈存在(拐点)。主要意义是从多个不同的测试角度去探测分析系统的性能变化情况,配合性能调优。测试角度可以是并发用户数、业务量、数据量等不同方面的负载。

  3.压力测试(Stress Testing)

  测试系统在一定饱和状态下系统能够处理的会话能力,以及是否出现错误,一般用于稳定性测试。

  可以理解为资源的极限测试。测试关注在资源处于饱和或超负荷的情况下,系统能否正常运行,是一种在极端压力下的稳定性测试。其主要意义是通过测试、调优保证系统即使在用户的极端压力下也不会出错甚至系统崩溃。

  压力测试的目的是调查系统在其资源超负荷的情况下的表现,尤其是对系统的处理时间有什么影响。这类测试在一种需要在反常数量、频率或资源的方式下执行系统。目标是通过极限测试方法,发现系统在极限或恶劣环境中自我保护能力。主要验证系统的可靠性。

  4.配置测试(Configuration Testing)

  通过对被测系统的软硬件环境的调整,了解各种不同环境对性能影响的程度,从而找到系统各项资源的最有分配原则。

  主要用于性能调优,在经过测试获得了基准测试数据后,进行环境调整(包括硬件配置、网络、操作系统、应用服务器、数据库等),再将测试结果与基准数据进行对比,判断调整是否达到最佳状态。

  5.并发测试(Concurrency Testing)

  模拟并发访问,测试多用户并发访问同一个应用、模块、数据时是否产生隐藏的并发问题,如内存泄漏、线程锁、资源争用问题。

  6.可靠性测试(Reliability Testing)

  通过给系统加载一定的业务压力的情况下,让应用持续运行一段时间,测试系统在这种条件下是否能够稳定运行。

  需要和压力测试区分开,两者的测试环境和测试目的不一样。压力测试强调在资源极限情况下系统是否出错,可靠性测试强调在 一定的业务压力下长时间(如24×7)运行系统,关注系统的运行情况(如资源使用率是否逐渐增加、响应时间是否越来越慢),是否有不稳定征兆。

eg:

负载测试:测试一个应用在重负荷下的表现,例如测试一个web站点在大量负荷下,何时系统的响应会退化或失败

压力测试:用来评估在超越最大负载的情况下系统将应如何进行

              压力测试的目标就是发现在高负荷条件下应用程序的缺陷

疲劳测试:采用系统稳定运行情况下能够支持的最大并发用户数,持续一段时间业务,通过综合分析交易执行指标和资源监控指标来确定系统处理最大量强度性能的过程

兼容测试:测试软件在一个特定的硬件/软件/操作系统/网络等环境下性能如何

安全性测试:针对程序中危险防止和危险处理设施进行的测试,以验证其是否有效

安装性测试

可用性测试:对“用户友好性”的测试

                主观的:取决于目标最终用户和可和

                用户面谈、调查、用户对话的路线和其他一些技术

                程序员和测试员通常都不宜做可用性测试员

注:功能的重点在于能做什么;性能在于做的如何

缺陷:最终产品和用户的期望不一致

       功能错误

       功能遗漏

       超出需求的部分

       性能不符合要求

二、测试模型与过程

   1-1 软件生命周期

   a.大棒开发法

   b.边改边写法

          优点:能够较为迅速的展现结果,适合需要快速制作并且用完就扔的小项目,如示范程序、演示程序等。

          缺点:其编码和测试可能是将长期的循环往复的过程



   c.  瀑布法:将软件生命周期的各项活动,规定为按照固定顺序相连的若干个阶段性工作,形如瀑布流水,最终得到软件产品

   优点:易于理解;调研开发的阶段性;强调早期计划及需求调查;确定何时能交付产品及何时进行评审与测试;

   缺点:需求调查分析只进行一次,不能适应需求变化;顺序的开发流程,使得开发中的经验教训不能反馈到该项目的开发中去;不能反映出软件开发过程的反复与迭代性;没有包含类型的风险评估;开发中出现的问题直到开发后期才暴露(测试在后期阶段),因此失去及早纠正的机会。



   d. 快速原型法

   根据客户需求在较短的时间内解决用户最迫切解决的问题,完成可演示的产品。这个产品只实现最重要的功能,在得到客户更加明确的需求之后,原型将丢弃



   e. 螺旋瀑布法

   将瀑布模型和快速原型模型结合起来,强调了其他模型所忽视的风险分析,特别适合于大型复杂的系统。 螺旋模型沿着螺线进行若干次迭代,图中的四个象限代表了以下活动:

          (1) 制定计划:确定软件目标,选定实施方案,弄清项目开发的限制条件

          (2) 风险分析:分析评估所选方案,考虑如何识别和消除风险;

          (3) 实施工程:实施软件开发和验证;

          (4) 客户评估:评价开发工作,提出修正建议,制定下一步计划。

  螺旋模型由风险驱动,强调可选方案和约束条件从而支持软件的重用,有助于将软件质量作为特殊目标融入产品开发之中。但是,螺旋模型也有一定的限制条件,具体如下:
  (1) 螺旋模型强调风险分析,但要求许多客户接受和相信这种分析,并做出相关反应是不容易的,因此,这种模型往往适应于内部的大规模软件开发。
  (2) 如果执行风险分析将大大影响项目的利润,那么进行风险分析毫无意义,因此,螺旋模型只适合于大规模软件项目。
  (3) 软件开发人员应该擅长寻找可能的风险,准确地分析风险,否则将会带来更大的风险
  一个阶段首先是确定该阶段的目标,完成这些目标的选择方案及其约束条件,然后从风险角度分析方案的开发策略,努力排除各种潜在的风险,有时需要通过建造原型来完成。如果某些风险不能排除,该方案立即终止,否则启动下一个开发步骤。最后,评价该阶段的结果,并设计下一个阶段。
优点:严格的全过程风险管理;强调个开发阶段的质量;提供机会评估项目是否有价值继续下去。

2.软件测试模型

   V模型的过程从左到右,描述了基本的开发过程和测试行为。V模型的价值在于它非常明确地标明了测试过程中存在的不同级别,并且清楚地描述了这些测试阶段和开发过程期间各阶段的对应关系;

   局限性:把测试作为最后一个活动,需求分析前期产生的错误直到后期的验收测试才能发现。

   该模型容易使人理解主要是针对程序进行测试寻找错误

   实际中,由于需求变更较大,导致要重复变更需求、设计、编码、测试。返工量大。主要用在快速程序的开发





   在V模型中增加软件开发各开发阶段应同步进行的测试,演化为W模型

   开发的是V,测试是与此并行的V;相对于V模型,W模型更科学,强调的是测试伴随整个软件开发周期,并且测试的对象不仅仅是程序,需求、功能、和设计同样要测试。测试和开发是同步进行的,有利于尽早的发现问题

   缺点:W和V都把软件的开发视为需求、设计、编码等一系列串行的活动,无法支撑迭代、自发性以及变更挑战

              主要应用在一些中型软件并且业务逻辑关联非常紧密的项目中



   H模型中,软件测试活动完全独立,贯穿于整个产品的周期,与其他流程并发的进行,某个测试点准备就绪时,就可以从测试准备阶段进行到测试执行阶段。软件测试可以尽早的进行,并且可以根据被测物的不同而分层次进行。

   软件测试是一个独立的流程,贯穿产品整个生命周期,与其他流程并发进行

   H模型指出软件测试要尽早准备,尽早执行,不同的测试活动可以是按照某次序先后进行,但也可能是反复的,只要某个测试达到准备就绪点,测试执行活动就可以开展。



   很好的处理测试与开发的交接过程,交接的过程是一个时间段,而不是一个点。

   左边描述的是针对单独程序片段所进行的相互分离的编码和测试,伺此后将进行频繁的交接,通过集成最终合成为可执行的程序,然后再对这些可执行的程序进行测试。

   已通过集成测试的产品可以进行封装并提交给用户,也可以作为更大规模和范围内集成的部分,多根并行的曲线表示变更可以在各个部分发生

   X模型还定位了探索性测试,这是不进行实现计划的特殊测试,给有经验的测试人员在测试计划外发现更多软件缺陷

三、 黑盒测试常用方法

  1. 边界值测试:

    1-1 边界

           a. 数值边界值:数值范围
    
          b. 字符边界值 :ASCII表
    
           c. 其他边界条件:默认值、空白、空值、零值、无输入等情况
    

    1-2 基本思想

           使用输入变量的最小值、略大于最小值、正常值、略小于最大值和最大值来设计测试用例(min,min+,nom,max-,maz)
    
          单缺陷假设:只让一个变量取边界值,其余变量取正常值
    
          多缺陷假设:同时让多个变量取边界值
    
          (1)边界值分析(单缺陷)(4N+1)
    
    
    
          (2)健壮性边界值分析(在异常情况下,软件还具有正常运行的能力)(增加一个取异常值,其他都正常值的测试用例,6N+1)
    
    
    
          (3)最坏情况测试(多个变量出现极值,最最小值,略大于最小值,正常值,最大值,略小于最大值做笛卡尔乘积,5N)
    
    
    
       (3)健壮性最坏情况测试(7N)
    
  2. 等价类测试

    2-1 等价类划分

         划分是指互不相交的一组子集,这些子集的并是整个集合
    

    2-2 有效等价类

          是指对于程序的规格说明来说是合理的、有意义的输入数据构成的集合。利用有效等价类可以验证程序是否实现了规格说明中的功能和性能。
    

    2-3 无效等价类

          对程序的规格说明来说是不合理的或无意义的输入数据所构成的集合。为了验证程序做其不应做的事情。
    

    2-4 等价类划分方法

         (1)按照区间划分。在输入条件规定了取值范围或值得个数的情况下,则可以确立一个有效等价类和两个无效等价类。
    
    
    
          (2)按照数值划分。在规定了输入数据的一组值(假定n),并且程序要对每一个输入值分别处理的该情况下,可确立n个有效等价类和一个无效等价类。
    
         (3)按照数值集合划分。在输入条件规定了输入值的集合或者规定了“必须如何”的情况下,可确立一个有效等价类和一个无效等价类。
    
          (4)在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类。
    
          (5)进一步细分等价类。在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步地划分为更小的等价类。
    
          (6)等价类划分还应特别默认值、空值、NULL、零值的情况。
    

    2-5 等价类的特点

          (1)完备性(全集)(2)无冗余性(互不相交的子集) (3)等价性
    

    2-6 等价类测试类型

          单/多缺陷:弱/强等价类
    
         是/否考虑无效等价类:健壮性/一般等价类测试
    
         eg  a≤x1≤d,区间为 [a,b) [b,c) [c,d];e≤x2≤g ,区间为 [e,f)  [f,g]
    
          (1)弱一般等价类测试:单缺陷,要求选取的测试用例覆盖所有的有效等价类
    

(2)弱一般等价类测试:多缺陷,要求将每个变量的有效等价类做笛卡尔积,设计测试用例覆盖笛卡尔积的每个元素。

(2)弱健壮性等价类测试:弱指基于单缺陷假设,健壮性指考虑了无效值。对有效输入,使用每个有效等价类的一个值;对无效输入,测试用例将拥有一个无效值。补充输入域边界以外的值(略小于最小值min-1,略大于与最大值max+1)

(3)基于多缺陷假设,并考虑无效输入

3 基于判定表的测试

3-1 判定表

(1)条件桩:列出了问题的所有条件。

(2)动作桩:列出了问题规定可能采取的操作。(1、2的排列顺序通常没有约束)

(3)条件项:列出针对它的左列条件的取值

(4)动作项:列出在条件项的各种取值情况下应该采取的动作

4.其他测试方法

4-1 因果图方法:从用自然羽然书写的程序规格说明的描述中找出因(输入条件)和果(输入或程序状态的改变)之间的关系绘制出因果图,然后通过因果图转换为判定表。

4-2 正交实验设计法:使用已经造好的正交表来安排适应并进行数据分析的一种方法,目的使用最小的测试用例达到最高的测试覆盖率。

4-3 错误推测设计方法:基于经验和直觉推测程序中所有可能存在的各种错误,从而有针对性的设计测试用例

四、 白盒测试常用方法

1.逻辑覆盖测试:根据被测试程序的逻辑结构设计测试用例。

  1. 语句覆盖:测试时设计若干测试用例,运行被测试程序,使程序中的每条可执行语句至少执行一次。

优点:检查所有语句;结构简单的代码测试效果好;容易实现自动测试;代码覆盖率高;如果是程序块覆盖,则不涉及程序块中的源代码。

缺点:不能检查出条件语句错误、循环语句错误;语句率覆盖率看似很高,却有严重缺陷(分支覆盖率)

  1. 判定覆盖/分支覆盖:设计若干测试用例,运行被测试程序,使得程序中每个判断的取真分支和取假分支至少经历一次,即判断的真假值均曾被满足。(while/switch/异常处理/跳转语句)

判定覆盖率:已取过“真”和“假”两个值的判定程序占程序中所有条件判定个数的百分比

优点:分支覆盖比语句覆盖查错能力强一些:执行了分支覆盖,实际也就执行了语句覆盖

缺点:不能查出条件语句错误/逻辑运算错误/循环次数错误/循环条件错误

  1. 条件覆盖:设计若干测试用例,执行被测程序后,要使每个判断中每个条件的可能取值至少满足一次,即每个条件至少有一次为真值,有一次为假值

优点:能够检查所有的条件错误;

缺点:不能实现对每个分支的检查,用例数量的增加

做到了完全的条件覆盖,并不能保证达到完全的判定覆盖。

做到了完全的判定覆盖也并不能保证达到了完全的条件覆盖==》条件和分支兼顾

  1. 判定-条件覆盖:将判定覆盖和条件覆盖结合起来,即设计足够的测试用例,使得判断条件中的每个条件的所有可能取值至少执行一次,并且每个判断本身的可能判定结果也至少执行一次。

优点:既考虑了每一个条件,又考虑了每一个分支,发现错误能力强于分支覆盖和条件覆盖。

缺点:并不能全面覆盖所有路径;用例数量增加

  1. 条件组合覆盖:设计足够的测试用例,运行被测程序,使得所有可能的条件取值组合至少执行一次

优点:满足了判定覆盖、条件覆盖和条件-判定覆盖

缺点:不能全面覆盖所有路径

  1. 路径覆盖:设计足够多的测试用例来覆盖程序中所有可能的路径(不可能:循环、、、、)

8.路径测试

  1. 基路径测试:把覆盖的路径数压缩到一定限度内,例如程序中的循环体只执行0次和1次

1-1 程序环路复杂性

a. 设E为控制流图的边数,N为图的节点数,则定义环路复杂性为V(G)=E-N+2

b. 设P为控制流图中的判定节点数,则由V(G)=P+1

c. 将环路复杂性定义为控制流图中的区域数(控制流图外面也要算一个区域)

2-1 独立路径:包括一组以前没有处理的语句或条件的一条路径

3-1 基本路径集:控制流图中所有独立路径的集合(路径数=环路复杂性)

4-1 基路径测试法:通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例。设计出的测试用例要保证在测试中的每个可执行语句至少执行一次(路径数=环路复杂性)。

缺点:测试覆盖并不充分(循环)

  1. 循环测试:针对循环的测试

3.数据流测试:基于程序的控制流,从建立的数据目标状态的序列中发现异常的结构测试方法,数据的定义/引用缺陷。

三、 单元测试

    单元:一个可独立运行的代码段

    独立运行:这个工作不受前一次或接下来的程序运行的结果影响,即不与上下文发送关系。

    单元测试方法:静态/动态

    静态测试:不需要运行单元代码,而是对代码进行逐行的检测

    动态测试:需要运行被测单元代码,由于被测单元需要调用其他单元,或者会被其他单元调用。

3-1 单元测试的环境

     静态测试:无需搭建测试环境

     动态单元测试:用一些辅助模块来模拟与所测模块相联系的其他模块,需要在测试之前搭建相应测试环境



      辅助模块分两种:

     (1)驱动模块(Driver):相当于所测模块的主程序

     (2)桩模块(stub):用于代替所测模块调用的子模块

      单元测试三个步骤:模拟输入->执行单元->检查验证输出

3-2 单元测试的策略和方法

     1、静态代码分析

           代码走读:一种交叉检查,就是自己的代码由他人来检查

           代码审查:以会议的形式展开,由大家根据缺陷检查表共同审核代码的质量

           代码评审:通常在审查会后进行,审查小组根据记录和报告进行评估

      2、单元结构测试(主要采用白盒测试)

            关注代码内部的执行情况,关注代码执行的覆盖率。

            基于路径的测试、基于数据流测试。

      3、单元功能测试(基本方法时黑盒测试)

            常用测试方法:边界测试、等价类测试、因果图测试

四、集成测试

 4-1. 基本概念

        集成:把多个单元组合起来形成更大的单元

        集成测试:在假定各个软件单元已经通过单元测试的前提下,检查各个软件单元之间的相互接口是否正确,也叫组装测试或联合测试

                         具体检测包括:功能性验证、接口测试、全局数据结构的测试以及计算精度检测等在集成测试时可能出现的错误

 4-2. 方法策略

非增量型集成测试:将所有软件统一集成后才进行整体测试(大棒集成)

增量型集成测试:从一个模块开始,测一次添加一个模块,边组装边测试,以发泄与结构相联系的问题(需要驱动程序或桩程序)

 4-3.基于功能分解的集成

       (1) 自顶向下集成:从最具控制力的主控模块开始,按照软件的控制层次结构,以深度优先或广度优先的策略,向系统中增加模块,直至实现整个系统, 需要设计桩模块

      优点:有助于最大限度减少对驱动程序的需求

      缺点:不能很好地支持有限功能的早期发布

      桩       模块不能反映真实情况,重要数据不能及时会送到上层模块,则测试可能并不充分

       (2)自底向上继承:从程序模块结构中最底层的模块开始组装,按控制层次增强的顺序向系统中增加模块并测试,直至实现整个系统,不需要再编制桩模块

   优点:减少了对桩模块的需求

              自底向上增值的方式可以实施多个模块的并行测试,提高测试效率,且管理方便,测试人员能较好地锁定软件故障所在位置。

   缺点:对驱动程序的需求使得测试管理变得复杂起来。高级别的逻辑和数据流在晚期测试,只有程序最后一个模块加入时才具有整体形象。

             不能很好地支持有限功能的早期发布。

       (3) 三明治集成:1和2的结合

 4-4.基于调用图的集成:以功能分解树为基础

七、案例

5-1 如何测试一个杯子

   5-2 测试web登录界面

   5-3 自动贩售机

   5-4 CP命令设计测试用例

       主要从异常、功能、性能三方面考虑

       (1)异常

                参数异常:源和目标参数异常;包含特殊字符;参数超长;指定的位置实际不存在

                拷贝对象异常:非法的执行权限;存储介质有破坏;非法的文件格式和内容;

                执行过程异常:拷贝到一半断电;拷贝过程中硬盘满;拷贝过程中源或目的被删除

        (2)功能

                 文件:不同的文件大小:1k,2k,10k...;不同的文件类型:文本,二进制,设备文件

                 目录:包含各种文件类型;包含子目录,目录深度;目录文件数量很多;针对文件和目录分别验证拷贝的准确性,完整性

         (3)性能

                  场景:拷贝大文件;拷贝目录中存在很多小文件

                             跨文件系统间拷贝;跨存储介质间拷贝(硬盘到U盘);构造源的各种磁盘分布(硬盘扇区分布);并发的执行拷贝

                  关注的性能点:拷贝时间、CPU、内存、磁盘IO

一、基本概念
定义:软件测试是为了发现错误而执行程序的过程,“寻找错误”是测试的目的
使用人工或自动手段运行或测定某个系统的过程,其目的在于检验它是否满足规定的需求或是否弄清预期结果与实际结果之间的差别
软件测试是一种重要的软件质量保证活动,测试过程中的活动包括分析软件和运行软件,是在软件投入运行前,对软件需求分析、设计规格说明和编码的最终复审,是软件质量保证的关键步骤。

测试:找错误(证明程序有错)
调试:该错误(使程序正确)

软件测试的目的:
(1)测试是程序执行的过程,目的在于发现错误
(2)一个好的测试用例在于能发现至今未发现的错误
(3)一个成功的测试是发现至今未发现的错误的测试
(测试的成功与失败在于能否发现错误,测试不能表能软件中不存在错误,只能说明软件中存在错误)

    通过对软件错误的原因和分布进行归纳,来发现并排除当前软件产品的缺陷,对在需求和设计过程中存在的问题查缺补漏,从而确保软件产品的质量;

软件测试的原则:
(1)所有的测试都应追索到用户的需求:系统中最严重的错误是导致程序无法满足用户需求的错误;
(2)尽早的和不断的进行软件测试:需求和设计时初心的缺陷占很大的比例;缺陷的修改成本随着阶段的推移而急剧上升;缺陷具有放大的特点

     (3)不可能完全的测试
     (4)80-20原则:测试发现的错误80%很可能起源于20%的模块中,应孤立这些疑点模块重点测试。
     (5)注意测试中的群集现象:在所测程序段中,若发现错误数目多,则残存数目也比较多
     (6)避免测试自己的程序
     (7)设计周密的测试用例
              软件测试的本质就是针对要测试的内容确定一组测试用例
              测试用例至少包括:
              执行测试用例前:应满足的前提条件
              输入
              预期输出
              设计测试用例时应包括合理的输入条件和不合理的输入条件
     (8)回归测试:程序修改错误后必须进行回归测试,避免引入新的错误
     (9)严格执行测试计划:排除测试的随意性

软件测试的对象:
(1)软件测试贯穿于定义与开发的整个期间
(2)软件测试的对象
需求规格说明
概要设计规格说明
详细设计规格说明
源程序
软件测试分类

是否执行被测试软件:

静态测试:不运行被测程序本身,而是通过在对软件进行分析、检查和审阅达到测试目的

  方法:代码审查;代码走查;桌面检查;技术评审

动态测试:值通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能。由三部分组成:编写测试用例、执行测试结果、分析程序的输出结果。

黑盒测试:功能测试/数据驱动测试,是在已知产品所应对应具有的功能的前提下,通过测试来检测每个功能是否都能正常使用。

白盒测试:结构测试/逻辑驱动测试,是在知道产品内部工作过程的前提下,可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行。

按照软件测试的策略和过程分(都是动态测试):

单元测试:单元测试的对象软件设计的最小单位——模块。单元测试的依据是详细设计描述,单元测试应对模块内所有重要的控制路径设计测试用例,以便发现模块内部的错误。单元测试多采用白盒测试技术,系统内多个模块可以并行的进行。

集成测试:组装软件的系统测试技术,按设计要求把通过单元测试的各个模块组装在一起之后,进行集成测试以便发现与接口有关的各种错误。

系统测试:是在真实或模拟系统运行的环境下,为验证和确认系统是否达到需求规格说明书规定的需求而对集成的硬件和软件系统进行的测试

验收测试:按照项目任务书或合同、供需双方约定的验收依据文档进行的整个系统的评测,决定是否接受或拒绝系统

按测试内容分:

功能测试:根据功能需求进行测试,以确定软件与软件功能需求的一致,功能遗缺和多余

性能测试:评价一个产品或组件与性能需求是否符合的测试

一、性能测试类型

  性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。负载测试和压力测试都属于性能测试,两者可以结合进行。通过负载测试,确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接受的性能点,来获得系统能提供的最大服务级别的测试。

  2.负载测试(Load Testing)

  在给定的测试环境下,通过在被测系统上不断增加压力,直到性能指标超过预定指标或某种资源使用已经达到饱和状态,目的是了解系统性能容量和处理能力极限。负载测试的主要用途是发现系统性能的拐点,寻找系统能够支持的最大用户、业务等处理能力的约束。
  负载测试是在固定测试环境,在其它测试角度(负载方面)不变的情况下,变化一个测试角度并持续增加压力,查看系统的性能曲线和处理极限,以及是否有性能瓶颈存在(拐点)。主要意义是从多个不同的测试角度去探测分析系统的性能变化情况,配合性能调优。测试角度可以是并发用户数、业务量、数据量等不同方面的负载。

  3.压力测试(Stress Testing)

  测试系统在一定饱和状态下系统能够处理的会话能力,以及是否出现错误,一般用于稳定性测试。

  可以理解为资源的极限测试。测试关注在资源处于饱和或超负荷的情况下,系统能否正常运行,是一种在极端压力下的稳定性测试。其主要意义是通过测试、调优保证系统即使在用户的极端压力下也不会出错甚至系统崩溃。

  压力测试的目的是调查系统在其资源超负荷的情况下的表现,尤其是对系统的处理时间有什么影响。这类测试在一种需要在反常数量、频率或资源的方式下执行系统。目标是通过极限测试方法,发现系统在极限或恶劣环境中自我保护能力。主要验证系统的可靠性。

  4.配置测试(Configuration Testing)

  通过对被测系统的软硬件环境的调整,了解各种不同环境对性能影响的程度,从而找到系统各项资源的最有分配原则。

  主要用于性能调优,在经过测试获得了基准测试数据后,进行环境调整(包括硬件配置、网络、操作系统、应用服务器、数据库等),再将测试结果与基准数据进行对比,判断调整是否达到最佳状态。

  5.并发测试(Concurrency Testing)

  模拟并发访问,测试多用户并发访问同一个应用、模块、数据时是否产生隐藏的并发问题,如内存泄漏、线程锁、资源争用问题。

  6.可靠性测试(Reliability Testing)

  通过给系统加载一定的业务压力的情况下,让应用持续运行一段时间,测试系统在这种条件下是否能够稳定运行。

  需要和压力测试区分开,两者的测试环境和测试目的不一样。压力测试强调在资源极限情况下系统是否出错,可靠性测试强调在 一定的业务压力下长时间(如24×7)运行系统,关注系统的运行情况(如资源使用率是否逐渐增加、响应时间是否越来越慢),是否有不稳定征兆。

eg:

负载测试:测试一个应用在重负荷下的表现,例如测试一个web站点在大量负荷下,何时系统的响应会退化或失败

压力测试:用来评估在超越最大负载的情况下系统将应如何进行

              压力测试的目标就是发现在高负荷条件下应用程序的缺陷

疲劳测试:采用系统稳定运行情况下能够支持的最大并发用户数,持续一段时间业务,通过综合分析交易执行指标和资源监控指标来确定系统处理最大量强度性能的过程

兼容测试:测试软件在一个特定的硬件/软件/操作系统/网络等环境下性能如何

安全性测试:针对程序中危险防止和危险处理设施进行的测试,以验证其是否有效

安装性测试

可用性测试:对“用户友好性”的测试

                主观的:取决于目标最终用户和可和

                用户面谈、调查、用户对话的路线和其他一些技术

                程序员和测试员通常都不宜做可用性测试员

注:功能的重点在于能做什么;性能在于做的如何

缺陷:最终产品和用户的期望不一致

       功能错误

       功能遗漏

       超出需求的部分

       性能不符合要求

二、测试模型与过程

   1-1 软件生命周期

   a.大棒开发法

   b.边改边写法

          优点:能够较为迅速的展现结果,适合需要快速制作并且用完就扔的小项目,如示范程序、演示程序等。

          缺点:其编码和测试可能是将长期的循环往复的过程



   c.  瀑布法:将软件生命周期的各项活动,规定为按照固定顺序相连的若干个阶段性工作,形如瀑布流水,最终得到软件产品

   优点:易于理解;调研开发的阶段性;强调早期计划及需求调查;确定何时能交付产品及何时进行评审与测试;

   缺点:需求调查分析只进行一次,不能适应需求变化;顺序的开发流程,使得开发中的经验教训不能反馈到该项目的开发中去;不能反映出软件开发过程的反复与迭代性;没有包含类型的风险评估;开发中出现的问题直到开发后期才暴露(测试在后期阶段),因此失去及早纠正的机会。



   d. 快速原型法

   根据客户需求在较短的时间内解决用户最迫切解决的问题,完成可演示的产品。这个产品只实现最重要的功能,在得到客户更加明确的需求之后,原型将丢弃



   e. 螺旋瀑布法

   将瀑布模型和快速原型模型结合起来,强调了其他模型所忽视的风险分析,特别适合于大型复杂的系统。 螺旋模型沿着螺线进行若干次迭代,图中的四个象限代表了以下活动:

          (1) 制定计划:确定软件目标,选定实施方案,弄清项目开发的限制条件

          (2) 风险分析:分析评估所选方案,考虑如何识别和消除风险;

          (3) 实施工程:实施软件开发和验证;

          (4) 客户评估:评价开发工作,提出修正建议,制定下一步计划。

  螺旋模型由风险驱动,强调可选方案和约束条件从而支持软件的重用,有助于将软件质量作为特殊目标融入产品开发之中。但是,螺旋模型也有一定的限制条件,具体如下:
  (1) 螺旋模型强调风险分析,但要求许多客户接受和相信这种分析,并做出相关反应是不容易的,因此,这种模型往往适应于内部的大规模软件开发。
  (2) 如果执行风险分析将大大影响项目的利润,那么进行风险分析毫无意义,因此,螺旋模型只适合于大规模软件项目。
  (3) 软件开发人员应该擅长寻找可能的风险,准确地分析风险,否则将会带来更大的风险
  一个阶段首先是确定该阶段的目标,完成这些目标的选择方案及其约束条件,然后从风险角度分析方案的开发策略,努力排除各种潜在的风险,有时需要通过建造原型来完成。如果某些风险不能排除,该方案立即终止,否则启动下一个开发步骤。最后,评价该阶段的结果,并设计下一个阶段。
优点:严格的全过程风险管理;强调个开发阶段的质量;提供机会评估项目是否有价值继续下去。

2.软件测试模型

   V模型的过程从左到右,描述了基本的开发过程和测试行为。V模型的价值在于它非常明确地标明了测试过程中存在的不同级别,并且清楚地描述了这些测试阶段和开发过程期间各阶段的对应关系;

   局限性:把测试作为最后一个活动,需求分析前期产生的错误直到后期的验收测试才能发现。

   该模型容易使人理解主要是针对程序进行测试寻找错误

   实际中,由于需求变更较大,导致要重复变更需求、设计、编码、测试。返工量大。主要用在快速程序的开发





   在V模型中增加软件开发各开发阶段应同步进行的测试,演化为W模型

   开发的是V,测试是与此并行的V;相对于V模型,W模型更科学,强调的是测试伴随整个软件开发周期,并且测试的对象不仅仅是程序,需求、功能、和设计同样要测试。测试和开发是同步进行的,有利于尽早的发现问题

   缺点:W和V都把软件的开发视为需求、设计、编码等一系列串行的活动,无法支撑迭代、自发性以及变更挑战

              主要应用在一些中型软件并且业务逻辑关联非常紧密的项目中



   H模型中,软件测试活动完全独立,贯穿于整个产品的周期,与其他流程并发的进行,某个测试点准备就绪时,就可以从测试准备阶段进行到测试执行阶段。软件测试可以尽早的进行,并且可以根据被测物的不同而分层次进行。

   软件测试是一个独立的流程,贯穿产品整个生命周期,与其他流程并发进行

   H模型指出软件测试要尽早准备,尽早执行,不同的测试活动可以是按照某次序先后进行,但也可能是反复的,只要某个测试达到准备就绪点,测试执行活动就可以开展。



   很好的处理测试与开发的交接过程,交接的过程是一个时间段,而不是一个点。

   左边描述的是针对单独程序片段所进行的相互分离的编码和测试,伺此后将进行频繁的交接,通过集成最终合成为可执行的程序,然后再对这些可执行的程序进行测试。

   已通过集成测试的产品可以进行封装并提交给用户,也可以作为更大规模和范围内集成的部分,多根并行的曲线表示变更可以在各个部分发生

   X模型还定位了探索性测试,这是不进行实现计划的特殊测试,给有经验的测试人员在测试计划外发现更多软件缺陷

三、 黑盒测试常用方法

  1. 边界值测试:

    1-1 边界

           a. 数值边界值:数值范围
    
          b. 字符边界值 :ASCII表
    
           c. 其他边界条件:默认值、空白、空值、零值、无输入等情况
    

    1-2 基本思想

           使用输入变量的最小值、略大于最小值、正常值、略小于最大值和最大值来设计测试用例(min,min+,nom,max-,maz)
    
          单缺陷假设:只让一个变量取边界值,其余变量取正常值
    
          多缺陷假设:同时让多个变量取边界值
    
          (1)边界值分析(单缺陷)(4N+1)
    
    
    
          (2)健壮性边界值分析(在异常情况下,软件还具有正常运行的能力)(增加一个取异常值,其他都正常值的测试用例,6N+1)
    
    
    
          (3)最坏情况测试(多个变量出现极值,最最小值,略大于最小值,正常值,最大值,略小于最大值做笛卡尔乘积,5N)
    
    
    
       (3)健壮性最坏情况测试(7N)
    
  2. 等价类测试

    2-1 等价类划分

         划分是指互不相交的一组子集,这些子集的并是整个集合
    

    2-2 有效等价类

          是指对于程序的规格说明来说是合理的、有意义的输入数据构成的集合。利用有效等价类可以验证程序是否实现了规格说明中的功能和性能。
    

    2-3 无效等价类

          对程序的规格说明来说是不合理的或无意义的输入数据所构成的集合。为了验证程序做其不应做的事情。
    

    2-4 等价类划分方法

         (1)按照区间划分。在输入条件规定了取值范围或值得个数的情况下,则可以确立一个有效等价类和两个无效等价类。
    
    
    
          (2)按照数值划分。在规定了输入数据的一组值(假定n),并且程序要对每一个输入值分别处理的该情况下,可确立n个有效等价类和一个无效等价类。
    
         (3)按照数值集合划分。在输入条件规定了输入值的集合或者规定了“必须如何”的情况下,可确立一个有效等价类和一个无效等价类。
    
          (4)在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类。
    
          (5)进一步细分等价类。在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步地划分为更小的等价类。
    
          (6)等价类划分还应特别默认值、空值、NULL、零值的情况。
    

    2-5 等价类的特点

          (1)完备性(全集)(2)无冗余性(互不相交的子集) (3)等价性
    

    2-6 等价类测试类型

          单/多缺陷:弱/强等价类
    
         是/否考虑无效等价类:健壮性/一般等价类测试
    
         eg  a≤x1≤d,区间为 [a,b) [b,c) [c,d];e≤x2≤g ,区间为 [e,f)  [f,g]
    
          (1)弱一般等价类测试:单缺陷,要求选取的测试用例覆盖所有的有效等价类
    

(2)弱一般等价类测试:多缺陷,要求将每个变量的有效等价类做笛卡尔积,设计测试用例覆盖笛卡尔积的每个元素。

(2)弱健壮性等价类测试:弱指基于单缺陷假设,健壮性指考虑了无效值。对有效输入,使用每个有效等价类的一个值;对无效输入,测试用例将拥有一个无效值。补充输入域边界以外的值(略小于最小值min-1,略大于与最大值max+1)

(3)基于多缺陷假设,并考虑无效输入

3 基于判定表的测试

3-1 判定表

(1)条件桩:列出了问题的所有条件。

(2)动作桩:列出了问题规定可能采取的操作。(1、2的排列顺序通常没有约束)

(3)条件项:列出针对它的左列条件的取值

(4)动作项:列出在条件项的各种取值情况下应该采取的动作

4.其他测试方法

4-1 因果图方法:从用自然羽然书写的程序规格说明的描述中找出因(输入条件)和果(输入或程序状态的改变)之间的关系绘制出因果图,然后通过因果图转换为判定表。

4-2 正交实验设计法:使用已经造好的正交表来安排适应并进行数据分析的一种方法,目的使用最小的测试用例达到最高的测试覆盖率。

4-3 错误推测设计方法:基于经验和直觉推测程序中所有可能存在的各种错误,从而有针对性的设计测试用例

四、 白盒测试常用方法

1.逻辑覆盖测试:根据被测试程序的逻辑结构设计测试用例。

  1. 语句覆盖:测试时设计若干测试用例,运行被测试程序,使程序中的每条可执行语句至少执行一次。

优点:检查所有语句;结构简单的代码测试效果好;容易实现自动测试;代码覆盖率高;如果是程序块覆盖,则不涉及程序块中的源代码。

缺点:不能检查出条件语句错误、循环语句错误;语句率覆盖率看似很高,却有严重缺陷(分支覆盖率)

  1. 判定覆盖/分支覆盖:设计若干测试用例,运行被测试程序,使得程序中每个判断的取真分支和取假分支至少经历一次,即判断的真假值均曾被满足。(while/switch/异常处理/跳转语句)

判定覆盖率:已取过“真”和“假”两个值的判定程序占程序中所有条件判定个数的百分比

优点:分支覆盖比语句覆盖查错能力强一些:执行了分支覆盖,实际也就执行了语句覆盖

缺点:不能查出条件语句错误/逻辑运算错误/循环次数错误/循环条件错误

  1. 条件覆盖:设计若干测试用例,执行被测程序后,要使每个判断中每个条件的可能取值至少满足一次,即每个条件至少有一次为真值,有一次为假值

优点:能够检查所有的条件错误;

缺点:不能实现对每个分支的检查,用例数量的增加

做到了完全的条件覆盖,并不能保证达到完全的判定覆盖。

做到了完全的判定覆盖也并不能保证达到了完全的条件覆盖==》条件和分支兼顾

  1. 判定-条件覆盖:将判定覆盖和条件覆盖结合起来,即设计足够的测试用例,使得判断条件中的每个条件的所有可能取值至少执行一次,并且每个判断本身的可能判定结果也至少执行一次。

优点:既考虑了每一个条件,又考虑了每一个分支,发现错误能力强于分支覆盖和条件覆盖。

缺点:并不能全面覆盖所有路径;用例数量增加

  1. 条件组合覆盖:设计足够的测试用例,运行被测程序,使得所有可能的条件取值组合至少执行一次

优点:满足了判定覆盖、条件覆盖和条件-判定覆盖

缺点:不能全面覆盖所有路径

  1. 路径覆盖:设计足够多的测试用例来覆盖程序中所有可能的路径(不可能:循环、、、、)

8.路径测试

  1. 基路径测试:把覆盖的路径数压缩到一定限度内,例如程序中的循环体只执行0次和1次

1-1 程序环路复杂性

a. 设E为控制流图的边数,N为图的节点数,则定义环路复杂性为V(G)=E-N+2

b. 设P为控制流图中的判定节点数,则由V(G)=P+1

c. 将环路复杂性定义为控制流图中的区域数(控制流图外面也要算一个区域)

2-1 独立路径:包括一组以前没有处理的语句或条件的一条路径

3-1 基本路径集:控制流图中所有独立路径的集合(路径数=环路复杂性)

4-1 基路径测试法:通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例。设计出的测试用例要保证在测试中的每个可执行语句至少执行一次(路径数=环路复杂性)。

缺点:测试覆盖并不充分(循环)

  1. 循环测试:针对循环的测试

3.数据流测试:基于程序的控制流,从建立的数据目标状态的序列中发现异常的结构测试方法,数据的定义/引用缺陷。

三、 单元测试

    单元:一个可独立运行的代码段

    独立运行:这个工作不受前一次或接下来的程序运行的结果影响,即不与上下文发送关系。

    单元测试方法:静态/动态

    静态测试:不需要运行单元代码,而是对代码进行逐行的检测

    动态测试:需要运行被测单元代码,由于被测单元需要调用其他单元,或者会被其他单元调用。

3-1 单元测试的环境

     静态测试:无需搭建测试环境

     动态单元测试:用一些辅助模块来模拟与所测模块相联系的其他模块,需要在测试之前搭建相应测试环境



      辅助模块分两种:

     (1)驱动模块(Driver):相当于所测模块的主程序

     (2)桩模块(stub):用于代替所测模块调用的子模块

      单元测试三个步骤:模拟输入->执行单元->检查验证输出

3-2 单元测试的策略和方法

     1、静态代码分析

           代码走读:一种交叉检查,就是自己的代码由他人来检查

           代码审查:以会议的形式展开,由大家根据缺陷检查表共同审核代码的质量

           代码评审:通常在审查会后进行,审查小组根据记录和报告进行评估

      2、单元结构测试(主要采用白盒测试)

            关注代码内部的执行情况,关注代码执行的覆盖率。

            基于路径的测试、基于数据流测试。

      3、单元功能测试(基本方法时黑盒测试)

            常用测试方法:边界测试、等价类测试、因果图测试

四、集成测试

 4-1. 基本概念

        集成:把多个单元组合起来形成更大的单元

        集成测试:在假定各个软件单元已经通过单元测试的前提下,检查各个软件单元之间的相互接口是否正确,也叫组装测试或联合测试

                         具体检测包括:功能性验证、接口测试、全局数据结构的测试以及计算精度检测等在集成测试时可能出现的错误

 4-2. 方法策略

非增量型集成测试:将所有软件统一集成后才进行整体测试(大棒集成)

增量型集成测试:从一个模块开始,测一次添加一个模块,边组装边测试,以发泄与结构相联系的问题(需要驱动程序或桩程序)

 4-3.基于功能分解的集成

       (1) 自顶向下集成:从最具控制力的主控模块开始,按照软件的控制层次结构,以深度优先或广度优先的策略,向系统中增加模块,直至实现整个系统, 需要设计桩模块

      优点:有助于最大限度减少对驱动程序的需求

      缺点:不能很好地支持有限功能的早期发布

      桩       模块不能反映真实情况,重要数据不能及时会送到上层模块,则测试可能并不充分

       (2)自底向上继承:从程序模块结构中最底层的模块开始组装,按控制层次增强的顺序向系统中增加模块并测试,直至实现整个系统,不需要再编制桩模块

   优点:减少了对桩模块的需求

              自底向上增值的方式可以实施多个模块的并行测试,提高测试效率,且管理方便,测试人员能较好地锁定软件故障所在位置。

   缺点:对驱动程序的需求使得测试管理变得复杂起来。高级别的逻辑和数据流在晚期测试,只有程序最后一个模块加入时才具有整体形象。

             不能很好地支持有限功能的早期发布。

       (3) 三明治集成:1和2的结合

 4-4.基于调用图的集成:以功能分解树为基础

七、案例

5-1 如何测试一个杯子

   5-2 测试web登录界面

   5-3 自动贩售机

   5-4 CP命令设计测试用例

       主要从异常、功能、性能三方面考虑

       (1)异常

                参数异常:源和目标参数异常;包含特殊字符;参数超长;指定的位置实际不存在

                拷贝对象异常:非法的执行权限;存储介质有破坏;非法的文件格式和内容;

                执行过程异常:拷贝到一半断电;拷贝过程中硬盘满;拷贝过程中源或目的被删除

        (2)功能

                 文件:不同的文件大小:1k,2k,10k...;不同的文件类型:文本,二进制,设备文件

                 目录:包含各种文件类型;包含子目录,目录深度;目录文件数量很多;针对文件和目录分别验证拷贝的准确性,完整性

         (3)性能

                  场景:拷贝大文件;拷贝目录中存在很多小文件

                             跨文件系统间拷贝;跨存储介质间拷贝(硬盘到U盘);构造源的各种磁盘分布(硬盘扇区分布);并发的执行拷贝

                  关注的性能点:拷贝时间、CPU、内存、磁盘IO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值