zoukankan      html  css  js  c++  java
  • 软件测试的基本理论知识

    软件测试的基本理论知识

    定义

    软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。

    软件测试的标准定义是:使用人工或自动的手段来运行或测定某个软件系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。

    概念

    狭义的概念

    程序测试是为了发现错误而执行程序的过程。

    广义的概念

    “静态测试”和“动态测试”。这样,静态测试和动态测试就构成了一个全过程的、完整的软件测试,而且静态测试显得更为重要。

    静态测试的主要活动是评审,即通过对需求、设计、配置、程序和其他各类文档的审查来检验相应的内容是否满足用户的需求。由于静态测试不需要运行程序,所以测试对象是属于静态的. 
          动态测试通过运行程序来发现软件系统中的问题,在程序运行过程中发现缺陷,它具有动态性。

    测试目的

    软件测试的目的是发现问题,发现至今未发现的问题。检验软件系统(或者说是产品)是否满足需求。

     

    测试对象      

    软件测试是不等同于程序测试,软件测试贯穿于软件定义和开发的整个期间。需求分析,概要设计,详细设计以及程序编码等各个阶段所得到的文档,包括需求规格说明书、概要设计规格说明,详细设计规格说明以及源程序,都是软件测试的对象。

    1.程序。

    2.数据。

    3.文档。

    测试目标

    1.发现一些可以通过测试避免的开发风险。

    2.实施测试来降低所发现的风险。

    3.确定测试何时可以结束。

    4.在开发项目的过程中将测试看作是一个标准项目。

    测试原则

    1.所有的测试都应追溯到用户需求。

    2.尽早不断测试的原则:错误发现的越早,修正它所需的费用越少。 测试应该尽早进行,最好在需求阶段就开始介入,因为最严重的错误不外乎是系统不能满足用户的需求。我们常常强调软件测试人员应该站在客户的角度去进行测试,除了发现程序中的错误,还要发现需求定义的错误、设计规格说明书的缺陷。

    3.IPO原则:测试用例由测试输入数据,测试执行步骤和预期输出结果三部分组成。

    4.独立测试原则:程序员应避免检查自己的程序,程序设计机构也不应测试自己开发的程序,软件测试应该由第三方来负责。

    5.合法和非合法原则:设计测试用例时,应包括合法的输入条件和不合法的输入条件以及各种边界条件,特殊情况下还要制造极端状态和意外状态,如网络异常中断、电源断电等。

    6.错误群集原则:软件错误呈现群集现象。程序某部分存在更多的错误可能性与该部分已发现的错误的数量成正比。

    7.严格性原则:严格执行测试计划,排除测试的随意性。一定要制定严格的测试计划,并且要有指导性。测试时间安排尽量宽松,不要希望在极短的时间内完成一个高水平的测试。

    8.覆盖原则:应对每一个测试结果做全面的检查。对错误结果要进行一个确认过程。一般由A测试出来的错误,一定要由B来确认。严重的错误可以召开评审会议进行讨论和分析,对测试结果要进行严格地确认,是否真的存在这个问题以及严重程度等。

    9.定义功能测试原则:不仅要检查程序是否做了它该做的事,还要检查程序是否做了它不该做的事。

    10.回归测试原则:应妥善保留测试用例,不仅可以用于回归测试,也可以为以后的测试提供参考。妥善保存测试计划、测试用例、出错统计和最终分析报告,为维护提供方便。

    11.错误不可避免原则:在测试时不能首先假设程序中没有错误。

    测试内容

    从标准观点来看,可以定义为“验证”和“有效性确认”的活动所够成的整体,即软件测试=V&V

    “验证”是检验软件是否已正确地实现了软件需求规格说明书所定义的系统功能和特性。验证过程提供证据表明软件相关产品与所有生命周期活动的要求(如正确性、完整性、一致性、准确性等)一致。相当于以软件产品设计规格说明书为标准进行软件测试的活动。

    “有效性确认”是确认所开发的软件是否满足用户真正需求的活动。一切从客户出发,理解客户的需求,并对软件需求定义和设计存疑,以发现需求定义和产品设计中的问题。主要通过各种软件评审活动来实现,保证让客户参加评审和测试活动。

    当然,软件测试的对象是产品(包括阶段性产品,如市场需求说明书、产品规格说明书、技术设计文档、数据字典、程序包、用户文档等),而质量保证和管理的对象集中于软件开发的标准、流程和方法等上。

    软件测试的过程阶段

    1.测试需求分析阶段:阅读需求,理解需求,主要就是对业务的学习,分析需求点,参与需求评审会议。

    2.测试计划阶段:主要任务就是编写测试计划,参考软件需求规格说明书,项目总体计划,内容包括测试范围(来自需求文档),进度安排,人力物力的分配,整体测试策略的制定。风险评估与规避措施有一个制定。

    3.测试设计阶段:主要是编写测试用例,会参考需求文档(原型图),概要设计,详细设计等文档,用例编写完成之后会进行评审。

    4.测试执行阶段:搭建环境,执行冒烟测试(预测试)-然后进入正式测试,bug管理直到测试结束。

    5.测试评估阶段:出测试报告,对整体过程做总结,对当前版本质量评估,确认是否可以上线。

    6.验收阶段:出用户手册,操作指引,公司严格评审流程,保证每一步输出的有效。

     

    测试分类

    1.按软件开发阶段的角度划分:单元测试、集成测试、系统测试、验收测试

    2.按是否查看源代码的角度划分:黑盒测试、灰盒测试、白盒测试

    3.按是否执行程序的角度划分:静态测试、动态测试

    4.按测试实施组织的角度划分:α测试、β测试、第三方测试

    5.按是否手工执行测试的角度划分:手工测试、自动化测试

    6.按测试对象的角度划分:性能测试、安全测试、兼容性测试、文档测试、易用性测试(用户体验测试)、业务测试、界面测试、安装测试

    7.按测试地域的角度划分:本地化测试、国际化测试

    按软件开发阶段的角度划分

    1.单元测试(Unit Testing)

    单元测试,又称模块测试。对软件的组成单位进行测试,其目的是检验软件基本组成单位的正确性。测试的对象是软件里测试的最小单位:模块。

    测试阶段:编码后或者编码前(TDD:测试驱动开发)

    测试对象:最小模块

    测试人员:白盒测试工程师或开发人员

    测试依据:代码和注释+详细文档

    测试方法:白盒测试

    测试内容:模块接口测试、局部数据结构测试、独立执行路径测试、错误处理路径测试、边界条件测试

    补充说明:

    (1)学习测试依据时,我们可以对比软件测试的“V”模型结合记忆

    (2)白盒测试不是单元测试,单元测试是白盒测试

    (3)测试驱动开发(TDD):测试人员先编写测试用例,开发人员根据测试用例写程序

    单元测试的目的

    单元测试的目的在于发现各模块内部可能存在的各种错误,主要是基于白盒测试。(也就是说,在单元测试过程中,用的最多的是白盒测试方法,也可能会有灰盒或者黑盒。单元测试和白盒测试是不同的划分,不存在包含关系)。

    在单元测试阶段对应的文档是详细设计文档(LLD);对应的代码就是单元代码,因此单元测试的目的主要有3点:

    1、验证代码是与设计相符合的;

    2、发现设计和需求中存在的错误;

    3、发现在编码过程中引入的错误。

    单元测试的特点

    1. 程序单元是应用的最小可测试部件,通常基于类或者类的方法进行测试。

    2. 程序单元和其他单元是相互独立的。

    3. 单元测试的执行速度很快

    4. 单元测试发现的问题相对容易定位。

    5. 单元测试通常由开发人员来完成。

    6. 通过了解代码的实现逻辑进行测试,通常称之为白盒测试。

    单元测试过程

    测试四部曲:

    1. 初始化数据
    2. 执行要测试的业务

    3. 验证测试的数据

    4. 清理数据

    单元测试策略

    1、孤立的单元测试策略(Isolation Unit Testing)

    方法:不考虑每个模块与其它模块之间的关系,为每个模块设计桩模块和驱动模块,每个模块进行独立的单元测试。

    优点:这个方法比较简单,最容易操作,可以达到很高的结构覆盖率,可以并行开展,该方法是纯粹的单元测试。

    缺点:桩函数和驱动函数工作量很大,效率低。

    2、自顶向下的单元测试策略(Top Down Unit Testing)

    方法:先对最顶层的单元进行测试,把顶层所调用的单元做成桩模块,其次对第二层进行测试,使用上面已经测试过的单元做驱动模块,以此类推,直到测试完所有模块。

    优点:可以节省驱动函数的开发工作,效率高。

    缺点:随着被测单元一个一个被加入,测试过程将变得越来越复杂,并且开发和维护的成本将增加。

    3、自底向上的单元测试策略(Bottom Up Unit Testing)

    方法:先对最底层的模块进行单元测试,将模拟调用该模块的模块设置为驱动模块,然后再对上面一层做单元测试,用下面已经测试好的模块做桩模块,以此类推,直到测试完所有模块。

    优点:可以节省桩函数的开发工作量,测试效率较高。

    缺点:不是纯粹的单元测试,底层函数的测试质量对上层函数的测试将产生很大影响。

    单元测试工具

    JavaScript单元测试工具 JsTestDriver和Venus和Buster.JS

    C单元测试工具 greatest

    C++单元测试工具 QTRunner和ECUT

    单元测试维护工具 Unitils

    Qt单元测试工具 QTestlib

    存储过程单元测试工具 SQLUnit

    数据库单元测试工具 DbUnit

    NoSQL的单元测试工具 NoSQLUnit

    单元测试框架

     Arquillian、The Grinder、

    JUnit 和TestNG是一个 Java 语言的单元测试框架;

     AndroidJUnit4 是Android的单元测试框架;

    C++ 单元测试框架 cipra

    Python单元测试框架 PyUnit、unittest、pytest

    Python 模拟测试框架 CaptureMock

    gtest是一个跨平台的(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)C++单元测试框架,由google公司发布。

    2.集成测试(Integration Testing)

    集成测试也称联合测试(联调)、组装测试:将程序模块采用适当的集成策略组装起来,对系统的接口及集成后的功能进行正确性检测的测试工作。集成主要目的是检查软件单位之间的接口是否正确。

    测试阶段:一般是单元测试之后

    测试对象:模块间的接口

    测试人员:白盒测试工程师或开发工程师

    测试依据:单元测试的文档+概要设计文档

    测试方法:黑盒测试与白盒测试(灰盒测试)

    测试内容:模块之间数据传输、模块之间功能冲突、模块组装功能的正确性、全局数据结构、单模块缺陷对系统的影响

    补充说明:

    单元测试是一个模块内部的测试,集成测试是在模块之间进行测试(至少两个)。

    集成测试的目的

    集成测试的目标是按照设计要求使用那些通过单元测试的构件来构造程序结构。单个模块具有高质量但不足以保证整个系统的质量。有许多隐蔽的失效是高质量模块间发生非预期交互而产生的。

    以下两种测试技术是用于集成测试:

    1)功能性测试。使用黑盒测试技术针对被测模块的接口规格说明进行测试。

    2)非功能性测试。对模块的性能或可靠性进行测试。

    另外,集成测试的必要性还在于一些模块虽然能够单独地工作,但并不能保证连接起来也能正常工作。程序在某些局部反映不出来的问题,有可能在全局上会暴露出来,影响功能的实现。此外,在某些开发模式中,如迭代式开发,设计和实现是迭代进行的。在这种情况下,集成测试的意义还在于它能间接地验证概要设计是否具有可行性。

    集成测试是确保各单元组合在一起后能够按既定意图协作运行,并确保增量的行为正确。它所测试的内容包括单元间的接口以及集成后的功能。使用黑盒测试方法测试集成的功能。并且对以前的集成进行回归测试。

    集成测试的内容

    集成测试的内容包括模块之间接口以及集成后的功能。它主要使用黑盒测试方法测试继承的功能,并对以前的集成进行回归测试。具体来说,集成测试的内容包括以下方面: 
    (1)、将各个具有相互调用关系的模块组装起来时,检查相应模块接口的数据是否会丢失。 
    (2)、判断各个子功能组合起来是否能够达到预期要求的父功能。 
    (3)、检查一个模块的功能是否对其他模块的功能产生不良影响。 
    (4)、检查全局数据结构是否正确,以及在完成模块功能的过程中是否会被异常修改。 
    (5)、单个模块的误差累计起来,是否会放大到不可接受的程度。

    集成测试过程

    1.计划阶段: 依据需求规格说明书、概要设计文档和开发计划,拟定软件集成测试计划;

    2设计阶段:依据被测对象的结构、待集成模块、接口、集成测试策略、测试工具等进行分析,拟定集成测试设计方案;

    3实现阶段:主要进行集成测试用例设计和集成测试代码设计;

    4执行阶段: 执行测试,生成测试报告。

    集成测试原则

    1.所有的公共接口都要被测试到;

    2.关键模块必须进行充分的测试;

    3.集成测试应该按一定的层次进行;

    4.集成测试的策略应该综合考虑质量、进度、成本;

    5.当测试计划中的结束标准满足时,集成测试结束;

    6.集成测试根据集成测试的计划和方案进行,防止测试的随意性;

    7.项目管理者保证测试用例经过审查;

    8.测试的执行结果应该如实的被记录。

    集成测试技术和步骤

    技术: 

       以黑盒测试技术为主、白盒测试技术为辅(灰盒测试技术)

    步骤:

       与集成测试策略相关

    集成测试策略

    基于功能分解的集成测试:非渐增式集成、渐增式集成、瞬时集成。

     

     

    瞬时集成测试策略又称大爆炸测试、一次性集成。首先对每个模块分别进行模块测试,然后将所有模块集成起来在一起进行测试,最终得到要求的软件系统。

    集成测试工具

    Jenkins持续集成自动化构建发布工具

    开源的 Restful Api 集成测试工具 Hitchhiker

    集成测试的三个级别

    由于集成的力度不同,一般可以把集成测试划分为三个级别:

    1、模块内集成测试。

    2、子系统内集成测试。

    3、子系统间集成测试。

    3.系统测试(System Testing)

    系统测试:将软件系统看成是一个系统的测试。包括对功能、性能以及软件所运行的软硬件环境进行测试。时间大部分在系统测试执行阶段,包括回归测试和冒烟测试。

    测试阶段:集成测试阶段之后

    测试对象:整个系统(软件、硬件)

    测试人员:黑盒测试工程师

    测试依据:需求规格说明文档

    测试方法:黑盒测试

    测试内容:功能、界面、可靠性、易用性、性能、兼容性、安全性等

    补充说明:

    (1)系统测试是从完整的角度,广面去看待问题,不再看模块;

    (2)虽然系统测试包括冒烟测试和回归测试,但三者之间是有严格的先后顺序的,即:先冒烟、再系统、后回归。

    系统测试的目的

    系统测试的目的是验证最终软件系统是否满足用户规定的需求。

    系统测试目标

    1、 确保系统测试的活动是按计划进行的;

    2、 验证软件产品是否与系统需求用例不相符合或与之矛盾;

    3、 建立完善的系统测试缺陷记录跟踪库;

    4、 确保软件系统测试活动及其结果及时通知相关小组和个人。

    系统测试主要分为以下几种:

    1.恢复测试

    2.安全测试

    3.强度测试

    4.性能测试

    系统测试原则

    1、测试机构要独立;

    2、要精心设计测试计划,包括负载测试、压力测试、用户界面测试、可用性测试、逆向测试、安装测试、验收测试;

    3、要进行回归测试;

    4、测试要遵从经济性原则。

    系统测试的方法

    功能测试:功能测试属于黑盒测试,是系统测试中最基本的测试。功能测试主要根据产品的需求规格说明和测试需求列表,验证产品是否符合需求规格说明。

    协议一致性测试:主要用于分布式系统。在分布式系统中,很多功能的实现是通过多台计算机相互协作来完成的,这要求计算机之间能相互交换信息,所以需要制定一些规则(协议)。对协议进行测试,通常包括:协议一致性测试、协议性能测试、协议互操作性测试、协议健壮性测试。

    性能测试:主要用于实时系统和嵌入式系统,性能测试是指测试软件在集成系统中的运行性能,目标是量度系统的性能和预先定义的目标有多大差距。一种典型的性能测试是压力测试,当系统同时接收极大数量的用户和用户请求时,需要测量系统的应对能力。性能测试要有工具的支持,在某种情况下,测试人员必须自己开发专门的接口工具。

    压力测试:又称强度测试,是在各种超负荷的情况下观察系统的运行情况的测试。

    容量测试:在系统正常运行的范围内测试并确定系统能够处理的数据容量。容量测试是面向数据的,主要目的就是检测系统可以处理目标内确定的数据容量。

    安全性测试:安全性测试就是要验证系统的保护机制是否抵御入侵者的攻击。保护测试是安全性测试中一种常见的测试,主要用于测试系统的信息保护机制。评价安全机制的性能与安全功能本身一样重要,其中安全性的性能主要包括:有效性、生存性、精确性、反应时间、吞吐量。

    失效恢复测试:验证系统从软件或者硬件失效中恢复的能力。失效恢复测试采用各种人为干预方式使软件出错,造成人为的系统失效,进而检测系统的恢复能力。如果恢复需要人为干预,则应考虑平均修复时间是否在限定的范围内。

    备份测试:备份测试是失效恢复测试的补充,目的是验证系统在软件或者硬件失效的实践中备份其数据的能力。

    GUI测试:GUI测试与用户友好性测试和可操作性测试有重复,但GUI测试更关注对图形界面的测试。GUI测试分为两个部分,一方面是界面实现与界面设计的情况要符合;另一方面是要确认界面能够正确处理事件。

                     GUI测试设计测试用例一般要从以下4方面考虑:

                     (1)划分界面元素,并根据界面的复杂性进行分层。通常把界面划分为三个层次,第一层是界面原子层;第二层是界面组合元素层;第三层是一个完整的窗口。

                     (2)在不同的界面层次确定不同的测试策略。

                     (3)进行测试数据分析,提取测试用例。

                     (4)使用自动化测试工具进行脚本化工作。

    健壮性测试:又称容错测试,用于测试系统在出故障时,是否能够自动恢复或者忽略故障继续运行。健壮性测试的一般方法是软件故障插入测试,在软件故障插入测试中,需要关注三个方面:目标系统、故障类型和插入故障的方法。

    兼容性测试:检验被测的应用系统对其他系统的兼容性。

    易用性测试:与可操作性类似。检测用户在理解和使用系统方面是否方便。易用性测试是面向用户的系统测试,包括对被测系统的系统功能、系统发布、帮助文本和过程等的测试。最好在开发阶段就开始进行。

    安装测试验证成功安装系统的能力。

    文档测试:主要是针对系统提交给用户的文档进行验证。文档测试的目标是验证用户文档的正确性并保证操作手册的过程能正常工作。

    在线帮助测试:用于检验系统的实时在线帮助的可操作性和准确性。

    数据转换测试:目标是验证已存在数据的转换并载入一个新的数据库是否有效。

    4.验收测试(Acceptance Testing)

    验收测试(交付测试):是部署软件之前的最后一个测试操作。它是技术测试的最后一个阶段,也称为交付测试。是以用户为主的测试,软件开发人员和质量保证人员也应参加,由用户参加设计测试用例,使用用户界面输入测试数据,并分析测试的输出结果。

    验收测试的目的是确保软件准备就绪,按照项目合同、任务书、双方约定的验收依据文档,向软件购买者系统测试展示该软件系统满足原始需求。

    测试阶段:系统测试通过后

    测试对象:整个系统(包括软硬件)

    测试人员:主要是最终用户或者需求方

    测试依据:用户需求、验收标准

    测试方法:黑盒测试

    测试内容:同系统测试(功能、各类文档等)

    补充说明:

    验收测试包括alpha测试和beta测试。alpha测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试。Beta测试由软件的最终用户们在一个或多个客房场所进行。

    验收测试分类

    用户验收测试可以分为两个大的部分:软件配置审核和可执行程序测试,其大致顺序可分为:文档审核、源代码审核、配置脚本审核、测试程序或脚本审核、可执行程序测试。

    验收测试策略

    实施验收测试的常用策略有三种,它们分别是:

    1· 正式验收

    2· 非正式验收或 Alpha 测试

    3· Beta 测试

    您选择的策略通常建立在合同需求、组织和公司标准以及应用领域的基础上。

    验收测试过程

    1. 软件需求分析:了解软件功能和性能要求、软硬件环境要求等,并特别要了解软件的质量要求和验收要求。

    2. 编制《验收测试计划》和《项目验收准则》:根据软件需求和验收要求编制测试计划,制定需测试的测试项,制定测试策略及验收通过准则,并经过客户参与的计划评审。

    3. 测试设计和测试用例设计:根据《验收测试计划》和《项目验收准则》编制测试用例,并经过评审。

    4. 测试环境搭建:建立测试的硬件环境、软件环境等。(可在委托客户提供的环境中进行测试)

    5. 测试实施:测试并记录测试结果。

    6. 测试结果分析:根据验收通过准则分析测试结果,作出验收是否通过及测试评价。

    7. 测试报告:根据测试结果编制缺陷报告和验收测试报告,并提交给客户。

    验收测试的内容

    通常可以包括:安装(升级)、启动与关机、功能测试(正例、重要算法、边界、时序、反例、错误处理)、性能测试(正常的负载、容量变化)、压力测试(临界的负载、容量变化)、配置测试、平台测试、安全性测试、恢复测试(在出现掉电、硬件故障或切换、网络故障等情况时,系统是否能够正常运行)、可靠性测试等。

     

    按是否查看代码的角度划分

    1.黑盒测试(Black-box Testing)

    黑盒测试也是功能测试,测试中把被测的软件当成一个黑盒子,不关心盒子的内部结构是什么,只关心软件的输入数据和输出数据。

    黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。黑盒测试着眼于程序外部结构,不考虑内部逻辑结构,主要针对软件界面和软件功能进行测试。

    黑盒测试是以用户的角度,从输入数据与输出数据的对应关系出发进行测试的。很明显,如果外部特性本身设计有问题或规格说明的规定有误,用黑盒测试方法是发现不了的。

    作用

    黑盒测试法注重于测试软件的功能需求,主要试图发现下列几类错误。

    功能不正确或遗漏;

    界面错误;

    输入和输出错误;

    数据库访问错误;

    性能错误;

    初始化和终止错误等。

    优点 

    1、对于子系统甚至系统,效率要比白盒测试高。 

    2、测试人员不需要了解实现的细节,包括特定的编程语言。 

    3、测试人员和编程人员彼此独立。 

    4、从用户的角度进行测试,很容易理解和接受。 

    5、有助于暴露规格的不一致或有歧义的问题。 

    6、测试用例可以在规格完成后马上进行。

    缺点 

    1、只有一小部分输入被测试到,要测试每个可能的输入几乎不可能。 

    2、没有清晰、简明的规格,测试用例很难设计。 

    3、如果测试人员不被告知开发人员已经执行过的用例,在测试数据上会存在不必要的重复。 

    4、有很多程序路径没有被测试到。 

    5、不能直接针对特定程序段测试,而这些程序段可能很复杂,有可能隐藏更多的问题。 

    6、大部分和研究相关的测试都是直接针对白盒测试的。

    测试用例设计方法

    从理论上讲,黑盒测试只有采用穷举输入测试,把所有可能的输入都作为测试情况考虑,才能查出程序中所有的错误。实际上测试情况有无穷多个,人们不仅要测试所有合法的输入,而且还要对那些不合法但可能的输入进行测试。这样看来,完全测试是不可能的,所以我们要进行有针对性的测试,通过制定测试案例指导测试的实施,保证软件测试有组织、按步骤,以及有计划地进行。黑盒测试行为必须能够加以量化,才能真正保证软件质量,而测试用例就是将测试行为具体量化的方法之一。具体的黑盒测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法、场景法等。

    等价类划分法

    等价类是指某个输入域的子集合。在该子集合中,各个输入数据对于揭露程序中的错误都是等效的,并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类。

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

    无效等价类:与有效等价类的定义恰巧相反。

    设计测试用例时,要同时考虑这两种等价类.因为,软件不仅要能接收合理的数据,也要能经受意外的考验.这样的测试才能确保软件具有更高的可靠性。

    1、划分等价类的原则

    ①  在输入条件规定了取值范围或值的个数的情况下,则可以确立一个有效等价类和两个无效等价类。

    例:输入值是学生成绩,范围是0~100:

     

    ②  在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可确立一个有效等价类和一个无效等价类。

    ③  在输入条件是一个布尔类型的情况下,可确定一个有效等价类和一个无效等价类。

    ④在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类。

    ⑤在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。

    ⑥在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步的划分为更小的等价类。

    2、建立等价类表

    设计测试用例:在确立了等价类后,可建立等价类表,列出所有划分出的等价类:

    3、确定测试用例

    输入条件 有效等价类 或  无效等价类

    然后从划分出的等价类中按以下三个原则设计测试用例:

    ①  为每一个等价类规定一个唯一的编号。

    ②  设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖地有效等价类,重复这一步.直到所有的有效等价类都被覆盖为止。

    ③  设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步.直到所有的无效等价类都被覆盖为止。

    4、举例:判断三角形类别

    【问题描述】程序要求:输入三个整数 a 、 b 、 c 分别作为三角形的三边长度,通过程序判定所构成的三角形的类型;当三角形为一般三角形、等腰三角形或等边三角形时,分别作处理 。 

    【问题分析】

    (1) 输入值域的显/隐式要求:A 整数、B 三个、C 正数、D 两边之和大于第三边、E 三边均不相等、F 两边相等但不等于第三边、G 三边相等;(D~G由输出值域的等价类隐性确定)

    (2) 输出值域的等价类:R1={不构成三角形}、R2={一般三角形}、R3={等腰三角形}、R4={等边三角形};

    【问题解答】
    (1) 列出等价类表并编号 

    (2) 设计覆盖有效等价类的测试用例 
     

    (3) 设计覆盖无效等价类的测试用例 
     

    【问题描述】程序要求:输入三个数 a 、 b 、 c 分别作为三角形的三边长度,通过程序判定所构成的三角形的类型;当三角形为一般三角形、等腰三角形或等边三角形时,分别作处理 。注:a、b、c非空。 

     

    【问题分析】

    (1) 输入值域的显/隐式要求:B 三个、C 正数、D 两边之和大于第三边、E 三边均不相等、F 两边相等但不等于第三边、G 三边相等;(D~G由输出值域的等价类隐性确定)

    (2) 输出值域的等价类:R1={不构成三角形}、R2={一般三角形}、R3={等腰三角形}、R4={等边三角形};

    【问题解答】
    (1) 列出等价类表并编号 

     

     (2) 设计覆盖有效/无效等价类的测试用例

    边界值分析法

    边界值分析是通过选择等价类边界的测试用例。边界值分析法不仅重视输入条件边界,而且也必须考虑输出域边界。它是对等价类划分方法的补充。

    (1)边界值分析方法的考虑:

    长期的测试工作经验告诉我们,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部.因此针对各种边界情况设计测试用例,可以查出更多的错误。

    使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入和输出等价类的边界,就是应着重测试的边界情况.应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据。

    (2)基于边界值分析方法选择测试用例的原则:

       1)如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据。

       2)如果输入条件规定了值的个数,则用最大个数,最小个数,比最小个数少一,比最大个数多一的数作为测试数据。

       3)根据规格说明的每个输出条件,使用前面的原则1)。

       4)根据规格说明的每个输出条件,应用前面的原则2)。

       5)如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例。

       6)如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构的边界上的值作为测试用例。

       7)分析规格说明,找出其它可能的边界条件。

    1、举例:区间值的边界值取值问题

    用边界值分析法,假定1<X<10,那么X在测试中应该取的边界值是( A )

    X=1,X=2,X=9,X=10

    X=2,X=9

    X=1,X=10

    X=1,X=5,X=6,X=10

    这里涉及到开闭区间和离点的概念,在边界值分析时,有下面几个点:

    上点:就是指得边界上得点,无论此时得域是开区间还是闭区间,开区间得话,上点就是在域外,闭区间得话,上点就是在域内。

    离点:指得就是离上点最近得点,这里就跟是闭区间还是开区间就有关系了,如果是开区间,那么离点就在域内,如果是闭区间,那么离点就在域外。

    内点:域内得任意点都是内点。

    题目中给的是开区间,不包括等于的情况。这里上点是1和10,因为是开区间,所以离点是在区间内,即2和9。所以边界值要覆盖1 2 9 10。

    上点很好理解,但是开区间的离点为什么在区间内,0和11需要覆盖吗?

    其实可以这么理解,对开区间,范围不包括边界,上点是在范围之外的,所以需要再测一个在范围之内,又离上点最近的点,这个值就是范围内离上点最近的点。

    另外,假如题目给的条件是1≦x≦10,那答案就是0 1 10 11,如果是1<x≦10,那答案就应该是1 2 10 11。

    2、举例:判断三角形类别

    【问题描述】程序要求:输入三个不超过200的整数 a 、 b 、 c 分别作为三角形的三边长度,通过程序判定所构成的三角形的类型;当三角形为一般三角形、等腰三角形或等边三角形时,结果打印出来 。 

    【问题分析】

    (1) 输入值域的显/隐式要求:A 整数、B 三个、C 正数、D 两边之和大于第三边、E 三边均不相等、F 两边相等但不等于第三边、G 三边相等;(D~G由输出值域的等价类隐性确定)

    (2) 输出值域的等价类:R1={不构成三角形}、R2={一般三角形}、R3={等腰三角形}、R4={等边三角形};

    (3)边界值:0、1、2、100、199、200、201

    当仅有一个变量取边界值,其他取正常值,从一般边界值的角度考虑{1、2、100、199、200},(4n+1=13,n=3)如下表所示。

    序号

    输入及操作说明

    期望的测试结果

    1

    1、100、100

    等腰三角形

    2

    2、100、100

    3

    199、100、100

    4

    200、100、100

    非三角形

    5

    100、1、100

    等腰三角形

    6

    100、2、100

    7

    100、199、100

    8

    100、200、100

    非三角形

    9

    100、100、1

    等腰三角形

    10

    100、100、2

    11

    100、100、199

    12

    100、100、200

    非三角形

    13

    100、100、100

    等边三角形

    当仅当有一个变量取边界值,其他取正常值,从健壮边界值的角度考虑{0、1、2、100、199、200、201},(6n+1=19,n=3) 如下表所示。

    序号

    输入及操作说明

    期望的测试结果

    1

    0、100、100

    非三角形

    2

    1、100、100

    等腰三角形

    3

    2、100、100

    4

    199、100、100

    5

    200、100、100

    非三角形

    6

    201、100、100

    7

    100、0、100

    8

    100、1、100

    等腰三角形

    9

    100、2、100

    10

    100、199、100

    11

    100、200、100

    非三角形

    12

    100、201、100

    13

    100、100、0

    14

    100、100、1

    等腰三角形

    15

    100、100、2

    16

    100、100、199

    17

    100、100、200

    非三角形

    18

    100、100、201

    19

    100、100、100

    等边三角形

     当所有变量取边界值时,介于篇幅原因,可使用上述表中的边界值自行完成53、73个测试用例。

       

    总结:

      由于多变量同时取边界值,关注的是变量同时取值对功能的影响,三角形问题的各个变量之间相对独立,因此对于三角形问题仅考虑使用一个变量取边界值,其他变量取正常值即可

    错误推测法

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

    错误推测方法的基本思想: 列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例。 例如,在单元测试时曾列出的许多在模块中常见的错误. 以前产品测试中曾经发现的错误等,这些就是经验的总结。还有,输入数据和输出数据为0的情况. 输入表格为空格或输入表格只有一行. 这些都是容易发生错误的情况。可选择这些情况下的例子作为测试用例。

    它的要素共有三点,分别为:经验、知识、直觉。关于如何使用的问题,我们提炼出两点:

      1.列举出程序中所有可能有的错误和容易发生错误的特殊情况;

      2.根据他们选择测试用例。

      我们知道经验是错误推测法的一个重要要素,也就说带有主观性,那么这就决定了错误猜测法的优缺点,首先我们来看优点:

      1.充分发挥人的直觉和经验;

      2.集思广益;

      3.方便使用;

      4.快速容易切入;

      对应的缺点有:

      1.难以知道测试的覆盖率;

      2.可能丢失大量未知的区域;

      3.带有主观性且难以复制;

    1、举例:手机终端通话功能

    例如:测试手机终端的通话功能,可以设计哪些通话失败的情况来补充测试用例

         1、无SIM 插入是进行呼出(非紧急呼叫)

         2、插入已欠费SIM卡进行呼出

         3、射频器件损坏或无信号区域插入有效SIM卡呼出

         4、网络正常、插入有效SIM卡,呼无效号码(如1、888、33333、不输入任何号码等)

         5、网络正常,插入有效SIM卡,使用“快速拔号”功能呼出设置无效号码的数字

    因果图法

    前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系,相互组合等。 考虑输入条件之间的相互组合,可能会产生一些新的情况. 但要检查输入条件的组合不是一件容易的事情,即使把所有输入条件划分成等价类,他们之间的组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例. 这就需要利用因果图(逻辑模型)。

    因果图方法最终生成的就是判定表。它适合于检查程序输入条件的各种组合情况。

    应用场景

    在一个界面中有多个控件,测试的时候要考虑各个控件的组合关系,不同控件的组合关系会产生不同的输出结果的组合,考虑用因果图。

    生成测试用例

    (1) 分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),并给每个原因和结果赋予一个标识符。

    (2) 分析软件规格说明描述中的语义。找出原因与结果之间,原因与原因之间对应的关系. 根据这些关系,画出因果图。

    (3) 由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况不可能出现. 为表明这些特殊情况,在因果图上用一些记号标明约束或限制条件。

    (4) 把因果图转换为判定表。

    (5) 把判定表的每一列拿出来作为依据,设计测试用例。

    从因果图生成的测试用例(局部,组合关系下的)包括了所有输入数据的取TRUE与取FALSE的情况,构成的测试用例数目达到最少,且测试用例数目随输入数据数目的增加而线性地增加。

    前面因果图方法中已经用到了判定表。判定表(Decision Table)是分析和表达多逻辑条件下执行不同操作的情况下的工具.在程序设计发展的初期,判定表就已被当作编写程序的辅助工具了.由于它可以把复杂的逻辑关系和多种条件组合的情况表达得既具体又明确。

    1、因果图标识

     原因和结果之间的关系有: 
     

     

    ①恒等:若C1是1,则E1也是1;若C1是0,则E1也是0。 
    ②非:若C1是1,则E1是0;若C1是0,则E1是1。 
    ③或:若c1或c2是1,则E1是1;否则E1为0。 或的含义:只有所有条件都为0时,结果为0,有任何1个条件为1(或者所有条件为1)时,结果为1
    ④与:若c1和c2都是1,则E1为1;否则E1为0。与的含义:只有所有条件都为1时,结果为1,有任何一个条件为0(或者所有条件为0)那么结果为0.

    2、因果图约束

    约束条件符号: 

     

      

    输入条件的约束有以下4类: 
    1. E约束(互斥/异):a和b中至多有一个可能为1,即a和b不能同时为1。含义:可以不选,如果选,只能选1个 
    2. I约束(或):a、b和c中至少有一个必须是1,即 a、b 和c不能同时为0。含义:至少选1个(可以多选,不能不选,最少得选1个) 
    3. O约束(唯一);a和b必须有一个,且仅有1个为1。含义:有且只有1个(必须要选,而且只能选1个)

    4. R约束();若a为1时,则b必须为1。而当a为0时,b的值不定。

    输出条件约束类型 

    输出条件的约束只有M约束(屏蔽/强制):若结果a是1,则结果b强制为0。而当a为0时,b的值不定。

    3、因果图法测试用例的设计步骤

    (1)  确定软件规格(需求)中的原因和结果

    分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件), 并给每个原因和结果赋予一个标识符。

    (2)  确定原因和结果之间的逻辑关系

    分析软件规格说明描述中的语义。找出原因与结果之间,原因与原因之间对应的关系。根据这些关系,画出因果图。

    (3)  确定因果图中的各个约束(constraints)

    由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况下不可能出现。 为表明这些特殊情况,在因果图上用一些记号表明约束或限制条件。

    (4)画出因果图并转换为决策表

    (5)根据决策表设计测试用例

    4、因果图法优缺点

    优点:

    ①  考虑到了输入情况的各种组合以及各个输入情况之间的相互制约关系。

    ②  能够帮助测试人员按照一定的步骤,高效率的开发测试用例。

    ③  因果图法是将自然语言规格说明转化成形式语言规格说明的一种严格的方法,可以指出规格说明存在的不完整性和二义性。

    缺点:

    ①  因果图来设计测试用例时,作为输入条件的原因与输出结果之间的因果关系,有时很难从软件需求规格说明中得到。

    ②  而且往往因果关系非常庞大,以至于据此因果图而得到的测试用例数目多的惊人,给软件测试,特别是手工测试带来沉重的负担,为了有效地,合理地减少测试的工时与费用,可利用正交实验设计方法进行测试用例的设计。

    5、举例:自动售货机

    产品说明书:有一个处理单价为1元5角钱的盒装饮料的自动售货机软件。若投入1元5角硬币,按下“可乐”、“雪碧”、或“红茶”按钮,相应的饮料就送出来。若投入的是2元硬币,在送出饮料的同时退还5角硬币。

     

     

    判定表法

    1.判定表是分析和表达多逻辑条件下执行不同操作的情况的工具。判定表通常由四个部分组成:

    条件桩(Condition Stub):列出了问题的所有条件.通常认为列出的条件的次序无关紧要。

    动作桩(Action Stub):列出了问题规定可能采取的操作.这些操作的排列顺序没有约束。

    条件项(Condition Entry):列出针对它左列条件的取值.在所有可能情况下的真假值。

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

     

    2.规则:任何一个条件组合的特定取值及其相应要执行的操作.在判定表中贯穿条件项和动作项的一列就是一条规则.显然,判定表中列出多少组条件取值,也就有多少条规则,既条件项和动作项有多少列。

     

    3. 判定表的化简:合并判定表中两条或多条具有相同动作,并且其条件项之间存在着极为相似关系的规则这一过程。

    4. 判定表使用场景:如果程序中多个条件决定一个动作,并且每个条件的取值只有两种,且条件和动作之间的逻辑关系明确

    5. 优点:能够将复杂的问题按照各种可能的情况全部列举出来,简明并且可以避免遗漏。

    1、判定表的建立步骤:(根据软件规格说明)

    1.列出所有的条件桩和动作桩。

    2.确定规则的个数。假如有n个条件.每个条件有两个取值(0,1),故有2n种规则。

    3.填入条件项。

    4.填入动作项.等到初始判定表。

    5.简化.合并相似规则(相同动作)。

    有两个或者多条规则具有相同的动作,并且条件项之间存在极为相似的关系就可以进行合并。

    2、判定表设计测试用例的条件:

    规格说明以判定表形式给出,或很容易转换成判定表。

    ①  条件的排列顺序不会也不影响执行哪些操作。

    ②  规则的排列顺序不会也不影响执行哪些操作。

    ③  每当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则。

    ④  如果某一规则得到满足要执行多个操作,这些操作的执行顺序无关紧要。

    3、判定表法优缺点

    判定表的优点:

          1)  充分考虑了输入条件简的组合,对组合情况覆盖充分;

          2)  最终每个用例覆盖多种输入情况,有利于提高测试效率;

          3)  设计过程中,对输入条件间的约束关系做了考虑,避免了无效用例,用例的有效性高;

          4)  能同时得出每个测试项目的预期输出。

    判定表的缺点:

          1)  当被测试特性输入较多时,会造成判定表规格庞大;

          2)  输入之间的约束条件不能有效区分输入是否确实需要进行组合测试,会造成不需要组合测试的输入做了组合,从而产生用例冗余。

    4、举例:判断三角形类别

     

     

     

     

    正交试验设计法

    就是使用已经造好了的正交表格来安排试验并进行数据分析的一种方法,目的是用最少的测试用例达到最高的测试覆盖率。

    使用正交试验设计法首先要知道正交表,正交表是研究多因素多水平的一种设计方法,它是格局正交性从全面试验中挑选出部分有代表性的点进行试验,这些有代表性的点具备了“均匀分散,齐整可比”的特点,正交试验设计是一种基于正交表的、高效率、快速、经济的试验设计方法。

    正交表由三个成分构成:

    Runs:正交表的行数,即实验的次数;

    Factors:正交表的列数,即因素数;

    Levels:水平数,任何单个因素能够取得的值的最大个数。正交表中的包含的值为从0到数“水平数-1”或从1到“水平数”

    正交表的表现形式是:L行数(水平数因素数)    L runs(levels^factors  )。

    1、设计过程

    1)确定试验因素及水平数;

    2)选用合适的正交表;

    3)列出试验方案及试验结果;

    4)对正交试验设计结果进行分析,包括极差分析和方差分析;

    5)确定最优或较优因素水平组合。

    2、用正交表设计测试用例的步骤:

    1. 有哪些因素(变量);

    2. 每个因素有哪几个水平(变量的取值):用等价类划分出来的;

    3. 选择一个合适的正交表;

    4. 把变量的值映射到表中;

    5. 把每一行的各因素水平的组合作为一个测试用例;

    6. 加上你认为可以且没有在表中出现的组合。

    如何选择正交表呢?取行数最少的一个,情况分三种:

    1.因素数(变量)、水平数(变量值)相符;

    2.因素数不相同: 取因素数最接近但略大的实际值的表;

    3.水平数不相同: 有五个因素(变量)A、B、C、D和E。两个因素有两个水平(变量的取值)、两个因素有三个水平,一个因素有六个水平。行数取最少的一个( 行数取最少的一个(L49(78)、 L18(3661)

    3、教你用Minitab进行正交试验设计(极差)分析

    首先,根据实验要求,确定你实验条件的因素、水平数,最好通过列表形式明确(如图:以影响大豆出油率为例)。

     

    然后,可以通过Minitab创建以上确定的正交表,依次选择工具栏“统计”—“DOE”—“田口”—“创建田口设计”选项,调出“田口设计”对话框。

    如图:

    在“田口设计”对话框中,根据需求选择合适的因素、水平数,并点击“设计”按钮,选择合适正交表。

    注意:要考虑到试验过程中的误差,所选正交表安排完因素后,要有一列空白列,以考察试验误差进行方差分析。(故本例:选4因素,3水平,L9表)。

    如图,创建的“四因素三水平正交表”(注意:此处不考虑交互作用)。

     

     

    在正交设计表等的基础上,将所选正交表中各列的“数字”换成对应因素的具体“实验水平值”(每一因素的某一水平均唯一对应一个实验条件值),便形成了试验方案。如图:

    此时可以根据此表安排实验方案。

     

    经过实验后,得到对应的数据结果后,填入正交表对应位置(本例:“大豆出油率/%”),进行实验数据分析。如图:

     

    接着可进行数据分析:依次选择工具栏“统计”—“DOE”—“田口”—“分析田口设计”选项,调出“分析田口设计”对话框。如图:

     

     

    然后,将实验数值列选择到“响应数据位于”(本例:C5 “大豆出油率/%”)框内,再点击“分析”按钮,选择要分析的项(本例:均值)如图:

    最后,依次点击“确定”按钮,即可得极差分析结果(如图)。本例中由于大豆出油率越大越好(B>A>D>C),所以最优水平为:B3 A2 D1 C2

     

    另外,Minitab软件还进行方差分析哦,(这里不再详述,请自行学习!)。

    希望能对你有帮助!

     

    场景法

    软件几乎都是用事件触发来控制流程的,事件触发的情景便形成了场景,而同一事件不同的触发顺序和处理结果就形成事件流。这种在软件设计方面的思想也可以引入到软件测试中,可以比较生动地描绘出事件触发时的情景,有利于测试设计者设计测试用例,同时使测试用例更容易理解和执行。

    场景法组成:基本流和备选流:如下图所示,图中经过用例的每条路径都用基本流和备选流来表示,直黑线表示基本流,是经过用例的最简单的路径。备选流用不同的色彩表示,一个备选流可能从基本流开始,在某个特定条件下执行,然后重新加入基本流中(如备选流1和3);也可能起源于另一个备选流(如备选流2),或者终止用例而不再重新加入到某个流(如备选流2和4)。

     

    1、备选流

    每个经过用例的可能路径,可以确定不同的用例场景。从基本流开始,再将基本流和备选流结合起来,可以确定以下用例场景:

    场景 1 基本流

    场景 2 基本流 备选流 1

    场景 3 基本流 备选流 1 备选流 2

    场景 4 基本流 备选流 3

    场景 5 基本流 备选流 3 备选流 1

    场景 6 基本流 备选流 3 备选流 1 备选流 2

    场景 7 基本流 备选流 4

    场景 8 基本流 备选流 3 备选流 4

    2、场景法的核心概念

    1、基本流(正确流):模拟用户正确的操作流程

    目的:验证软件的业务流程和主要功能

    2、备选流(错误流):模拟用户错误的操作流程

    目的:验证软件的错误处理能力

    3、场景法的本质

    1、场景法是一种基于等价类划分的测试技术(技术层面)

    2、场景法的应用是基于对软件业务(需求)的深入理解(业务层面)

    4、用例设计步骤

    1. 根据说明,描述出程序的基本流及各项备选流

    2. 根据基本流和各项备选流生成不同的场景

    3. 对每一个场景生成相应的测试用例

    4. 对生成的所有测试用例重新复审,去掉多余的测试用例,测试用例确定后,对每一个测试用例确定测试数据值

    5、举例:分析ATM取款机的场景流程

    例子:分析ATM取款机的场景流程,并设计测试用例和测试数据 

    1、根据需求,找到基本流和备选流(找出正确的操作流程和可能出错的环节)

    基本流:1.插入磁卡

         2.ATM验证账户正确

         3.输入密码正确,通过验证

         4.输入取款金额

         5.取出金额

         6.取卡

    备选流一:账户不存在或者受限制

    备选流二:密码不正确,还有输入机会

    备选流三:密码不正确,没有输入机会

    备选流四:卡中余额不足

    备选流五:ATM机中余额不足

    备选流六:超过每日最大提款限额

    备选流七:输入金额非100的倍数

     

    2.白盒测试(White-box Testing)

    白盒测试又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。盒子指的是被测试的软件,白盒指的是盒子是可视的,你清楚盒子内部的东西以及里面是如何运作的。

    "白盒"法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。"白盒"法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。白盒测试是指打开盒子,去研究里面的源代码和程序结果。

    白盒测试也是接口测试的一种。

    目的

    1.保证一个模块中的所有独立路径至少被执行一次;

    2.对所有的逻辑值均需要测试真、假两个分支;

    3.在上下边界及可操作范围内运行所有循环;

    4.检查内部数据结构以确保其有效性。

    测试方法

    白盒测试的测试方法有代码检查法、静态结构分析法、静态质量度量法、逻辑覆盖法、基本路径测试法、域测试、符号测试、Z路径覆盖和程序变异。

    白盒测试法的覆盖标准有逻辑覆盖、循环覆盖和基本路径测试。

    1、覆盖标准

    a).逻辑覆盖有:语句覆盖、判定覆盖(分支覆盖)、条件覆盖、判定/条件覆盖、条件组合覆盖、路径覆盖;

    b).控制结构覆盖有:基本路径测试、循环测试、条件测试、数据流测试 

    2、代码检查法

       代码检查是白盒测试的一种静态测试方法,是一种对程序代码进行静态检查。代码检查包括桌面检查、代码审查和走查等,主要检查:

    1. 检查代码和设计的一致性;
    2. 代码的可读性及对软件设计标准的遵循情况;
    3. 代码逻辑表达的正确性;
    4. 代码结构的合理性;
    5. 发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分;
    6. 违背程序编程风格的内容,包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容。

    a).代码检查方法

    (1)  桌面检查:

    这是一种传统的检查方法,由程序员检查自己编写的程序。程序员在程序通过编译之后,对源程序代码进行分析、检验,并补充相关文档,目的是发现程序中的错误。由于程序员熟悉自己的程序及其程序设计风格,桌面检查由程序员自己进行可以节省很多的检查时间,但应避免主观片面性。

    (2)代码审查
        由若干程序员和测试员组成一个审查小组,通过阅读、讨论和争议,对程序进行静态分析的过程。代码审查分两步:第一步,小组负责人提前把设计规格说明书、控制流程图、程序文本及有关要求、规范等分发给小组成员,作为审查的依据。小组成员在充分阅读这些材料后,进入审查的第二步,召开程序审查会。在会上,首先由程序员逐句简介程序的逻辑。在此过程中,程序员或其他小组成员可以提出问题,展开讨论,审查错误是否存在。实践表明,程序员在讲解过程中能发现许多原来自己没有发现的错误,而讨论和争议则促进了问题的暴露。
        在会前,应当给审查小组每个成员准备一份常见错误的清单,把以往所有可能发生的常见错误罗列出来,供与会者对照检查,以提高审查的失效。这个常见的错误清单也成为检查表,它把程序中可能发生的各种错误进行分类,对每一类错误列出尽可能多的典型错误,然后把它们制成表格,供再审查时使用。
    (3)走查
        与代码审查基本相同,分为两步,第一步也是把材料分给走查小组的每个成员,让他们认真研究程序,然后再开会。开会的程序与代码审查不同,不是简单地读程序和对照错误检查表进行检查,而是让与会者“充当”计算机,即首先由测试组成员为所测试程序准备一批有代表性的测试用例,提交给走查小组。走查小组开会,集体扮演计算机角色,让测试用例沿程序的逻辑运行一遍,随时记录程序的踪迹,供分析和讨论用。

    代码检查应在编译和动态测试之前进行,在检查前,应准备好需求描述文档、程序设计文档、程序的源代码清单、代码编译标准和代码缺陷检查表等。在实际使用中,代码检查能快速找到缺陷,发现30%~70%的逻辑设计和编码缺陷,而且代码检查看到的问题本身而非征兆。但是代码检查非常耗费时间,而且代码检查需要知识和经验的积累。
        代码检查可以使用测试软件进行自动化测试,以利于提高测试效率,降低劳动强度,或者使用人工进行测试,以充分发挥人力的逻辑思维能力。

    b).代码检查项目

    变量交叉引用表;标号的交叉引用表;检查子程序、宏、函数;等价性检查;常量检查;标准检查;风格检查;比较控制流;选择、激活路径;补充文档
    根据检查项目可以编制代码规则、规范和检查表等作为测试用例,如编码规范、代码检查规范、缺陷检查表等。

    c).编码规范

    编码规范是指程序在编写过程中必须遵循的规则,一般会详细制定代码的语法规则、语法格式等。

    d).代码检查规范

    在代码检查中,需要依据被测软件的特点,选用适当的标准与规则规范。在使用测试软件进行自动化代码检查时,测试工具一般会内置许多的编码规则。在自动化测试基础上使用桌面检查、代码走查、代码审查等人工检查的方法仔细检查程序的结构、逻辑等方面的缺陷。

    e).缺陷检查表

    在进行人工代码检查时,代码缺陷检查表是我们用到的测试用例。代码缺陷检查表中一般包括容易出错的地方和在以往的工作中遇到的典型错误。

    3、静态结构分析法

    在静态结构分析中,测试者通过使用测试工具分析程序源代码的系统结构、数据结构、内部控制逻辑等内部结构,生成函数调用关系图、模块控制流图、内部文件调用关系图、子程序表、宏和函数参数表等各类图形图标,可以清晰地标识整个软件系统的组成结构,使其便于阅读和理解,然后可以通过分析这些图标,检查软件有没有存在缺陷或错误。

    其中函数调用关系图通过应用程序中各函数之间的调用关系展示了系统的结构。通过查看函数调用关系图,可以检查函数之间的调用关系是否符合要求,是否存在递归调用,函数的调用是否过深,有没有存在独立的没有被调用的函数。从而可以发现系统是否存在结构缺陷,发现哪些函数是重要的,哪些是次要的,需要使用什么级别的覆盖要求等。

      模块控制流图是与程序流程图相类似的,由许多节点和连接节点的边组成的一种图形,其中一个节点代表一条语句或数条语句,边代表节点间控制流向,它显示了一个函数的内部逻辑结构。模块控制流图可以直观地反映出一个函数的内部逻辑结构,通过检查这些模块控制流图,能够很快发现软件的错误与缺陷。

    检查项:代码风格和规则审核;程序设计和结构的审核;业务逻辑的审核;走查、审查与技术复审手册。

     

     

     

    4、静态质量度量法

    1、度量规则

      度量规则使用了代码行数、注释频度等参数度量软件的各种行为属性。

    2、分类标准

      软件的可维护性采用以下四个分类标准来评估:可分析性(ANALYZABILITY)、可修改性(CHANGEABILITY)、稳定性(STABILITY)、可测性(TESTABILITY)。每个分类标准由一系列度量规则组成,各个规则分配一个权重,由规则的取值与权重值计算出每个分类标准的取值。

      function_TESTABILITY_DRCT_CALLS+LEVL+PATH+PARA

    3、质量因素

      质量因素的取值与分类标准的计算方式类似:依据各分类标准取值组合权重方法计算。

      function_MAINTAINABILITY=function_ANALYZABILITY + function_CHANGEABILITY + function_ATABILITY + function_TESTABILITY

    a).质量度量模型(从上到下)

    质量因素(Factors):与分类标准的计算方式相似,依据各分类标准取值组合权重方法来计算,依据结果将软件质量分为四个等级,与分类标准等级内容相同。

    分类标准(criteria):对某一软件质量分为不同的分类标准,每个分类标准由一系列度量规则组成,每个规则分配一个权重,每个分类标准的取值由规则的取值与权重值计算得出,依据结果将软件质量分为四个等级:

    优秀(exceent):符合本模型框架中的所有规则(可以接受)

    良好(good):未大量偏离模型框架中的规则(可以接受)

    一般(fair):违背了模型框架中的大量规则(可以接受)

    较差(poor):无法保障正常的软件可维护性(不可以接受)

    度量规则(Metrics):使用代码行数、注释频度等参数度量软件各种行为属性

    4、逻辑覆盖

    逻辑覆盖是以程序内部的逻辑结构为基础的设计测试用例的技术。其中逻辑覆盖包括语句覆盖、判定覆盖、条件覆盖、判定条件组合覆盖、条件组合覆盖和路径覆盖。六种覆盖标准发现错误的能力呈由弱到强的变化:

    1.语句覆盖每条语句至少执行一次。

    2.判定覆盖每个判定的每个分支至少执行一次。

    3.条件覆盖每个判定的每个条件应取到各种可能的值。

    4.判定/条件覆盖同时满足判定覆盖和条件覆盖。

    5.条件组合覆盖每个判定中各条件的每一种组合至少出现一次。

    6.路径覆盖使程序中每一条可能的路径至少执行一次。

     

     

    逻辑覆盖原则

     

    语句覆盖

    定义

    “语句覆盖”是一个比较弱的测试标准,它的含义是:在测试时,首先设计若干个测试用例,然后运行被测程序, 使程序中的每个可执行语句至少执行一次。这时所谓“若干个”,自然是越少越好。即用最少得测试用例来达到语句全覆盖。

    用例设计

    为使程序中每个语句至少执行一次,只需设计一个能通过路径ace的例子就可以了,例如选择输入数据为: A=2,B=0,X=4 

    这样该程序段的4个语句均得到执行,从而作到了语句覆盖。

     

    优点

    可以很直观地从源代码得到测试用例,无须细分每条判定表达式。

    缺点

    由于这种测试方法仅仅针对程序逻辑中显式存在的语句(即可执行语句),但对于隐藏的条件和可能到达的隐式逻辑分支,是无法测试的。

    判定覆盖

    定义

    比“语句覆盖”稍强的覆盖标准是“判定覆盖”(或称branch coverage分支覆盖)标准。判定覆盖准则进行测试是指,设计若干测试用例,运行被测程序,使得程序中每个判断的取真分支和取假分支至少经历一次,即判断的真假值均曾被满足。判定覆盖又称为分支覆盖。设计测试用例只需要用最少条数,以判定条件结果为全真或者全假的思路来编写测试用例。

    用例设计

    如果设计两个例子,使它们能通过路径ace和abd,或者通过路径acd和abe,就可达到“判定覆盖”标准,为此,可以选择输入数据为: 
    ①A=2,B=0,X=4(沿判定条件结果为全真路径ace执行)

    ②A=1,B=1,X=1(沿判定条件结果为全假路径abd执行) 

     

    优点

    判定覆盖比语句覆盖要多几乎一倍的测试路径,当然也就具有比语句覆盖更强的测试能力。同样判定覆盖也具有和语句覆盖一样的简单性,无须细分每个判定就可以得到测试用例。

    缺点

    往往大部分的判定语句是由多个逻辑条件组合而成(如,判定语句中包含AND、OR、CASE),若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径。

    条件覆盖

    定义

    条件覆盖于分支覆盖不同,条件覆盖要求所设计的测试用例能使每个判定中的每一个条件都获得可能的取值,即每个条件至少有一次真值、有一次假值。

    用例设计

    A>1、B=0、A=2、X>1

    为了达到“条件覆盖”标准,需要执行足够的测试用例使得在判定条件1处有:  

    A>1、A≤1、B=0、B≠0

    等各种结果出现,以及在判定条件2处有:A=2、A≠2、X>1、X≤1等各种结果出现。

    现在只需设计以下两个测试用例就可满足这一标准:

    ①  A=2,B=0,X=4(沿判定条件中的各个条件都为真路径ace执行);

    ②  A=1,B=1,X=1(沿判定条件中的各个条件都为假路径abd执行) 

     

    优点

    增加了对条件判定情况的测试,增加了测试路径。

    缺点

    条件覆盖不一定包含判定覆盖。条件覆盖只能保证每个条件至少有一次为真,而不考虑所有的判定结果。

    判定条件组合覆盖

    定义

    执行足够的测试用例,使得判定中每个条件取到各种可能的值,并使每个判定取到各种可能的结果。

    用例设计

    A>1、B=0、A=2、X>1

    为了达到“条件覆盖”标准,需要执行足够的测试用例使得在判定条件1处有:  

    A>1、A≤1、B=0、B≠0

    等各种结果出现,以及在判定条件2处有:A=2、A≠2、X>1、X≤1等各种结果出现。

    另外也要满足判定条件1处结果出现一次真和一次假,则要保证(A>1 AND B=0)为真(A=2,B=0)和为假(A=1,B=1),同时也满足了条件覆盖说的每个条件都要出现一次真和一次假。(A=2为真,B=0为真)和为假(A=1为假,B=1为假)。

    同理判定条件2处结果出现一次真和一次假,则要保证(A=2 OR X>1)为真(A=2,X=4)和为假(A=1,X=1),同时也满足了条件覆盖说的每个条件都要出现一次真和一次假。(A=2为真,X=4为真)和为假(A=1为假,X=1为假)。

    现在只需设计以下两个测试用例就可满足这一标准:

    ①  A=2,B=0,X=4(沿判定条件中的各个条件都为真,同时也满足判定条件结果均为真路径ace执行);

    ②  A=1,B=1,X=1(沿判定条件中的各个条件都为假,同时也满足判定条件结果均为假路径abd执行) 

     

    优点

    能同时满足判定、条件两种覆盖标准。

    缺点

    判定/条件覆盖准则的缺点是未考虑条件的组合情况。

    条件组合覆盖

    定义

    执行足够的例子,使得每个判定中条件的各种可能组合都至少出现一次。显然,满足“条件组合覆盖”的测试用例是一定满足“判定覆盖”、“条件覆盖”和“判定/条件覆盖”的。

    用例设计

     

    条件组合覆盖说的判定条件里的每个条件组合在一起形成的各种可能。

    使得下面8种条件组合都能够出现:

    1)A>1, B=0    2)A>1, B≠0     3)A≤1, B=0    4)A≤1, B≠0   

    5)A=2, X>1    6)A=2, X≤1     7)A≠2, X>1    8)A≠2, X≤1

    判定条件1里有2个条件,所以条件组合的情况是2*2=4个的情况;排列组合里的组合逻辑形成的个数。如果有3个条件,则就有2*2*2=8个的情况,以此类推。

    判定条件1:(A=2为真,B=0为真)、(A=2为真,B=1为假)、(A=1为假,B=0为真)、(A=1为假,B=1为假)。

    判定条件2:(A=2为真,X=4为真)、(A=2为真,X=1为假)、(A=1为假,X=4为真)、(A=1为假,X=1为假)。

    现在只需设计以下两个测试用例就可满足这一标准:

    ①  A=2,B=0,X=4(沿判定条件中的各个条件A=2为真,B=0为真,A=2为真,X=4为真,路径ace执行);

    ②  A=2,B=1,X=1(沿判定条件中的各个条件A=2为真,B=1为假,A=2为真,X=1为假,路径abe执行);

    ③  A=1,B=0,X=2(沿判定条件中的各个条件A=1为假,B=0为真,A=1为假,X=2为真,路径abe执行);

    ④  A=1,B=1,X=1(沿判定条件中的各个条件A=1为假,B=1为假,A=1为假,X=1为假,路径abd执行) 

    上面四个例子虽然满足条件组合覆盖,但并不能覆盖程序中的每一条路径,例如路径acd就没有执行,因此,条件组合覆盖标准仍然是不彻底。

    优点

    能同时满足判定、条件两种覆盖标准。条件组合覆盖准则满足判定覆盖、条件覆盖和判定/条件覆盖准则。

    缺点

    线性地增加了测试用例的数量。

    路径覆盖

    定义

    选取足够多的测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。

    对于比较简单的小程序来说,实现路径覆盖是可能的,但是如果程序中出现了多个判断和多个循环,可能的路径数目将会急剧增长,以致实现路径覆盖是几乎不可能的。

    所以我们需要路径分析,计算程序中的路径数(复杂度)。

    以下的公式:V(G)=e-n+2

    PS:其中e为边数,n为结点数。

    优点

    这种测试方法可以对程序进行彻底的测试,比前面五种的覆盖面都广。

    缺点

    需要设计大量、复杂的测试用例,使得工作量呈指数级增长,不见得把所有的条件组合都覆盖。

    基本路径测试法

    在程序控制图的基础上,通过分析控制构造的环行复杂性,导出基本可执行路径集合,从而设计测试用例。设计出的测试用例要保证在测试中程序的每一个基本独立路径至少执行一次。

    在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例。

    包括以下4 个步骤

    1. 程序的控制流图:描述程序控制流的一种图示方法。

    2. 程序圈复杂度:McCabe复杂性度量。从程序的环路复杂性可导出程序基本路径集合中的独立路径条数,这是确定程序中每个可执行语句至少执行一次所必须的测试用例数目的上界。

    3. 导出测试用例:根据圈复杂度和程序结构设计用例数据输入和预期结果。

    4. 准备测试用例:确保基本路径集中的每一条路径的执行。

    一个工具方法: 

    图形矩阵:是在基本路径测试中起辅助作用的软件工具,利用它可以实现自动地确定一个基本路径集。

    另外,对于测试用例的选择除了满足所选择的覆盖程度(或覆盖标准)外还需要尽可能的采用边界值分析法、错误推测法等常用地设计方法。采用边界值分析法设计合理的输入条件与不合理的输入条件;条件边界测试用例应该包括输入参数的边界与条件边界(if,while,for,switch ,SQL Where子句等)。错误推测法,列举出程序中所有可能的错误和容易发生错误的特殊情况,根据它们选择测试用例;在编码、单元测试阶段可以发现很多常见的错误和疑似错误,对于这些错误应该作重点测试,并设计相应的测试用例。

    控制流图

    基本语句对应的控制流图:

     

    程序流程图->控制流图

     

    如何根据程序流程图画出控制流程图?

      在将程序流程图简化成控制流图时,应注意:

      1)在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。

      2)边和结点圈定的范围叫做区域,当对区域计数时,图形外的区域也应记为一个区域。

    如下图所示:

    三种计算方法:

    1. 控制流图中区域的数量

    2. V(G)= E-N+2,E是边数,N是结点数

    3. V(G)= P+1,P是判定结点的数量

    圆圈称为控制流图的一个结点,表示一个或多个无分支的语句或源程序语句

    独立路径( 基本路径)

    一条程序执行的路径 ,至少包含一条在定义该路径之前的其他基本路径中所不曾用过的边( 即:至少引入程序的一个新处理语句集合或一个新条件)

    注意:独立路径不应该经过同一个判定结点的左右两侧,否则这条路径如果出现错误,则不知道是哪一侧出现错误。

    设计测试用例步骤 

    第一步:画出控制流图

      流程图用来描述程序控制结构。可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。在流图中,每一个圆,称为流图的结点,代表一个或多个语句。一个处理方框序列和一个菱形决策框可被映射为一个结点,流图中的箭头,称为边或连接,代表控制流,类似于流程图中的箭头。一条边必须终止于一个结点,即使该结点并不代表任何语句(例如:if-else-then结构)。由边和结点限定的范围称为区域。计算区域时应包括图外部的范围。

    画出其程序流程图和对应的控制流图如下

           

    第二步:计算圈复杂度

      圈复杂度是一种为程序逻辑复杂性提供定量测度的软件度量,将该度量用于计算程序的基本的独立路径数目,为确保所有语句至少执行一次的测试数量的上界。独立路径必须包含一条在定义之前不曾用到的边。

      有以下三种方法计算圈复杂度:

      流图中区域的数量对应于环型的复杂性;

      给定流图G的圈复杂度V(G),定义为V(G)=E-N+2,E是流图中边的数量,N是流图中结点的数量;

      给定流图G的圈复杂度V(G),定义为V(G)=P+1,P是控制流图G中判定结点的数量。

      

    第三步:导出测试用例

      根据上面的计算方法,可得出四个独立的路径。(一条独立路径是指和其他的独立路径相比,至少引入一个新处理语句或一个新判断的程序通路。V(G)值正好等于该程序的独立路径的条数。)

      路径1:4-14

      路径2:4-6-7-14

      路径3:4-6-8-10-13-4-14

      路径4:4-6-8-11-13-4-14

      根据上面的独立路径,去设计输入数据,使程序分别执行到上面四条路径。

    第四步:准备测试用例

      为了确保基本路径集中的每一条路径的执行,根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到,满足上面例子基本路径集的测试用例是:

    工具方法:图形矩阵

    导出控制流图和决定基本测试路径的过程均需要机械化,为了开发辅助基本路径测试的软件工具,称为图形矩阵(graph matrix)的数据结构很有用。利用图形矩阵可以实现自动地确定一个基本路径集。一个图形矩阵是一个方阵,其行/列数控制流图中的结点数,每行和每列依次对应到一个被标识的结点,矩阵元素对应到结点间的连接(即边)。

    对每个矩阵项加入连接权值(link  weight),图矩阵就可以用于在测试中评估程序的控制结构,连接权值为控制流提供了另外的信息。最简单情况下,连接权值是 1(存在连接)或0(不存在连接),但是,连接权值可以赋予更有趣的属性:

    执行连接(边)的概率。

    穿越连接的处理时间。

    穿越连接时所需的内存。

    穿越连接时所需的资源。

    上图为图形矩阵:

    连接权为“1”表示存在一个连接,在图中如果一行有两个或更多的元素“1”,则这行所代表的结点一定是一个判定结点,通过连接矩阵中有两个以上(包括两个)元素为“1”的个数,就可以得到确定该图圈复杂度的另一种算法。

    循环测试

         从本质上来说,循环测试的目的就是检查循环结构的有效性。

    四种循环 :简单循环 、嵌套循环 、串接循环、无结构循环(非结构循环)

    简单循环

    对于简单循环,测试应包括以下几种,其中的n 表示循环允许的最大次数。

    1.零次循环:从循环入口直接跳到循环出口。 (换句话说:跳过循环)

    2. 一次循环:查找循环初始值方面的错误。

    3. 二次循环:检查在多次循环时才能暴露的错误。

    4. m次循环:此时的m<n-1(通常取m=n/2),也是检查在多次循环时才能暴露的错误。

    5. n(最大)次数循环、n+1(比最大次数多一)次的循环、n-1(比最大次数少一)次的循环。

    嵌套循环

    1.从最内层循环开始,设置所有其他层的循环为最小值;

    2.对最内层循环使用简单循环的全部测试。测试时保持所有外层循环的循环变量(迭代参数)为最小值。另外,对越界值和非法值增加一些额外的测试。

    3.逐步外推,对其外面一层循环进行测试。测试时保持所有外层循环的循环变量取最小值,所有其它嵌套内层循环的循环变量取“典型”值。

    4.反复进行,直到所有各层循环测试完毕。

    5.对全部各层循环同时取最小循环次数,或者同时取最大循环次数。对于后一种测试,由于测试量太大,需人为指定最大循环次数。

    举例说明

    1 案例描述 

    昨天去面试,面试官出了一道面试题目,但是知道一个初步的优化,但不知道为什么会有性能提高,下去上网才恍然大悟:

    题目是这样的:请对以下的代码进行优化 

    Java代码  

    for (int i = 0; i < 1000; i++)  

        for (int j = 0; j < 100; j++)  

            for (int k = 0; k < 10; k++)  

                testFunction (i, j, k);  

    (注:为了同后面的内容一致,这里对原题目进行了部分修改) 
    2 案例分析 

    从给出的代码可知,不论如何优化,testFunction执行的次数都是相同的,该部分不存在优化的可能。那么,代码的优化只能从循环变量i、j、k的实例化、初始化、比较、自增等方面的耗时上进行分析。 
    首先,我们先分析原题代码循环变量在实例化、初始化、比较、自增等方面的耗时情况:

    变量

    实例化(次数)

    初始化(次数)

    比较(次数)

    自增(次数)

    i

    1

    1

    1000

    1000

    j

    1000

    1000

    1000 * 100

    1000 * 100

    k

    1000 * 100

    1000 * 100

    1000 * 100 * 10

    1000 * 100 * 10

    (注:由于单次耗时视不同机器配置而不同,上表相关耗时采用处理的次数进行说明) 
    该代码的性能优化就是尽可能减少循环变量i、j、k的实例化、初始化、比较、自增的次数,同时,不能引进其它可能的运算耗时。 
    3 解决过程 
    从案例分析,对于原题代码,我们提出有两种优化方案: 
    3.1 优化方案一 
    代码如下: 

    Java代码  

    for (int i = 0; i < 10; i++)  

        for (int j = 0; j < 100; j++)  

            for (int k = 0; k < 1000; k++)  

                testFunction (k, j, i);  

    该方案主要是将循环次数最少的放到外面,循环次数最多的放里面,这样可以最大程度的(注:3个不同次数的循环变量共有6种排列组合情况,此种组合为最优)减少相关循环变量的实例化次数、初始化次数、比较次数、自增次数,方案耗时情况如下: 

    变量

    实例化(次数)

    初始化(次数)

    比较(次数)

    自增(次数)

    i

    1

    1

    10

    10

    j

    10

    10

    10 * 100

    10 * 100

    k

    10 * 100

    10 * 100

    10 * 100 * 1000

    10 * 100 * 1000

    3.2 优化方案二 
    代码如下: 

    Java代码  

    int i, j, k;  

    for (i = 0; i < 10; i++)  

        for (j = 0; j < 100; j++)  

            for (k = 0; k < 1000; k++)  

                testFunction (k, j, i);  

    该方案在方案一的基础上,将循环变量的实例化放到循环外,这样可以进一步减少相关循环变量的实例化次数,方案耗时情况如下: 

    变量

    实例化(次数)

    初始化(次数)

    比较(次数)

    自增(次数)

    i

    1

    1

    10

    10

    j

    1

    10

    10 * 100

    10 * 100

    k

    1

    10 * 100

    10 * 100 * 1000

    10 * 100 * 1000

    4 解决结果 
    那么,提出的优化方案是否如我们分析的那样有了性能上的提升了呢?我们编写一些测试代码进行验证,数据更能说明我们的优化效果。 
    4.1 测试代码 

    Java代码  

    public static void testFunction(int i, int j, int k) {  

            System.out.print("");   // 注:该方法不影响整体优化,这里只有简单输出  

        }  

         public static void testA() {  

            long start = System.nanoTime();  

            for (int i = 0; i < 1000; i++)  

                for (int j = 0; j < 100; j++)  

                    for (int k = 0; k < 10; k++)  

                        testFunction(i, j, k);  

            System.out.println("testA time>>" + (System.nanoTime() - start));  

        }  

          public static void testB() {  

            long start = System.nanoTime();  

            for (int i = 0; i < 10; i++)  

                for (int j = 0; j < 100; j++)  

                    for (int k = 0; k < 1000; k++)  

                        testFunction(k, j, i);  

            System.out.println("testB time>>" + (System.nanoTime() - start));  

        }  

          public static void testC() {  

            long start = System.nanoTime();  

            int i;  

            int j;  

            int k;  

            for (i = 0; i < 10; i++)  

                for (j = 0; j < 100; j++)  

                    for (k = 0; k < 1000; k++)  

                        testFunction(k, j, i);  

            System.out.println("testC time>>" + (System.nanoTime() - start));  

    }  

    4.2 测试结果 
    1、测试机器配置:Pentium(R) Dual-Core CPU E5400 @2.70GHz 2.70GHz, 2GB内存; 
    2、循环变量i、j、k循环次数分别为10、100、1000,进行5组测试,测试结果如下: 

    第1组

    第2组

    第3组

    第4组

    第5组

    原方案

    171846271

    173250166

    173910870

    173199875

    173725328

    方案一

    168839312

    168466660

    168372616

    168310190

    168041251

    方案二

    168001838

    169141906

    168230655

    169421766

    168240748

    从上面的测试结果来看,优化后的方案明显性能优于原方案,达到了优化的效果。但优化方案二并没有如我们预期的优于方案一,其中第2、4、5组的数据更是比方案一差,怀疑可能是循环次数太少,以及测试环境相关因素影响下出现的结果。 
    3、重新调整循环变量i、j、k循环次数分别为20、200、2000,进行5组测试,测试结果如下: 

    第1组

    第2组

    第3组

    第4组

    第5组

    原方案

    1355397203

    1358978176

    1358128281

    1350193682

    1354786598

    方案一

    1343482704

    1348410388

    1343978037

    1347919156

    1340697793

    方案二

    1342427528

    1343897887

    1342662462

    1342124048

    1336266453

    从上面的测试结果来看,优化后的方案基本符合我们的预期结果。 
    5 总结 
    从案例分析和解决过程中的三个表的分析可知,优化方案一和优化方案二的性能都比原代码的性能好,其中优化方案二的性能是最好的。在嵌套For循环中,将循环次数多的循环放在内侧,循环次数少的循环放在外侧,其性能会提高;减少循环变量的实例化,其性能也会提高。从测试数据可知,对于两种优化方案,如果在循环次数较少的情况下,其运行效果区别不大;但在循环次数较多的情况下,其效果就比较明显了。

    串接循环

    对于串接循环,要区别两种情况。

    1.如果各个循环互相独立,则串接循环可以用与简单循环相同的方法进行测试。

    2.如果有两个循环处于串接状态,而前一个循环的循环变量的值是后一个循环的初值。则这几个循环不是互相独立的,则需要使用测试嵌套循环的办法来处理。

     

    对于非结构循环,不能测试, 应重新设计循环结构,使之成为其它循环方式,然后再进行测试。

    条件测试

    条件测试方法注重于测试程序中的条件。是检查程序模块中所包含逻辑条件的测试用例设计方法。

    条件

    程序中的条件分为简单条件和复合条件。

    简单条件是一个布尔变量或一个可能带有NOT(“!”)操作符的关系表达式。关系表达式的形式如:

    E1<关系操作符>E2

    其中E1和E2是算术表达式,而<关系操作符>是下列之一:“<”、“≤”、“=”、“≠”(“!=”)、“>”、或“≥”。

    复合条件由简单条件通过逻辑运算符(AND、OR、NOT)和括号连接而成,不含关系表达式的条件称为布尔表达式。

    所以条件的成分类型包括:布尔操作符、布尔变量、布尔括弧(括住简单或复杂条件)、关系操作符、算术表达式。

    条件测试的目的

    条件测试是测试程序条件错误和程序的其他错误。如果程序的测试集能够有效地检测程序中的条件错误,则该测试集可能也会有效地检测程序中的其他错误。此外,如果测试策略对检测条件错误有效,则它也可能有效地检测程序错误。

    条件测试策略

    1) 穷举测试(条件组合)

    有n个变量的布尔表达式需要2n个可能的测试(n>0)。这种策略可以发现布尔操作符、变量和括弧的错误,但是只有在n很小时实用。

    2) 分支测试

    分支测试可能是最简单的条件测试策略,它是真假分支必须至少执行一次的路径策略,对于复合条件C,C的真分支和假分支以及C中的每个简单条件都需要至少执行一次。

    域测试是对于大于、小于和等于的值的测试路径策略。域测试要求从有理表达式中导出三个或四个测试,有理表达式的形式如:

    E1<关系操作符>E2

    需要三个测试分别用于计算E1的值是大于、等于或小于E2的值。如果<关系操作符>错误,而E1和E2正确,则这三个测试能够发现关系算式的错误。为了发现E1和E2的错误,计算E1小于或大于E2的测试应使两个值间的差别尽可能小。

    3) BRO(branch and relational) 测试

    如果在一个判定的复合条件表达式中每个布尔变量和关系运算符最多只出现一次,而且没有公共变量,应用一种称之为BRO(分支与关系运算符)的测试法可以发现多个布尔运算符或关系运算符错,以及其他错误。

    BRO策略引入条件约束的概念。设有n个简单条件的复合条件C,其条件约束为D= (D1,D2,…,Dn) ,其中Di(0<i≤n)是条件C中第i个简单条件的输出约束。如果在C的执行过程中,其每个简单条件的输出都满足D中对应的约束,则称条件C的条件约束D由C的执行所覆盖。对于布尔变量或布尔表达式B,B的输出约束必须是真(t)或假(f);对于关系表达式,其输出约束为符号>、=、< 。

    域测试

     

     

    由于程序中每条路径对应着一个输入域,是程序的一个子计算。如果程序的控制流有错误,则对某一特定的输入可能执行的是一条错误路径,这种错误被称为路径错误或域错误。

    而域测试主要是针对域错误进行的测试。

    域测试的基本步骤如下:

    (1):根据各个分支谓词,给出子域的分割图;

    (2):对每个子域的边界,采用ON-OFF-ON原则选取测试点。

    (3):在子域内选取一些测试点。

    (4):针对这些测试点进行测试。

    符号测试

     

    Z路径覆盖测试

     

    实施步骤

    1.测试计划阶段:根据需求说明书,制定测试进度。

    2.测试设计阶段:依据程序设计说明书,按照一定规范化的方法进行软件结构划分和设计测试用例。

    3.测试执行阶段:输入测试用例,得到测试结果。

    4.测试总结阶段:对比测试的结果和代码的预期结果,分析错误原因,找到并解决错误。

    优缺点
    优点

    1.迫使测试人员去仔细思考软件的实现

    2.可以检测代码中的每条分支和路径

    3.揭示隐藏在代码中的错误

    4.对代码的测试比较彻底

    5.最优化

    缺点

    1.代价有些高,需要测试人员有编程能力

    2.无法检测代码中遗漏的路径和数据敏感性错误

    3.不能直接验证需求的正确性

    局限

    即使每条路径都测试了仍然可能有错误。可能出现的情况如下:

    穷举路径测试决不能查出程序违反了设计规范,即程序本身是个错误的程序。

    穷举路径测试不可能查出程序中因遗漏路径而出错。

    穷举路径测试可能发现不了一些与数据相关的错误。

    3.灰盒测试(Gray-Box Testing)

    灰盒测试是介于白盒测试和黑盒测试之间的一种,灰盒测试多用于集成测试阶段,不仅关注输入、输出的正确性,同时也关注程序内部的情况。灰盒测试不像白盒测试那样详细、完整,但又比黑盒测试更关注程序的内部逻辑,常常是通过一些表征性的现象、事件、标志来判断内部的运行状态。有时候输出是正确的,但内部其实已经错误了,这种情况非常多,如果每次都通过白盒测试来操作,效率会很低,因此需要采取这样的一种灰盒的方法。

    灰盒测试:功能+接口

    定义

    灰盒测试由方法和工具组成,这些方法和工具取材于应用程序的内部知识和与之交互的环境,能够用于黑盒测试以增强测试效率、错误发现和错误分析的效率。灰盒测试涉及输入和输出,但使用关于代码和程序操作等通常在测试人员视野之外的信息设计测试。

    目的

    一、确认软件的质量

    二、提供信息,提供给开发人员或程序经理的反馈信息,为风险评估所准备的信息。

    三、软件测试不仅是在测试软件产品的本身,而且还包括软件开发的过程。

    测试任务

    1、寻找Bug;

    2、避免软件开发过程中的缺陷;

    3、衡量软件的品质;

    4、关注用户的需求。

    如何做好灰盒测试?
    1. 测试定位要清晰。灰盒测试的对象应该是整个产品,而非各个组件,应从整个测试产品的业务出发进行测试设计。
    2. 测试阶段要正确。灰盒测试应该在集成测试中采用,他并不适合于单元测试。
    3. 测试辅助要必备。灰盒测试需要深入产品代码逻辑,对于测试人员来说,业务逻辑图是必不可少的,测试人员需要根据业务逻辑图进行功能点划分,并扩展用例。另外可以借助于测试覆盖率等工具辅助查找遗漏功能点。
    4. 运行状态检查点要仔细选择。灰盒测试对于程序运行状态的检查往往采用标志来判断,测试人员一定要仔细考虑,否则很容易遗漏某些bug。
    做灰盒测试需要哪些条件呢?

    1、需要在测试中,除了部署产品之外,还有就是程序源代码,不管外部是多少漂亮界面或易用的功能,最终都是由源代码来实现的。所以在部署时,要安装源代码。从源代码编译生成的目录中运行软件。
    2、需要代码覆盖率工具的配置;部署可以针对本软件开发语言的代码覆盖率工具;
    3、测试人员要具备阅读代码的能力,其对开发语言的熟悉程度和程序设计经验多少决定了采用灰盒测试能够取得多大的好处,所以配置这方面的测试人员或进行必要的培训是必要的。
    那么有人可能问,服务器端软件适合做灰盒测试吗?回答是肯定的。任何一个项目都可以从灰盒测试中获得裨益。不管是手机中使用的各种嵌入式软件、还是web页面和服务器端的任何脚本,都可以运用这种测试方法。

    优点

    1、 能够进行基于需求的覆盖测试和基于程序路径覆盖的测试;
    2、 测试结果可以对应到程序内部路径,便于bug的定位、分析和解决;
    3、 能够保证设计的黑盒测试用例的完整性,防止遗漏软件的一些不常用的功能或功能组合;
    4、 能够需求或设计不详细或不完整对测试造成的影响。

    缺点

    1、    投入的时间比黑盒测试大概多20-40%的时间;

    2、    对测试人员的技术要求更高;

    灰盒测试的好处

    测试者可能知道系统组件之间是如何互相作用的,但缺乏对内部程序功能和运作的详细了解。对于内部过程,灰盒测试把程序看作一个必须从外面进行分析的黑盒。灰盒测试通常与web服务应用一起使用,因为尽管应用程序复杂多变,并不断发展进步,因特网仍可以提供相对稳定的接口。由于不需要测试者接触源代码,因此灰盒测试不存在侵略性和偏见。开发者和测试者间有明显的区别,人事冲突的风险减到最小。

    灰盒测试相对于黑盒测试和白盒测试有什么特点?

    1.灰盒测试比白盒测试效率高,从程序的整体出发,而非细节.
    2.灰盒测试健壮性好,相对于白盒测试降低了程序代码改变而导致用例失效的风险。
    3.灰盒测试更细致。灰盒测试要求测试人员关注程序的代码逻辑,根据代码逻辑扩充用例,更加细致。

    按是否执行程序的角度划分

    1.静态测试(Static testing)

    定义

    静态方法是指不运行被测程序本身,而只是静态地检查程序代码、界面或文档中可能存在的错误的过程。仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性,对需求规格说明书、软件设计说明书、源程序做结构分析、流程图分析、符号执行来找错的过程。

    静态测试主要包括各阶段的评审(人工检查)、代码检查、静态结构分析、代码质量度量等,用于对被测程序进行特性分析。

    分析如下:

    检查项:代码风格和规则审核;程序设计和结构的审核;业务逻辑的审核;走查、审查与技术复审手册。

    静态质量:度量所依据的标准是ISO9126。在该标准中,软件的质量用以下几个方面来衡量,即功能性(Functionality)、可靠性(Reliability)、可用性(Usability)、有效性(Efficiency)、可维护性(Maintainability)、可移植性(Portability)。具体到静态测试,这里主要关注的是可维护性。要衡量软件的可维护性,可以从四个方面去度量,即可分析性(Analyzability)、可改变性(Changeability)、稳定性(Stability)以及可测试性(Testability)。具体到软件的可测试性怎么去衡量。又可以从三个度量元去考虑,例如圈复杂度、输入/输出的个数等。圈复杂度越大,说明代码中的路径越多;路径越多,意味着要去做测试,需要写更多的测试用例。输入/输出的个数同样的道理。

    为什么要进行静态测试?

    静态分析潜在收益是很高的: 在软件开发生命周期中,越是后来发现的缺陷,其去除成本呈指数上涨,所以缺陷越早发现越好。静态分析是所有测试中可以最先发现缺陷的方法,极大的降低了软件的修复成本。

    对软件经理,静态分析有助于:

    1) 减少部署后存在错误的风险,去除此时发现的错误是非常昂贵的;

    2) 缩短产品上市时间;

    3) 减少代码审查和测试的成本和时间;

    4) 自动化(部分)审查,没有或多个有限的人工检查;

    5) 消除明显的错误以便改善测试的速度和重点;

    6) 提高代码质量(坚持编码标准);

    7) 实现更高的覆盖率(更多的代码检查):与测试覆盖率相关但并不完全一样,因为重点不同。

    对软件开发人员,静态分析有助于:

    1) 提早找到/阻止错误(在错误变得很难处理之前):工具可用作开发周期的一部分,像编译器;更直接,明显的反馈。

    2) 发现/阻止“难以测试”的错误:例如,静态分析善于检测潜在的内存泄露和缓冲区溢出,从而使开发人员更高效,花费更少的时间调试。

    包括三个方面

    代码测试、界面测试和文档测试

      对于代码测试,主要测试代码是否符合相应的标准和规范。

     对于界面测试,主要测试软件的实际界面与需求中的说明是否相符。

     对于文档测试,主要测试用户手册和需求说明是否符合用户的实际需求。

    对界面和文档的静态测试相对容易,只要测试人员对用户需求仔细分析研究,就很容易发现界面和文档中的缺陷。对程序代码的静态测试相对复杂,需要按照相应语言的代码规范模板(无统一标准,各公司有自己的标准)来逐行检查程序代码。

    静态测试主要检查点:

     

    下面分别从代码、界面、文档三个方面进行详细说明每一部分应该如何进行测试。

    1) 界面测试:

     

     

     

    主要从联机功能、接口测试、报表测试和批量测试几个方面进行阐述。

    2) 文档测试

    主要是需求文档与实际设计和实现是否相符,可以根据界面测试中的点进行测试。

    3) 代码测试

    程序代码的静态测试要复杂得多,需要我们按照相应的代码规范模板来逐行检查程序代码。

    对代码的检查我们推荐使用现有的工具进行。那么我们从哪里获得这个规范模板呢?其实没有一个统一的标准,每个公司内部一般都有自己的编码规范,比如《c/c++编码规范》,你只需要按照上面的条目逐条测试就可以了。

     

    这段C语言编写的小程序,比较简单,实现的功能为:在主函数里输入两个单精度的数a和b,

    然后调用max子函数来求a和b中的大数,最后将大数输出。我们现在就对代码进行静态分析,主要根据一些C语言的基础知识来检查。

    我们把问题分为两种,一种必须修改的,另一种建议修改的。

    必须修改的问题有三个:

    1)程序没有注释。

    注释是程序中非常重要的组成部分,一般占到总行数的1/4左右。程序开发出来不仅是给程序员看,其他程序员和测试人员也要看。有了注释,别人就能很快地了解程序实现的功能。注释应该包含作者,版本号、创建日期等,以及主要功能模块的含义。

    2)子函数max没有返回值的类型。

    由于类型为单精度,我们可以在max()前面加一个float类型声明。

    3)精度丢失问题。

    大家注意“c=max(a,b)”语句,我们知道c的类型为整型int ,而max(a,b)的返回值z为单精度float, 将单精度的数赋值给一个整型的数,c语言的编译器会自动地进行类型转换,将小数部分去掉,比如z=2.5,赋给c则为2,最后输出的结果就不是a和b 中的大数,而是大数的整数部分。

    建议修改的问题也有三个;

    1)Main函数没有返回值类型和参数列表。

    虽然main函数没有返回值和参数,但是我们将其改为void main(void),来表明main函数的返回值和参数都为空,因为在有的白盒测试工具的编码规范中,如果不写void会认为是个错误。

    2)一行代码只定义一个变量。

    3)程序适当加些空行。空行不占内存,会使程序看起来更清晰。

    解释和说明一下静态测试技术

    静态测试不以测试数据的执行而是对测试对象的分析过程。 

    静态测试存在于软件生命周期的各级测试。如:需求分析、概要设计、详细设计及组件测试、集成测试和系统测试的阶段或层级。 

    静态测试的方法主要有人工(手工)评审与静态分析(人工或机器自动检测)两大类。通常可分别采用一种方法或混合使用两种方法。 

    静态测试中的评审(或审查)的基本思想和目标是对软件缺陷或错误的一种预防措施。因而软件技术文档的审查是静态测试的主要任务之一。

    静态测试的技术方法构成和说明:

     

    针对需求分析和概要设计进行的评审。评审在需求分析和概要分析阶段 建立的评审基础上开展,有人工评审和静态技术分析两个过程。 

    人工评审分为正式评审和非正式评审。正式评审是执行对被测对象(文档或程序)检查的活动及过程(也称为技术评审);非正式评审主要采用对文档或程序的走查活动及过程。如,对某一个具体程序的走查。走查通常采用单独或集体审阅的方式进行。

    静态测试内容及过程

    (1)静态测试内容 

    静态测试的内容包含:测试需求分析、测试概要分析、测试详细设计、测试执行与测试结果分析 

    (2)静态测试过程 

    进行测试需求分析:这是静态测试过程的首个阶段,将确定测试的需求,建立起测试基础与评审基础。 

    进行测试概要设计:在测试需求分析基础上,完成对测试方案的制定。如,测试内容、测试目标、测试策略、测试方法等。 

    进行测试详细设计:这个阶段主要完成测试进程中,各项具体任务安排和实施的细节考虑。如,测试用例设计等。 

    测试执行与结果分析:根据静态测试的计划进行静态测试执行的过程,各项测试任务的完成,并提交测试工作交付物。 

    静态测试的实施与执行 

    (1) 静态测试的实施 

    静态测试通常采用两种策略:人工静态分析和借用工具静态分析。 

    人工静态分析发挥人的智力和具有的逻辑思维优势,在分析过程中也常借助专用的静态测试分析工具来辅助。目前,实际工作中基本都是采用两种方法的混合模式,既充分发挥了发挥人的智慧,又运用了机器(工具)分析的高效便捷。

    (2) 静态分析的过程有别于编译过程 

    编译的功能是不能替代测试的。虽然编译系统也能检查软件(程序)中的错误,但其主要的作用是检查程序的语法等错误。这是因为编译系统并不具备软件测试的功能,并无针对性的去寻找特定的软件测试对象中的缺陷、错误的功效。

    而测试通常是要通过执行测试用例来实现的。同时,编译是无法检测到程序的逻辑错误或缺陷的。 

    (3) 代码检查 

    代码检查的内容主要包括:代码走查、桌面检查、代码审查等活动及过程。主要检查代码和设计的一致性,代码对标的遵循、可读性,代码的逻辑表达的正确性,代码结果的合理性等方面。

    代码检查的具体内容:变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等。

    代码检查的优点:是能快速找到软件缺陷或错误。测试业界实践表明,通过代码(通常是源代码)的走查过程,可检查到程序中 30-70%的程序逻辑设计及编码中的缺陷或者错误。代码检查在实际软件开发过程中被普遍采用,特别是针对组件(即单元)测试。

    代码检查的缺点:非常耗费时间,而且代码检查需要知识和经验的积累。 

    一般代码审查以下方面:

    1、 代码是否与设计一致,是否符合软件需求、概要和详细设计,这不仅可以看出代码问题,也可以反过来更早发现需求或设计是否正确。

    2、 代码书写的规范性和可读性。每个项目都有代码编写规范,如Java编写规范,C语言编写规范等。规范的代码包括清晰且充分的注释、漂亮的对齐、没有冗余、规范的命名等等。

    3、 代码逻辑是否正确,有没有死循环、内存泄露,异常处理是否充分,事务处理是否正确等等。

    4、 代码是否有安全漏洞、易被攻击。

    5、 代码文件组织目录是否合理,代码的结构是否合理

    6、 代码的重用性或复用性是高还是低

    7、 代码嵌套调用是否过多等等

    静态测试的结构分析方法 

    (1)以图形方式表现程序内部结构 

    静态结构分析主要以图形的方式来表达程序内部的结构关系。如,函数调用关系图,函数内部控制流图等。函数调用关系图是以直观的图形方式描述一个程序中各个函数的调用和被调用的关系; 函数内部控制流图以有向图来表达函数内部的程序控制逻辑。 

    (2) 以程序的控制流图显示程序函数的逻辑结构 

    程序的控制流图由多个节点和连接的边所构成。一个节点代表一条语句或数条语句,连接结点叫作边,边表示节点之间的控制流向。 

     

    (3)检查项 

    静态测试的检查项,主要有:代码风格和规则的审核;程序设计和结构的审核;业务逻辑的审核。 

    (4) 代码的质量度量 

    针对软件的可测试性、可读性(可维护性),通常有 3 种不同的代码质量度量 

    参数。 

     Line(行)复杂度。Line 复杂度是以代码的行数作为计算度量的基准。

     Halstead(运算符与运算元)复杂度。Halstead 复杂度是以程序中使用到的运算符与运算元数量作为计数目标(直测指标),据此来计算程序的容量和工作量。 

     McCabe(圈)复杂度。它是将程序流程图结构转化为有向图结构,以图形(有向图)为基础来衡量软件或程序的复杂度度量。 

    代码质量度量常常通过静态测试来获得,所以静态测试方法也称为静态分析,静态测试是对被测程序进行质量特性分析方法的总称。 

    (5)检查与规范、标准的一致性 

    通过静态测试工具可检查测试对象是否与应用的程序规范、标准的相一致,以检查软件程序是否遵循了大部分的编程规则与标准规范。以工具检查的优势是可快速并准确的帮助开发者与测试人员进行自动化检测过程,以发现被测对象与规范、标准的一致性。 

    2.动态测试(Dynamic testing)

    动态测试是指通过运行被测程序,输入相应的测试数据,检查实际输出结果与预期结果的差异,并分析运行效率、正确性、健壮性、性能等。

    (1)动态测试有三部分组成:构造测试用例、执行程序、分析程序的输出结果。

    (2)大多数软件测试都属于动态测试。所谓软件的动态测试,就是通过运行软件来检验软件的动态行为和运行结果的正确性。目前,动态测试也是公司的测试工作的主要方式。

    是否查看代码角度和是否执行程序角度的关系

    黑盒测试有可能是动态测试(运行程序,只看输入和输出),也有可能是静态测试(不运行程序,只是查看界面)

    白盒测试有可能是动态测试(运行程序,并分析代码结构),也有可能是静态测试(不运行程序,只是静态查看代码)

    动态测试有可能是黑盒测试(运行程序,只看输入和输出),也有可能是白盒测试(运行程序,并分析代码结构)

    静态测试有可能是黑盒测试(不运行程序,只是查看界面),也有可能是白盒测试(不运行程序,只是静态查看代码)

    按测试对象的角度划分

    性能测试

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

    中国软件评测中心将性能测试概括为三个方面:应用在客户端性能的测试、应用在网络上性能的测试和应用在服务器端性能的测试。通常情况下,三方面有效、合理的结合,可以达到对系统性能全面的分析和瓶颈的预测。

    定义

    狭义的性能测试主要用于描述常规的性能测试,是指通过模拟生产运行的业务压力或用户使用场景来测试系统的性能是否满足生产性能的要求。
    广义的性能测试则是压力测试、负载测试、强度测试、并发(用户)测试、大数据量测试、配置测试、可靠性测试等和性能相关的测试统称。

    基本策略

    测试的基本策略是自动负载测试,通过在一台或几台PC机上模拟成百或上千的虚拟用户同时执行业务的情景,对应用程序进行测试,同时记录下每一事务处理的时间、中间件服务器峰值数据、数据库状态等。通过可重复的、真实的测试能够彻底地度量应用的可扩展性和性能,确定问题所在以及优化系统性能。预先知道了系统的承受力,就为最终用户规划整个运行环境的配置提供了有力的依据。

    目的

    目的是验证软件系统是否能够达到用户提出的性能指标,同时发现软件系统中存在的性能瓶颈,以优化软件,最后起到优化系统的目的。

    包括以下几个方面:

    1.评估系统的能力,测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策。

    2.识别体系中的弱点:受控的负荷可以被增加到一个极端的水平,并突破它,从而修复体系的瓶颈或薄弱的地方。

    3.系统调优:重复运行测试,验证调整系统的活动得到了预期的结果,从而改进性能。

    4. 检测软件中的问题:长时间的测试执行可导致程序发生由于内存泄露引起的失败,揭示程序中的隐含的问题或冲突。

    5.验证稳定性(resilience)、可靠性(reliability):在一个生产负荷下执行测试一定的时间是评估系统稳定性和可靠性是否满足要求的唯一方法。

    类型

    性能测试类型包括负载测试,压力测试,容量测试,稳定性测试等。

     

    负载测试(Load Testing)

    定义

    负载测试是一种主要为了测试软件系统是否达到需求文档设计的目标,譬如软件在一定时期内,最大支持多少并发用户数,软件请求出错率等,测试的主要是软件系统的性能。

    负载测试是不断增加系统的负载,直到负载达到阈值——评估系统在预期工作负载下的性能的测试。这里增加负载的意思是在测试中增加并发用户数量、用户交互等,通常是在可控的环境下进行。典型的负载测试包括在负载测试过程中确定响应时间,吞吐量,误码率等。该方法可以找到系统的性能极限,可以为性能调优提供相关数据。该类方法通常要基于或模拟系统真实运行环境,且选取的业务场景也要尽可能地与实际情况相符。

    狭义的定义:是指对系统不断地增加压力或增加一定压力下的持续时间,直到系统的某项或多项性能指标达到安全临界值,例如某种资源已经达到饱和状态等。运用场景:此类型的测试目前运用得比较少。一般情况下,是以服务器资源安全临界值为界限的测试。如果要模拟某个应用在指定服务器上最大且安全的负载量,则属于负载测试。

    目标

    确定并确保系统在超出最大预期工作量的情况下仍能正常运行。此外,负载测试还要评估性能特征。例如,响应时间、事务处理速率和其他与时间相关的方面。

    负载测试的目标是测试在一定负载情况下系统性能(不关注稳定性,也就是说不关注长时间运行,只是得到不同负载下相关性能指标即可);实际中我们常从比较小的负载开始,逐渐增加模拟用户的数量(增加负载), 观察不同负载下应用程序响应时间、所耗资源,直到超时或关键资源耗尽,这就是所说的负载测试,它是测试系统的不同负载情况下的性能指标。

    目的

    负载测试是为了发现系统的性能问题,负载测试需要通过系统性能特性或行为来发现问题,从而为性能改进提供帮助,从这个意义看,负载测试可以看作性能测试的一部分。但它们两者的目的是不一样的,负载测试是为了发现缺陷,而性能测试是为了获取性能指标。因为性能测试过程中,也可以不调整负载,而是在同样负载情况下改变系统的结构、改变算法、改变硬件配置等等来得到性能指标数据,从这个意义看,负载测试可以看作是性能测试所用的一种技术,即性能测试使用负载测试的技术、使用负载测试的工具。性能测试要获得在不同的负载情况下的性能指标数据。

    通过负载测试和压力测试都可以获得系统正常工作时的极限负载或最大容量。容量测试,自然也是采用负载测试技术来实现,而在破坏性的压力测试中,容量的确可以看作是一种副产品——间接结果。

    负载测试的必要准备

    1.什么是你真正需要了解的?

    2.确定用户数量

    3.研究你的分析

    4.组建你的团队

    5.准备你的浏览器

    6.准备测试你的应用

    7.预留时间分析结果

    8.预留时间修改

    9.计划一个敏捷测试方法

    压力测试(Stress Testing)

    定义

    压力测试是在强负载(大数据量、大量并发用户等)下的测试,查看应用系统在峰值使用情况下操作行为,从而有效地发现系统的某项功能隐患、系统是否具有良好的容错能力和可恢复能力。压力测试分为高负载下的长时间(如24小时以上)的稳定性压力测试和极限负载情况下导致系统崩溃的破坏性压力测试。

    压力测试可以被看作是负载测试的一种,即高负载下的负载测试,或者说压力测试采用负载测试技术。通过压力测试,可以更快地发现内存泄漏问题,还可以更快地发现影响系统稳定性的问题。例如,在正常负载情况下,某些功能不能正常使用或系统出错的概率比较低,可能一个月只出现一次,但在高负载(压力测试)下,可能一天就出现,从而发现有缺陷的功能或其它系统问题。通过负载测试,可以证明这一点,某个电子商务网站的订单提交功能,在10个并发用户时错误率是零,在50个并发用户时错误率是1%,而在200个并发用户时错误率是20%。

    狭义的定义:压力测试是指超过安全负载的情况下,对系统不断施加压力,是通过确定一个系统的瓶颈或不能接收用户请求的性能点,来获得系统能提供的最大服务级别的测试。运用场景:此类型的测试目前运用得比较少。但对于大型的共享中心或者核心的应用也会用到。

    目标

    压力测试的目标是测试在一定的负载下系统长时间运行的稳定性,尤其关注大业务量情况下长时间运行系统性能的变化(例如是否反应变慢、是否会内存泄漏导致系统逐渐崩溃、是否能恢复);压力测试是测试系统的限制和故障恢复能力,它包括两种情况:
    稳定性压力测试:在选定的压力值下,长时间持续运行。通过这类压力测试,可以考察各项性能指标是否在指定范围内,有无内存泄漏、有无功能性故障等;
    破坏性压力测试:在稳定性压力测试中可能会出现一些问题,如系统性能明显降低,但很难暴露出其真实的原因。通过破坏性不断加压的手段,往往能快速造成系统的崩溃或让问题明显的暴露出来。

    目的

    压力测试主要是为了发现在一(任意)定条件下软件系统的性能的变化情况,通过改变应用程序的输入以对应用程序施加越来越大的负载(并发,循环操作,多用户) 并测量在这些不同的输入时性能的改变,也就是通常说的概念:压力测试考察当前软硬件环境下系统所能承受的最大负荷并帮助找出系统瓶颈所在。其实这种测试也 可以称为负载测试,但是负载测试通常描述一种特定类型的压力测试——增加用户数量以对应用程序进行压力测试。比如实际中我们说从比较小的负载开始,逐渐增加模拟用户的数量, 直到应用程序响应时间超时,就是说的负载测试。

    压力测试主要是为了测试硬件系统是否达到需求文档设计的性能目标,譬如在一定时期内,系统的cpu利用率,内存使用率,磁盘I/O吞吐率,网络吞吐量等,压力测试和负载测试最大的差别在于测试目的不同。压力测试是指当硬件资源如cpu、内存、磁盘空间等不充足时对软件稳定性的检查。压力测试属于负面测试(Negative testing),使大量并发用户/进程加载软件以使系统硬件资源不能应付,这个测试也被称为是疲劳测试(Fatigue testing),通过超出其能力的测试来捕获应用程序的稳定性。压力测试的主要思想是确定系统故障,关注系统如何优雅地恢复正常,这种质量被称为是可恢复性。

    负面测试(Negative testing)是相对于正面测试(Positive testing)而言的。正面测试就是测试系统是否完成了它应该完成的功能;而负面测试就是测试系统是否不执行它不应该完成的操作。

    配置测试

    同功能测试一样,如果需求规格说明中有明确的性能需求,例如完成复杂运算处理的解算时间要求,解算精度要求,网络传输吞吐量,数据库的最大容量,服务器能允许的同时在线访问数量等等,都要反映在配置项测试里。如果没有明确指出性能要求,测试人员可根据软件产品所处行业,自行产生测试需求。——这很考验测试人员的素质和水平的哦。例如前面所提到的,服务器能允许的最大同时在线访问量,就是互联网行业的一个性能需求。当然,还有常规的空间性能(存储和占用计算机硬件资源)和时间性能(软件处理一个任务所用时间),如今的计算机资源,基本都满足要求,除非你是航空发射,武器控制等特殊行业,才需要非常关注

    配置测试主要指通过测试找到系统各项资源的最优分配原则。配置测试是系统调优的重要依据。例如,可以通过不停地调整 Oracle 的内存参数来进行测试,使之达到一个较好的性能。可以看出,配置测试本质上是前面提到的某些种类的性能测试组合在一起而进行的测试。

     

    并发测试

    定义

       所谓并发,它的特点是“并行”和“同时”。

       测试多个用户同时访问同一个应用、同一个模块或者数据记录时是否存在死锁或者其他性能问题,几乎所有的性能测试都会涉及一些并发测试。通常的测试方法是设置集合点。

    目的

    测试目的并非为了获得性能指标,而是为了发现并发引起的问题。

    并发概念的浅谈

    想确定用户并发数;必须知道系统所承载的在线用户数;

    对于并发,我过去接触了几种理解,在接触的第一种理解中,“并发”是由loadrunner中获取,即脚本中所有或部分vuser执行至集合点函数时进行停留,等待触发条件发生以后,同时执行集合点函数后的请求操作的这一个过程,为“并发”(这一个请求操作一般存在多个http请求),可惜这种“并发”是无法直接用于衡量系统性能的。

    LoadRuner的并发很好理解,就是虚拟用户数。因为LR有个集合点,可以在所有虚拟用户初始化且到达集合点后,再一起执行后续操作,从而达到同时且并行的效果。

    而在接触的第二种理解中,“并发”的理解是相对于服务器某一个时间区间内接收的请求数,也就是每秒的点击率(loadrunner考虑到这点,也就是analysis里面的hits/s),为“并发”,这种“并发”是可以用于对系统性能状况进行量化的,但是这种测试思想只是比较片面的从性能指标的角度去衡量系统性能,不能体现出系统性能带给用户何种性能体验(这也是不少开源性能测试工具的问题)。

    前一种“并发”的理解普遍获得了loadrunner初级用户的认可,后一种“并发”的理解普遍获得系统运维、开发人员的认可,在沟通中为了方便区别开来,在两种角色里面,当大家意识到并发的理解存在差异时,大家把前一种被称为“狭义上的并发”,而后一种被称为“广义上的并发”。后来,又从淘宝团队里面了解了一种定义,貌似淘宝QA把“并发”定义为一个完整的事务请求数量过程(loadrunner也考虑到这点,也就是analysis里面的Transactions per Second)。一直以来,还有一种技术范围以外对“并发”的粗略的理解被第三方测试拿来用了,那就是用户在线数中的某个百分比即并发数。

    如果一个团队里面对“并发”的理解有这么多种,那么当我们在讨论性能需求的“支持并发数”时,我们究竟在讨论什么呢?

    个人认为,有一部分的原因是由于loadrunner是惠普saas(软件即服务的解决方案)的一部分,所以并不是一个纯粹技术人员使用的测试工具,它同时也是一个业务人员可以相对轻易掌握的性能测试工具,因此loadrunner内很多名词解释也不能单纯从技术人员的角度从字面意义上理解。

    通常来说,面对同样100笔业务交易量,普遍会认为100vuser对服务器产生的负载会比50vuser要高,但是在性能脚本能够在较快的响应时间中完成时,由于50vuser执行过程中每一个vuser都需要发生两次迭代,导致了性能场景中vuser在脚本action部分停留的时间更长,因此反而能够得到比100vuser的更高的vuser在线数,更高在线数带来的也就是更大的负载,也就是说:

    同等业务量的情况下,50线程所产生的负载完全有可能比100线程所产生的负载要高。

    为了避免发生这种问题,“并发(集合点)”的真正作用就体现出来了,通过集合点函数控制了vuser的行为相对一致,降低了初始化过程和事务前后文请求产生的时间差影响。测试工具中并发存在的真正意义也就在这里,对集合点所理解的“并发”,和现场实际用户里面同时触发的请求关系不是太大。

    分析并发需求时的一些典型:

    a)     某个业务系统里面有10000用户,但是能够访问这个系统的终端数只有1000个、或者所需测试的业务每个月上限是1000笔,那么最高在线用户数就不可能超过1000、业务量也不可能超过1000。所以,有些时候在分析性能需求的时候,去统计一个业务系统的用户数还不如去统计能够访问这个系统的终端数、甚至业务量靠谱。

    b)     某个业务系统里面,各个业务模块都不一样,那么就是说完成一笔业务交易,所产生的请求数也是不一样的,例如表单新增,有的需要填写20个字段,有的只需要填写5个字段,各个表单都不一样,那么为了更接近的去模拟用户现场负载,请求数都不一样的各种业务混在一起,并发数又应该是多少呢?

    为了解决这些问题,需要首先考虑并发的粒度,以真实的业务场景为例:

    a)     把粒度控制在用户上来看,假定所有用户访问一次系统平均耗时500秒,一个业务峰值会有800用户在线,则800/500=1.6。理论上,系统的性能需求是每秒要成功处理1.6个用户的请求;

    b)     把粒度控制在事务上来看,假定所有用户执行一次完整的、成功的业务操作平均需要500秒,一个业务峰值有2000笔所关注的业务需要去执行,则2000/500=4。理论上,系统的性能需求是每秒要成功处理4笔业务交易;

    c)      把粒度控制在请求上来看,假定所有用户执行一次完整的、不管成功或者失败的HTTP请求操作平均需要0.08秒,一个业务峰值有28000个请求需要去完成,则28000/0.08=350000。理论上,系统的性能需求是每秒要成功处理350000个请求。

    分类

    1、独立业务性能测试:核心业务模块的某一业务并发性能测试; 

    2、组合业务性能测试:一个或多个模块的多个业务同时进行并发测试。

     

    独立业务性能测试

    1、完全一样功能的并发测试:检查程序对同一时刻并发操作的处理,例如模拟多个用户在

    同一时刻向数据库写入相同数据,或者多个用户在同一时刻发出请求测试系统能否正确响应。

    2、完全一样操作的并发测试:在同一时刻完成完全一样的操作,即从宏观上看操作对系统

    的影响是一致的,例如同时单击保存按钮。这类测试目的在于验证大量用户使用同一功能时系统能否正常工作。

    3、相同/不同的子功能并发测试:同一模块大多数功能相互耦合,针对一些子功能较多的

    模块做组合测试。组合的依据就是用户使用的场景,每个不同的子功能都模拟一定的用户数量进行并发测试。

    组合业务性能测试

    1、不同核心业务模块的用户进行并发,模块之间具有一定耦合:这种测试比较接近用户使

    用情况,测试的对象是多个模块组,每个组相关的模块之间具有一定耦合关系。组与组之间的关系相对独立。例如实际中各类型的用户都会对应一组模块,相当于不同的业务组并发的访问系统。

    2、具有耦合关系的核心模块组进行并发,每组模块内部存在耦合关系:主要测试多用户并发条件下一些存在耦合或者数据接口的模块是否正常运行,可以参考集成测试用例和概要设计文档,分析出一些核心模块的接口。

    3、基于用户场景的并发测试:选择用户的一些经典场景做测试,测试对象可以使核心模块,也可以是非核心模块。这种测试更接近用户使用的实际情况,测试需要充分考虑实际场景。设计组合模块用户并发性测试用例一般用不同“子功能”或者“子事务”为单位,来进行各种模块的不同核心功能组合。

    并发用户数量设计方法

     

    容量测试(Volume Testing)

    定义

        所谓容量,即系统处于最大负载状态或某项指标达到所能接受的最大阈值下对请求的最大处理能力。

    容量测试是一种非功能的测试,它通过向应用程序中添加大量的数据来实现检查被测系统处理大数据量的能力。

    可以通过向数据库插入大量的数据或让应用程序处理一个大型文件来进行测试应用程序。通过容量测试,可以识别应用程序中具有大数据时的瓶颈,检查应用程序的效率,进而得到不同数据量级下应用程序的性能。确定系统最大承受量,譬如系统最大用户数,最大存储量,最多处理的数据流量等。

     

    举例:
    在一个新开发的网络游戏应用程序中,在进行容量测试时,可以通过向数据库中插入数百万行的数据,然后在这些数据的基础上进行性能的测试。
    注意,这里所说的数据一定是符合其功能场景的,不是毫无关系的数据。

    目的

    容量测试的目的是通过测试预先分析出反映软件系统应用特征的某项指标的极限值(如最大并发用户数、数据库记录数等),系统在其极限状态下没有出现任何软件故障或还能保持主要功能正常运行。容量测试还将确定测试对象在给定时间内能够持续处理的最大负载或工作量。软件容量的测试能让软件开发商或用户了解该软件系统的承载能力或提供服务的能力,如某个电子商务网站所能承受的、同时进行交易或结算的在线用户数。知道了系统的实际容量,如是不能满足设计要求,就应该寻求新的技术解决方案,以提高系统的容量。有了对软件负载的准确预测,不仅能对软件系统在实际使用中的性能状况充满信心,同时也可以帮助用户经济地规划应用系统,优化系统的部署。

    如何统计容量指标?

    统计维度

    一般来说,可以从如下两个维度来定量系统的容量:

     

    统计方法

    一般来说,常用的采集数据的方法,有以下几种方式:

    ①、埋点采集:即在系统的各个节点,根据需要添加埋点,针对性的进行数据采集;

    ②、日志/数据库:通过日志服务(比如ELK)或者运维监控(现在很流行的Devops),采集分析数据;

    ③、Agent/探针:在需要采集的节点添加Agent/探针,实时采集,数据存入时序数据库(比如influxdb),实时展示;

    注意事项

    ①、采集对比的数据一定要采集线上的真实数据,这样才能反映真实客观的系统压力。

    ②、容量测试环境的配置,一定要和线上保持一致(服务器数量可以不同,但配置尽可能保持一致)。

    测试思路

    ①、根据具体的业务情况和系统架构,通过配置测试的手段,测量得到单个服务节点在对应的业务场景下最大的性能表现;

    ②、根据系统架构(集群、分布式、微服务)特点,通过启用≥2的服务节点,来得到服务节点的增加和系统性能的提升比例;

    ③、通过线上采集的系统数据,分析出过去某段时间(或某个业务)的高峰流量,然后通过计算,得到容量扩容,需要投入的实际服务数量;

    约束/停止条件

    在测试过程中,只要限定的某项指标达到最大可接受阈值或某项资源达到最大使用状态,即刻停止测试。

    选择合适的容量指标

    考虑到业务需求和系统架构的不同,在选取容量指标时一般遵循如下原则:

    ①、数据密集型:即并发请求量较大的类型,一般TPS和RT是比较关注的指标;

    ②、数据存储型:即需要存储读写的数据量较大的类型,一般吞吐量和IO是比较关注的指标;

    容量规划

    为什么需要容量规划?

    对于业务越来越复杂的商业形态,每个业务都由一系列不同的系统来提供服务,每个业务系统都部署在不同的机器上。容量规划的目的在于让每一个业务系统能够清晰地知道:

    ①、什么时候应该增加服务节点,什么时候应该减少服务节点(比如服务端接受到的流量达到什么量级)?(比如双十一,大促,秒杀)

    ②、为了双 11 、促销、秒杀、渠道拓展引流等业务需求,需要扩充到什么数量级的服务,才能即保证系统的可用性、稳定性,又能节约成本?

    容量规划四步走

    ①、业务流量预估阶段:通过分析历史数据以及实时的线上监控,预估未来某个时间点或者某个业务可能会有多少多少的流量冲击;

    ②、系统容量评估阶段:根据具体的业务场景,分析每个业务场景的流量配比,然后计算每个业务大概需要多少服务节点来提供可靠稳定的性能支撑;

    ③、系统容量测试阶段:通过全链路压测或者PAT/UAT环境的压测,来模拟真实的业务场景,确定每个服务节点的具体性能表现,进行针对性的调整;

    ④、流量分配调整阶段:根据压测的结果,设定限流、服务降级等系统保护措施,来预防当实际流量超过系统所能承受的最大流量时,系统无法提供服务;

    扩容手段

    ①、垂直扩容

    升级服务的硬件配置,让单个服务节点的容量更大,来提供更高的系统服务能力。比如:

    加大服务机器的CPU数量和内存,更换性能更好的高速缓存服务器,数据存储用NAS盘替换等。

    ②、水平扩展

    即增加服务节点的数量,让可提供服务的服务变得更多,来提升系统总体的服务能力。常见的方式有:

    服务集群:服务器的数量由1→N(但需要重点关注负载均衡);

    分布式:提供服务的节点由统一集中管理部署,分散到不同的地点;

    容器:提供更灵活的弹性扩容机制,根据具体的访问流量大小来弹性扩容或者缩容;

    容量测试的优点

    以下是任何软件应用程序的容量或洪水测试的优点。

    • 它提供了运行软件应用程序所需的硬件类型的清晰图像,包括CPU、内存等。
    • 可以很早地确定可扩展性计划。
    • 它有助于节省可能用于应急计划的大量资金。
    • 它有助于尽早发现应用程序操作中的瓶颈。
    • 它确保了经过容量测试的应用程序已准备好投入实际使用。
    • 它有助于让应用程序上线或不上线。

    容量测试的缺点

    此类测试增加了项目的额外成本,因为它是由不同的性能测试团队在功能测试的基础上完成的。

    为什么经常推荐容量测试?

    由于以下原因,通常建议进行容量测试。

    • 当到数据库中的数据量增加时,它有助于检查系统性能。
    • 使用大量数据研究软件应用程序行为。
    • 评估应用程序稳定性开始降低的点。
    • 它可以识别正常,低,中,高容量下的应用能力。

    容量测试检查

    在容量或洪水测试期间评估和检查以下参数。

    • 容量测试旨在检查是否有任何数据丢失。
    • 进行容量测试以记录不同容量条件下的响应时间并评估平均响应时间。
    • 它旨在评估数据库中的数据是否正确保存。
    • 它旨在验证数据是否被任何通知覆盖。
    • 它旨在检查警告和错误消息,以及它们在不同容量级别的关联。
    • 它旨在检查高数据量是否会以任何方式影响被测系统中处理请求的速度。

    容量测试最佳实践

    以下是最佳容量测试结果广泛遵循的最佳实践。

    • 在检查所有日志 (即服务器和应用程序的日志) 时, 不要忘记停止所有服务器。
    • 在开始容量测试之前,确保正面(正常)场景正常工作。
    • 为了从容量测试中获得最佳结果,始终建议错开用户数量。
    • 平衡你的容量试时间以克服许可限制。
    • 引入的任何新版本都应该非常谨慎地处理。
    • 建立基线后,应分析用例以提高性能。
    • 在出现性能瓶颈的情况下,应该反复重复进行容量测试,以深入研究性能问题。
    可靠性测试

    定义

    软件可靠性测试是指为了保证和验证软件的可靠性要求而对软件进行的测试。其采用的是按照软件运行剖面(对软件实际使用情况的统计规律的描述)对软件进行随机测试的测试方法。

    软件可靠性是软件系统在规定的时间内以及规定的环境条件下,完成规定功能的能力。一般情况下,只能通过对软件系统进行测试来度量其可靠性。

    对软件可靠性进行定量的评估或验证,为了达到和验证软件的可靠性定量要求而对软件进行的测试。

    软件可靠性测试通常是在系统测试、验收、交付阶段进行,它主要是在实验室内仿真环境下进行,也可以根据需要和可能在用户现场进行。

    在给系统加载一定业务压力的情况下,使系统运行一段时间,以此检测系统是否稳定。例如,可以施加让 CPU 资源保持 70%~90%使用率的压力,连续对系统加压 8 个小时,然后根据结果分析系统是否稳定。这么多类型的性能测试看起来很吓人,实际上它们大多是密切相关的。例如,运行 8 个小时来测试系统是否可靠,而这个测试极有可能包含了可靠性测试、强度测试、并发(用户)测试、负载测试,等等。

    特点

     

    测试的目的

    (1)通过在有使用代表性的环境中执行软件,以证实软件需求是否正确实现。

    (2)为进行软件可靠性估计采集准确的数据,预测软件在实际运行中的可靠性。

    估计软件可靠性一般可分为四个步骤,即数据采集、模型选择、模型拟合以及软件可靠性评估。可以认为,数据采集是整个软件可靠性估计工作的基础,数据的准确与否关系到软件可靠性评估的准确度。

    (3)通过软件可靠性测试找出所有对软件可靠性影响较大的错误。

    (4)通过测试可以提高整个软件系统的防错、容错和纠错的能力。

    通过软件可靠性测试可以达到以下目的:

    (1) 有效地发现程序中影响软件可靠性的缺陷,从而实现可靠性增长:软件可靠性是指“在规定的时间内,规定的条件下,软件不引起系统失效的能力,其概率度量称为软件可靠度。”

    软件的“规定的条件”主要包括相对不变的条件和相对变化的条件,相对不变的条件如计算机及其操作系统;相对变化的条件是指输入的分布,用软件的运行剖面来描述。认为按照软件的运行剖面对软件进行测试一般先暴露在使用中发生概率高的缺陷,然后是发生概率低的缺陷。而高发生概率的缺陷是影响产品可靠性的主要缺陷,通过排除这些缺陷可以有效地实现软件可靠性的增长。

    (2) 验证软件可靠性满足一定的要求:通过对软件可靠性测试中观测到的失效情况进行分析,可以验证软件可靠性的定量要求是否得到满足。

    (3) 估计、预计软件可靠性水平

    通过对软件可靠性测试中观测到的失效数据进行分析,可以评估当前软件可靠性的水平,预测未来可能达到的水平,从而为开发管理提供决策依据。软件可靠性测试中暴露的缺陷既可以是影响功能需求的缺陷也可以是影响性能需求的缺陷。软件可靠性测试方法从概念上讲是一种黑盒测试方法,因为它是面向需求、面向使用的测试,它不需要了解程序的结构以及如何实现等问题。

    分析方法

    目前主要的软件可靠性分析方法有失效模式影响分析法、严酷性分析法、故障树分析法、事件树分析法、潜在线路分析法。

    测试过程

    包括五个步骤:确定可靠性目标,定义软件运行剖面,设计测试用例,实施可靠性测试,分析测试结果。

    失败恢复性测试

      对于有冗余备份和负载均衡的系统,通过这样的测试来检验如果系统局部发生故障用户是否能够继续使用系统,用户收到多大的影响。

     

    强度测试

    强度测试是一种性能测试,它在系统资源特别低的情况下软件系统运行情况,目的是找到系统在哪里失效以及如何失效的地方。 

    强度测试主要是为了检查程序对异常情况的抵抗能力。强度测试总是迫使系统在异常的资源配置下运行。例如:
      当正常的用户点击率为“1000 次/秒”时,运行点击率为“2000 次/秒”的测试用例;
      运行需要最大存储空间(或其他资源)的测试用例;
      运行可能导致操作系统崩溃或磁盘数据剧烈抖动的测试用例,等等。
    强度测试是一种特别重要的测试,对测试系统的稳定性,以及系统未来的扩展空间均具有重要的意义。在这种异常条件下进行的测试,更容易发现系统是否稳定以及性能方面是否
    容易扩展。

    疲劳测试

    疲劳测试是采用系统稳定运行情况下能够支持的最大并发用户数,持续执行一段时间业务,通过综合分析交易执行指标和资源监控指标来确定系统处理最大工作量强度性能的过程。是一类特殊的强度测试,主要测试系统长时间运行后的性能表现,例如 7× 24 小时的压力测试。

    尖峰测试(Spike testing)

    尖峰测试(Spike testing)其实可以算作是压力测试(Stress Testing)的子集。

    尖峰测试是在目标系统经受短时间内反复增加工作负载,以至超出预期生产操作的负载量时,分析系统的行为,验证其性能特征。它还包括检查应用程序是否可以从突然增加的超预期负荷中恢复出来的测试。
    举例:在电商应用程序中经常有“整点秒杀”的活动,所以在整点时间前后的两三分钟时间里,会有巨大数量的用户进入到该活动中秒杀商品。尖峰测试就是为了分析这类场景。

    持久测试(Endurance testing)

    持久测试(Endurance testing),也被称为是浸泡测试(Soak Testing),它也是一种非功能的测试。
    持久测试是指在相当长的时间内使用预期的负载量对系统进行测试,以检查系统的各种行为,如内存泄露、系统错误、随机行为等。
    这里的提到的相当长的时间是相对而言的,举例来说,如果一个系统设计为运行3个小时的时间,那可以使用6个小时的时间来进行持久测试;如果设计为5个小时的时间,不妨用10个小时的时间来进行持久测试。对于现在的许多网络类应用程序,通常情况下会持续运行好多天,那么进行持久测试时可以选择更长的时间段。

    稳定性测试

    狭义的定义:稳定性测试是指被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定,一般稳定性测试时间为 n*12 小时。

    运用场景:此类型的测试目前也最常见,针对需要长时间稳定运行的性能点,需要执行稳定性测试。往往在一个项目的性能测试过程中,会划分出优先级较高的性能点,做稳定性测试。例如:宝贝详情页面等等。

    如何实施

    识别并确认软件主要业务(是否需要稳定性测试)

    将稳定性测试的重心放在软件最有Value的地方,比如说一个抢票系统,它最有value的地方是当有一定数量的用户同时进行买票操作是系统的响应时间,资源利用率等是否能够正常且稳定,而不是用户如何添加新的联系人,修改个人信息等。

    罗列主要用户场景及响应负载量

    用户场景可以根据软件主要业务进行设定

    对主要场景负载量需要有一个清晰的定义(或者通过负载测试验证了用户场景的负载量,这将作为一个标准的负载在稳定性测试中使用)

    制定稳定性指标模型(Modeling)

    根据用户场景建模,创建合适合理的稳定性指标模型(之后会有一个例子)

    测试环境准备(对软硬件环境的配置:配置的来源可以是客户环境模拟、需求文档规定的配置或者配置测试得出的最佳配置)

    识别稳定性的主要性能指标(KPI)

    用来描述稳定性测试关注的系统指标,比如响应时间、CPU、内存使用率等等,需要根据具体业务进行定义  

    测试的执行和数据收集

    按照相应稳定性指标模型(Modeling)分析测试结果

    将测试结果应用在稳定性测试模型中,观察是否满足稳定性要求

    持续改进(如有必要)

    大数据量测试

    主要针对数据库有特殊要求的系统进行的测试,如电信业务系统的手机短信业务;可以分为实时大数据量,主要目的是测试用户较多或者某些业务产生较大数据量时,系统能否稳定运行;极限状态下的测试,测试系统使用一段时间即系统累计一点量的数据时能否正常的运行业务;前面两种的结合,测试系统已经累计了较大数据量时,一些实时产生较大数据量的模块能否稳定工作;

    如下大数量测试用例:
      功能:数据库中的短信息表可以保存所有不能及时发送的短信息,用户上线后又能及时发送已经保存的信息;

    大数据量测试可以分为两种类型:针对某些系统存储、传输、统计、查询等业务进行大数据量的独立数据量测试;与压力性能测试、负载性能测试、疲劳性能测试相结合的综合数据量测试方案。大数据量测试的关键是测试数据的准备,可以依靠工具准备测试数据。

    速度测试

    速度测试主要是针对关键有速度要求的业务进行手工测速度,可以在多次测试的基础上求平均值,可以和工具测得的响应时间等指标做对比分析。

    不同类型测试之间的区别

    性能测试是为了获得系统在某种特定的条件下(包括特定的负载条件下)的性能指标数据,而负载测试、压力测试是为了发现软件系统中所存在的问题,包括性能瓶颈、内存泄漏等。通过负载测试,也是为了获得系统正常工作时所能承受的最大负载,这时负载测试就成为容量测试。通过压力测试,可以知道在什么极限情况下系统会崩溃、系统是否具有自我恢复性等,但更多的是为了确定系统的稳定性。

    压力测试是测试系统什么情况下失效或者崩溃;负载测试是测试系统什么情况下超出需求指标;强度测试是测试系统在瞬时高负载、长时间负载情况下系统反应;容量测试是测试系统在大数据量交互的反应! 

    性能指标
    性能测试最基本要考虑以下几点

    1、时间特性,主要指的是软件产品的事物响应时间(用户发出请求到收到应答的这段时间)

    2、资源利用率,包括:cpu、内存、网络、硬盘、虚拟内存(如Java虚拟机)

    3、服务器可靠性,指服务器能在相对高负载情况下持续的运行

    4、可配置优化性,指服务器配置优化、业务逻辑优化、代码优化等

    检查系统是否满足需求规格说明书中规定的性能,通常表现在以下几个方面:

    1、对资源利用(包括:cpu、内存、网络、硬盘、虚拟内存(如Java虚拟机)等)进行的精确度量;

    2、对执行间隔;

    3、日志事件(如中断,报错)

    4、响应时间

    5、吞吐量(TPS)

    6、辅助存储区(例如缓冲区、工作区的大小等)

    7、处理精度等进行的监测

    在实际工作中我们经常会对两种类型软件进行测试:bs和cs,这两方面的性能指标一般需要哪些内容呢?

    bs结构程序一般会关注的通用指标如下(简):

    Web服务器指标指标:

    * Avg Rps: 平均每秒钟响应次数=总请求时间 / 秒数;

    * Avg time to last byte per terstion (mstes):平均每秒业务脚本的迭代次数,有人会把这两者混淆;

    * Successful Rounds:成功的请求;

    * Failed Rounds :失败的请求;

    * Successful Hits :成功的点击次数;

    * Failed Hits :失败的点击次数;

    * Hits Per Second :每秒点击次数;

    * Successful Hits Per Second :每秒成功的点击次数;

    * Failed Hits Per Second :每秒失败的点击次数;

    * Attempted Connections :尝试链接数;

    CS结构程序,由于一般软件后台通常为数据库,所以我们更注重数据库的测试指标:

    * User 0 Connections :用户连接数,也就是数据库的连接数量;

    * Number of deadlocks:数据库死锁;

    * Buffer Cache hit :数据库Cache的命中情况

    当然,在实际中我们还会察看多用户测试情况下的内存,CPU,系统资源调用情况。这些指标其实是引申出来性能测试中的一种:竞争测试。什么是竞争测试,软件竞争使用各种资源(数据纪录,内存等),看他与其他相关系统对资源的争夺能力。

    我们知道软件架构在实际测试中制约着测试策略和工具的选择。如何选择性能测试策略是我们在实际工作中需要了解的。一般软件可以按照系统架构分成几种类型:

    c/s

    client/Server 客户端/服务器架构

    基于客户端/服务器的三层架构

    基于客户端/服务器的分布式架构

    b/s

    基于浏览器/Web服务器的三层架构

    基于中间件应用服务器的三层架构l

    基于Web服务器和中间件的多层架构l

    性能指标的两个方面

     

    外部指标|系统指标(与用户场景和需求相关指标)

    从外部看,性能测试主要关注如下四个指标

    • 吞吐量:每秒钟系统能够处理客户的请求数、任务数,其直接体现系统的承载的能力。
    • 并发用户数:同一时刻与服务器进行数据交互的所有用户数量;
    • 响应时间:服务处理一个请求或一个任务的耗时。
    • 错误率:一批请求中结果出错的请求所占比例。

    响应时间

    从单个请求来看就是服务响应一次请求的花费的时间。但是在性能测试中,单个请求的响应时间并没有什么参考价值,通常考虑的是完成所有请求的平均响应时间及中位数时间。

     

    平均响应时间很好理解,就是完成请求花费的总时间/完成的请求总数。但是平均响应时间有一点不靠谱,因为系统的运行并不是平稳平滑的,如果某几个请求的时间超短或者超长就会导致平均数偏离很多。因此有时候我们会用中位数响应时间。

    所谓中位数的意思就是把将一组数据按大小顺序排列,处在最中间位置的一个数叫做这组数据的中位数 ,这意味着至少有50%的数据低于或高于这个中位数。当然,最为正确的统计做法是用百分比分布统计。也就是英文中的TP – Top Percentile ,TP50的意思在,50%的请求都小于某个值,TP90表示90%的请求小于某个时间。

    响应时间的指标取决于具体的服务。如智能提示一类的服务,返回的数据有效周期短(用户多输入一个字母就需要重新请求),对实时性要求比较高,响应时间的上限一般在100ms以内。而导航一类的服务,由于返回结果的使用周期比较长(整个导航过程中),响应时间的上限一般在2-5s。

    决定系统响应时间要素

    我们做项目要排计划,可以多人同时并发做多项任务,也可以一个人或者多个人串行工作,始终会有一条关键路径,这条路径就是项目的工期。

    系统一次调用的响应时间跟项目计划一样,也有一条关键路径,这个关键路径是就是系统响应时间;

    关键路径是由CPU运算、IO、外部系统响应等等组成。

    计算公式

    1、响应时间:对一个请求做出响应所需要的时间

    网络传输时间:N1+N2+N3+N4

    应用服务器处理时间:A1+A3

    数据库服务器处理时间:A2

    响应时间=网络响应时间+应用程序响应时间=(N1+N2+N3+N4)+(A1+A2+A3)

    2、平均响应时间:所有请求花费的平均时间

    系统处理事务的响应时间的平均值。事务的响应时间是从客户端提交访问请求到客户端接收到服务器响应所消耗的时间。对于系统快速响应类页面,一般响应时间为3秒左右。

    如:如果有100个请求,其中 98 个耗时为 1ms,其他两个为 100ms

    平均响应时间: (98 * 1 + 2 * 100) / 100.0 = 2.98ms,但是,2.98ms并不能反映服务器的整体效率,因为98个请求耗时才1ms,引申出百分位数

    百分位数:以响应时间为例,指的是 99% 的请求响应时间,都处在这个值以下,更能体现整体效率。

    注:(一般响应时间在3s内,用户会感觉比较满意。在3s~8s之间用户勉强能接受,大于8s用户就可能无法接受,从而刷新页面或者离开,仅供参考)

    响应时间与负载对应关系

    图中拐点说明:
    (1)响应时间突然增加
    (2)意味着系统的一种或多种资源利用达到的极限
    (3)通常可以利用拐点来进行性能测试分析与定位

    并发用户数

    一、首先涉及到并发用户数可以从以下几个方面去做数据判断。

    1.系统用户数

    2.在线用户数

    3.并发用户数

    二、三者之间的关系

    1.在线用户数的预估可以采取20%的系统用户数。例如某个系统在系统用户数有1000,则同时在线用户数据有可能达到200,或者预估200做参考。

    2.在线用户数和并发用户数又存在着关系。即:平均并发用户数为:c=NL/T L为在线时长,T为考核时长。例如:考核时长为1天,即8小时,但是用户平均在线时长为2小时,则c=n*2/8 n为登录系统的用户数,L为登录的时常。例如:一个系统有400个用户登录,然后每个用户登录大概停留2小时,则以一天8小时考核,算平均并发用户则为:c=400*2/8

    并发主要是针对服务器而言,在同一时刻与服务器进行交互(指向服务器发出请求)的在线用户数。

    (1)并发用户数:某一物理时刻同时向系统提交请求的用户数,提交的请求可能是同一个场景或功能,也可以是不同场景或功能。

    (2)在线用户数:某段时间内访问系统的用户数,这些用户并不一定同时向系统提交请求。如多个用户在浏览网页,但没有对同时对服务器进行数据请求,需要与并发用户数区分开。

    (3)系统用户数:系统注册的总用户数据

       三者之间的关系:系统用户数 >= 在线用户数 >= 并发用户数

    同时在线用户数:在一定的时间范围内,最大的同时在线用户数量。

    同时在线用户数=每秒请求数RPS(吞吐量)+并发连接数+平均用户思考时间

    平均并发用户数的计算:C=nL / T

    其中C是平均的并发用户数,n是平均每天访问用户数(login session),L是一天内用户从登录到退出的平均时间(login session的平均时间),T是考察时间长度(一天内多长时间有用户使用系统)

    并发用户数峰值计算:C^约等于C + 3*根号C  也是峰值C1,即最大并发数,计算公式C1=C+³√C

    其中C^是并发用户峰值,C是平均并发用户数,该公式遵循泊松分布理论。

    注:理解最佳并发用户数和最大并发用户数

     

    看了《LoadRunner没有告诉你的》之理发店模式,对最佳并发用户数和最大的并发用户数的理解小小整理了一下。

    所谓的理发店模式,简单地阐述一下,一个理发店有3个理发师,当同时来理发店的客户有3个的时候,那么理发师的资源能够有效地利用,这时3个用户数即为最佳的并发用户数;当理发店来了9个客户的时候,3个客户理发,而6个用户在等待,3个客户的等待时间为1个小时,另外的3个客户的等待时间为2小时,客户的最大忍受时间为3小时包括理发的1个小时,所以6个客户的等待时间都在客户的可以承受范围内,故9个客户是该理发店的最大并发用户数。

    吞吐量

    我把吞吐量定义为“单位时间内系统处理的客户请求的数量”( 吞吐量表示单位时间内能够完成的事务数量,因此也被称为每秒事务数(Transaction Per Second),计算方式是完成的事务数除以时间。),直接体现软件系统的性能承载能力,对于交互式应用系统来说、吞吐量反映的是服务器承受的压力、在容量规划的测试中、吞吐量是一个重要指标、它不但反映在中间件、数据库上、更加体现在硬件上。

    吞吐量的指标受到响应时间、服务器软硬件配置、网络状态等多方面因素影响。

    • 吞吐量越大,响应时间越长。
    • 服务器硬件配置越高,吞吐量越大。
    • 网络越差,吞吐量越小。

    在低吞吐量下的响应时间的均值、分布比较稳定,不会产生太大的波动。在高吞吐量下,响应时间会随着吞吐量的增长而增长,增长的趋势可能是线性的,也可能接近指数的。当吞吐量接近系统的峰值时,响应时间会出现激增。

    系统吞度量要素

      一个系统的吞度量(承压能力)与request对CPU的消耗、外部接口、IO等等紧密关联。单个reqeust 对CPU消耗越高,外部系统接口、IO影响速度越慢,系统吞吐能力越低,反之越高。

    系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间

    QPS(每秒请求数)(TPS (Transaction Per Second)每秒事务数):每秒钟系统处理的request/事务 数量,它是衡量系统处理能力的重要指标;

    并发数:系统同时处理的request/事务数

    响应时间:一般取平均响应时间

    理解了上面三个要素的意义之后,就能推算出它们之间的关系:QPS(TPS)= 并发数/平均响应时间

      一个系统吞吐量通常由QPS(TPS)、并发数两个因素决定,每套系统这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。

    系统吞吐量评估

    我们在做系统设计的时候就需要考虑CPU运算、IO、外部系统响应因素造成的影响以及对系统性能的初步预估。而通常境况下,我们面对需求,我们评估出来的QPS、并发数之外,还有另外一个维度:日页面流量PV。

    PV:访问一个URL,产生一个PV(Page View,页面访问量),每日每个网站的总PV量是形容一个 网站规模的重要指标。

    通过观察系统的访问日志发现,在用户量很大的情况下,各个时间周期内的同一时间段的访问流量几乎一样。只要能拿到日流量图和QPS我们就可以推算日流量。

    通常的技术方法:

    1. 找出系统的最高TPS和日PV,这两个要素有相对比较稳定的关系(除了放假、季节性因素影响之外)

    2. 通过压力测试或者经验预估,得出最高TPS,然后跟进1的关系,计算出系统最高的日吞吐量。

    无论有无思考时间(T_think),测试所得的TPS值和并发虚拟用户数(U_concurrent)、Loadrunner读取的交易响应时间(T_response)之间有以下关系(稳定运行情况下):TPS=U_concurrent / (T_response+T_think)。

    并发数、QPS、平均响应时间三者之间关系

     

     

    X轴代表并发用户数,Y轴代表资源利用率、吞吐量、响应时间。

    X轴与Y轴区域从左往右分别是轻压力区、重压力区、拐点区。

    随着并发用户数的增加,在轻压力区的响应时间变化不大,比较平缓,进入重压力区后呈现增长的趋势,最后进入拐点区后倾斜率增大,响应时间急剧增加。接着看吞吐量,随着并发用户数的增加,吞吐量增加,进入重压力区后逐步平稳,到达拐点区后急剧下降,说明系统已经达到了处理极限,有点要扛不住的感觉。

    同理,随着并发用户数的增加,资源利用率逐步上升,最后达到饱和状态。

    最后,把所有指标融合到一起来分析,随着并发用户数的增加,吞吐量与资源利用率增加,说明系统在积极处理,所以响应时间增加得并不明显,处于比较好的状态。但随着并发用户数的持续增加,压力也在持续加大,吞吐量与资源利用率都达到了饱和,随后吞吐量急剧下降,造成响应时间急剧增长。轻压力区与重压力区的交界点是系统的最佳并发用户数,因为各种资源都利用充分,响应也很快;而重压力区与拐点区的交界点就是系统的最大并发 用户数,因为超过这个点,系统性能将会急剧下降甚至崩溃。

    Light Load(较轻压力)-----最佳用户数(资源利用最高)---(较重压力,系统可以持续工作,但用户等待时间较长,满意度会下降)-----Heavy Load-------最大并发用户数--------Buckle Zone(用户无法忍受而放弃请求)

    最佳并发用户数:当系统的负载等于最佳并发用户数时,系统的整体效率最高,没有资源被浪费,用户也不需要等待
        最大并发用户数:系统的负载一直持续,有些用户在处理而有的用户在自己最大的等待时间内等待的时候

    我们需要保证的是:

    (1)最佳并发用户数需大于系统的平均负载

    (2)系统的最大并发用户数要大于系统需要承受的峰值负载

    怎么理解这两句话呢?

    (1)系统的平均负载:在特定的时间内,系统正在处理的用户数和等待处理的用户数的总和

    如果系统的平均负载大于最佳并发用户数,则用户的满意度会下降,所以我们需要保证系统的平均负载小于或者等于最佳并发用户数

    (2)峰值:指的是系统的最大能承受的用户数的极值

    只有最大并发用户数大于系统所能承受的峰值负载,才不会造成等待空间资源的浪费,导致系统的效率低下

    计算公式

    指单位时间内系统处理用户的请求数

    从业务角度看,吞吐量可以用:请求数/秒、页面数/秒、人数/天或处理业务数/小时等单位来衡量

    从网络角度看,吞吐量可以用:字节/秒来衡量

    对于交互式应用来说,吞吐量指标反映的是服务器承受的压力,他能够说明系统的负载能力

    以不同方式表达的吞吐量可以说明不同层次的问题,例如,以字节数/秒方式可以表示数要受网络基础设施、服务器架构、应用服务器制约等方面的瓶颈;已请求数/秒的方式表示主要是受应用服务器和应用代码的制约体现出的瓶颈。

    当没有遇到性能瓶颈的时候,吞吐量与虚拟用户数之间存在一定的联系,可以采用以下公式计算:F=VU * R /T

    其中F为吞吐量,VU表示虚拟用户个数,R表示每个虚拟用户发出的请求数,T表示性能测试所用的时间

     

    吞吐量与负载对应关系

    图中拐点说明:
    (1)吞吐量逐渐达到饱和
    (2)意味着系统的一种或多种资源利用达到的极限
    (3)通常可以利用拐点来进行性能测试分析与定位

    错误率

    超时错误率:主要指事务由于超时或系统内部其它错误导致失败占总事务的比率。

    错误率和服务的具体实现有关。通常情况下,由于网络超时等外部原因造成的错误比例不应超过5%%,由于服务本身导致的错误率不应超过1% 。

    内部指标|资源指标(与硬件资源消耗相关指标)

     资源利用率:资源利用率指的是对不同系统资源的使用程度,一般使用“资源实际使用/总的资源可用量”形成资源利用率。例如服务器的 CPU 利用率、磁盘利用率等。资源利用率是分析系统性能指标进而改善性能的主要依据,因此,它是 Web 性能测试工作的重点。资源利用率主要针对 Web 服务器、操作系统、数据库服务器、网络等,是测试和分析瓶颈的主要参数。在性能测试中,要根据需要采集具体的资源利用率参数来进行分析。

    从服务器的角度看,性能测试主要关注CPU、内存、服务器负载、网络、磁盘IO等

    1.硬件性能指标:CPU,内存Memory,磁盘I/O(Disk I/O),网络I/O(Network I/O)

    CPU:主要解释计算机指令以及处理计算机软件中的数据

    Linux系统中top命令查看CPU的使用率

    CPU的利用率(<=75%)有:user(用户使用),sys(系统调用<=30%),wait(等待<=5%),idle(空闲)

    当user消耗高时,通过top命令查看哪个用户进程占用cpu的使用

    user消耗过高的原因可能有:

    (1)代码问题。如代码中耗时循环中不加sleep,即例如while的死循环中,没有加sleep时间,导致没有空余的时间将cpu的控制权给其他的进程,一直陷入该死循环中,cpu得不到休息,所以usr的消耗过高,则cpu的消耗高

    (2)gc频繁。gc则为垃圾回收,由于垃圾回收也是需要大量的计算,也消耗cpu,所以当gc频繁时也导致usr用户空间的消耗也过高,cpu消耗过高

    当sys消耗高时,通过top命令查看系统调用资源的情况

    sys消耗过高的原因可能有:
    (1)上下文切换频繁。上下文切换发生的情况有:中断处理,多任务处理,用户状态改变。

    中断处理,当cpu停止处理当前的进程转而处理中断请求的进程时发生上下文切换。多任务处理则为有多个进程请求cpu的处理,进程的数量多于cpu的核数,则分配进程时间片,根据时间片处理进程,意味着会强制停止一个进程而去处理另一个进程,形成频繁的上下文切换。用户状态改变则为user状态与sys状态的改变。

    wait较高时,即等待的进程占比高则可以考虑是否磁盘读写,磁盘瓶颈问题, 等待的进程较多时,cpu无论如何切换都是切换到等待的进程,导致cpu一直在频繁切换等待的线程而利用率较低

    内存:与cpu沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存分为物理内存、页面交换(Paging),SWAP内存(虚拟内存)

    页面交换:当物理内存即实际的内存满了的时候,将物理内存中不常用的进程调出存储到虚拟内存中,以缓解物理内存空间的压力,所以当物理内存与虚拟内存的数据交换频繁的时候,这时候就要关注下内存的性能情况。

    SWAP内存:为进程分配虚拟的内存空间,即调用硬盘的空间作为内存使用。

    内存的性能分析是又可用内存与页面交换来分析的,可用内存使用占70%-80%为上限,当超出这个数值,内存性能情况就比较危险,而且即使可用内存使用不超过80%的数值时,页面交换比较频繁时,也是要关注下内存情

    一般物理内存即使是满内存也不能代表内存出现问题,主要是看虚拟内存swap,虚拟内存应该<=70%,大于则可以考虑是否内存问题或者内存泄漏

    磁盘吞吐量,指单位时间内通过磁盘的数据量。主要关注磁盘的繁忙率,如果高于70%,则磁盘瓶颈

    网络吞吐量,指单位时间内通过网络的数据量,当吞吐量大于网路设备或链路最大传输能力,即带宽时,则应该考虑升级网络设备或者增加带宽,Linux命令netstate

    网络IO也有可能出现终止连接失败。例如当服务端出现大量的TIME_WAIT,见以下TCP终止连接的第4个步骤,在主动发起关闭连接方接收到结束符FIN时状态变为TIME_WAIT,这时在服务端发现大量的TIME_WAIT,意味着关闭连接是由服务端发起的。

    常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。

    问?什么情况是由服务端发起关闭连接?答:在用户端的应用程序忘记关闭连接

    另外如果在服务端发现大量状态CLOSE_WAIT,则说明第二次关闭回不去,也就是TCP关闭连接的第三个步骤没有执行,停留在CLOSE_WAIT的状态,浏览器如果这时发起请求则会返回超时连接,因为服务端这边一直无法进行第二次关闭,将结束符返回去给用户端。
    注:普及TCP连接的三次握手,终止连接的四次握手

    TCP三次握手连接:

    (1)用户端发送SYN给服务器,用户端的状态为SYN_SEND

    (2)服务端接收到后发送ACK给用户端,服务端的状态为SYN_RECV

    (3)用户端接收到服务端发送过来的后发送了ACK给服务端,用户端的状态变为Estabilished

    TCP终止连接:

    (1)用户端的应用主动发起关闭连接,即应用调用close发送FIN给服务端

    (2)服务端接收到FIN后发送ACK给用户端,服务端的状态变为CLOSE_WAIT

    (3)服务端发送ACK给用户端的同时也将FIN作为一个文件结束符传递给接收端应用程序

    (4)用户端的应用程序接收到FIN后将调用close关闭它的套接字,确认FIN,这时用户端的状态变为TIME_WAIT

    (5)用户端发送ACK回执给服务端,连接终止

    2.中间件:常用的中间件例如web服务器Tomcat,Weblogic web服务器,JVM(java虚拟机),ThreadPool线程池,JDBC数据驱动

    注:http服务器和web服务器与应用服务器的差别是一个存储静态网页的服务器,一个是存储css,js等动态加载网页的服务器,而tomcat则属于应用服务器

    注:对中间件例如对服务器的性能测试,需要将监控的jmeter-server的文件下载在服务端上,然后开启即可监控被测服务器的性能,或者将监控的软件下载在被测服务器上,远程启动监控软件等

    3.数据库指标

    应关注SQL,吞吐量,缓存命中率,连接数等,则是关注sql语句执行时间,以微妙为单位,吞吐量TPS,缓存命中率应>=95%

    注:对数据库的性能测试通过jemter利用批量的sql语句对数据库进行操作,从而测试数据库的性能,前提是需要将jdbc的驱动加载在测试计划添加的驱动文件中,然后添加jdbc的前置处理器和jdbc的请求sample。

    4.JVM,java虚拟机,为使java的代码可以编译运行在不同的平台上顺畅,仿真模拟各种计算机来实现

    GC:自动内存管理程序,被引用的对象保存在内存中,当对象不被引用时则释放。关注的参数有Full GC完全java虚拟机垃圾部分回收频率

    5.前端指标

    前端应该关注页面展示,即首次显示时间,页面数量,页面大小,网络startRender,firstRender等

    注:关注前端的性能与后端的性能的不同点在于,前端是每个用户的直观的感受,以及前端页面的加载元素耗费时间给予用户的感受,而后端的性能关注点在于多用户使用系统时,服务器是否能够承受或者服务器的处理能力如何,能否以较好的响应时间响应。

    6.Load:系统平均负载,特定时间间隔内运行进程数,Load与cpu核数一致

    CPU

    CPU使用率:指用户进程与系统进程消耗的CPU时间百分比,长时间情况下,一般可接受上限不超过85%。

    后台服务的所有指令和数据处理都是由CPU负责,服务对CPU的利用率对服务的性能起着决定性的作用。

    Linux系统的CPU主要有如下几个维度的统计数据:

    us:用户态使用的cpu时间百分比

    sy:系统态使用的cpu时间百分比

    ni:用做nice加权的进程分配的用户态cpu时间百分比

    id:空闲的cpu时间百分比

    wa:cpu等待IO完成时间百分比

    hi:硬中断消耗时间百分比

    si:软中断消耗时间百分比

    下图是线上开放平台转发服务某台服务器上top命令的输出,下面以这个服务为例对CPU各项指标进行说明

     

    us & sy:大部分后台服务使用的CPU时间片中us和sy的占用比例是最高的。同时这两个指标又是互相影响的,us的比例高了,sy的比例就低,反之亦然。通常sy比例过高意味着被测服务在用户态和系统态之间切换比较频繁,此时系统整体性能会有一定下降。另外,在使用多核CPU的服务器上,CPU 0负责CPU各核间的调度,CPU 0上的使用率过高会导致其他CPU核心之间的调度效率变低。因此测试过程中CPU 0需要重点关注。

    ni:每个Linux进程都有个优先级,优先级高的进程有优先执行的权利,这个叫做pri。进程除了优先级外,还有个优先级的修正值。这个修正值就叫做进程的nice值。一般来说,被测服务和服务器整体的ni值不会很高。如果测试过程中ni的值比较高,需要从服务器Linux系统配置、被测服务运行参数查找原因

    id:线上服务运行过程中,需要保留一定的id冗余来应对突发的流量激增。在性能测试过程中,如果id一直很低,吞吐量上不去,需要检查被测服务线程/进程配置、服务器系统配置等。

    wa:磁盘、网络等IO操作会导致CPU的wa指标提高。通常情况下,网络IO占用的wa资源不会很高,而频繁的磁盘读写会导致wa激增。如果被测服务不是IO密集型的服务,那需要检查被测服务的日志量、数据载入频率等。

    hi & si:硬中断是外设对CPU的中断,即外围硬件发给CPU或者内存的异步信号就是硬中断信号;软中断由软件本身发给操作系统内核的中断信号。通常是由硬中断处理程序或进程调度程序对操作系统内核的中断,也就是我们常说的系统调用(System Call)。在性能测试过程中,hi会有一定的CPU占用率,但不会太高。对于IO密集型的服务,si的CPU占用率会高一些。

    内存

    内存利用率:内存利用率=(1-空闲内存/总内存大小)*100%,一般至少有10%可用内存,内存使用率可接受上限为85%。

    性能测试过程中对内存监控的主要目的是检查被测服务所占用内存的波动情况。

    在Linux系统中有多个命令可以获取指定进程的内存使用情况,最常用的是top命令,如下图所示

     

    其中

    VIRT:进程所使用的虚拟内存的总数。它包括所有的代码,数据和共享库,加上已换出的页面,所有已申请的总内存空间

    RES:进程正在使用的没有交换的物理内存(栈、堆),申请内存后该内存段已被重新赋值

    SHR:进程使用共享内存的总数。该数值只是反映可能与其它进程共享的内存,不代表这段内存当前正被其他进程使用

    SWAP:进程使用的虚拟内存中被换出的大小,交换的是已经申请,但没有使用的空间,包括(栈、堆、共享内存)

    DATA:进程除可执行代码以外的物理内存总量,即进程栈、堆申请的总空间

    从上面的解释可以看出,测试过程中主要监控RES和VIRT,对于使用了共享内存的多进程架构服务,还需要监控SHR。

    LOAD(服务器负载)

    Linux的系统负载指运行队列的平均长度,也就是等待CPU的平均进程数

    从服务器负载的定义可以看出,服务器运行最理想的状态是所有CPU核心的运行队列都为1,即所有活动进程都在运行,没有等待。这种状态下服务器运行在负载阈值下。

    通常情况下,按照经验值,服务器的负载应位于阈值的70%~80%,这样既能利用服务器大部分性能,又留有一定的性能冗余应对流量增长。

    Linux提供了很多查看系统负载的命令,最常用的是top和uptime

    top和uptime针对负载的输出内容相同,都是系统最近1分钟、5分钟、15分钟的负载均值

     

    Uptime命令结果的每一列的含义如下:

    “当前时间 系统运行时长 登录的用户数最 近1分钟、5分钟、15分钟的平均负载”

    查看系统负载阈值的命令如下,下方是查看CPU每个核心的使用情况:

     

    在性能测试过程中,系统负载是评价整个系统运行状况最重要的指标之一。通常情况下,压力测试时系统负载应接近但不能超过阈值,并发测试时的系统负载最高不能超过阈值的80%,稳定性测试时,系统负载应在阈值的50%左右。

    网络

    网络带宽:一般使用计数器Bytes Total/sec来度量,Bytes Total/sec表示为发送和接收字节的速率,包括帧字符在内。判断网络连接速度是否是瓶颈,可以用该计数器的值和目前网络的带宽比较。

    性能测试中网络监控主要包括网络流量、网络连接状态的监控。

    网络流量监控

    可以使用nethogs命令。该命令与top类似,是一个实时交互的命令,运行界面如下

     

    在后台服务性能测试中,对于返回文本结果的服务,并不需要太多关注在流量方面。

    网络连接状态监控

    性能测试中对网络的监控主要是监控网络连接状态的变化和异常。对于使用TCP协议的服务,需要监控服务已建立连接的变化情况(即ESTABLISHED状态的TCP连接)。对于HTTP协议的服务,需要监控被测服务对应进程的网络缓冲区的状态、TIME_WAIT状态的连接数等。Linux自带的很多命令如netstat、ss都支持如上功能。下图是netstat对指定pid进程的监控结果

    磁盘IO

     磁盘主要用于存取数据,因此当说到IO操作的时候,就会存在两种相对应的操作,存数据的时候对应的是写IO操作,取数据的时候对应的是读IO操作,一般使用% Disk Time(磁盘用于读写操作所占用的时间百分比)度量磁盘读写性能。

    性能测试过程中,如果被测服务对磁盘读写过于频繁,会导致大量请求处于IO等待的状态,系统负载升高,响应时间变长,吞吐量下降。

    Linux下可以用iostat命令来监控磁盘状态,如下图

     

    tps:该设备每秒的传输次数。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的

    kB_read/s:每秒从设备(driveexpressed)读取的数据量,单位为Kilobytes

    kB_wrtn/s:每秒向设备(driveexpressed)写入的数据量,单位为Kilobytes

    kB_read:读取的总数据量,单位为Kilobytes

    kB_wrtn:写入的总数量数据量,单位为Kilobytes

    从iostat的输出中,能够获得系统运行最基本的统计数据。但对于性能测试来说,这些数据不能提供更多的信息。需要加上-x参数

      

    rrqm/s:每秒这个设备相关的读取请求有多少被合并了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge)

    wrqm/s:每秒这个设备相关的写入请求有多少被Merge了

    await:每一个IO请求的处理的平均时间(单位是毫秒)

    %util:在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,该参数暗示了设备的繁忙程度。

    资源利用与负载对应关系

    图中拐点说明:
    (1)服务器某一资源使用逐渐达到饱和
    (2)通常可以利用拐点来进行性能测试分析与定位

    性能计数器(counters)

    是描述服务器或操作系统性能的一些数据指标,如使用内存数、进程时间,在性能测试中发挥着“监控和分析”的作用,尤其是在分析系统可扩展性、进行新能瓶颈定位时有着非常关键的作用。

    常见性能瓶颈

    吞吐量到上限时系统负载未到阈值:一般是被测服务分配的系统资源过少导致的。测试过程中如果发现此类情况,可以从ulimit、系统开启的线程数、分配的内存等维度定位问题原因

    CPU的us和sy不高,但wa很高:如果被测服务是磁盘IO密集型型服务,wa高属于正常现象。但如果不是此类服务,最可能导致wa高的原因有两个,一是服务对磁盘读写的业务逻辑有问题,读写频率过高,写入数据量过大,如不合理的数据载入策略、log过多等,都有可能导致这种问题。二是服务器内存不足,服务在swap分区不停的换入换出。

    同一请求的响应时间忽大忽小:在正常吞吐量下发生此问题,可能的原因有两方面,一是服务对资源的加锁逻辑有问题,导致处理某些请求过程中花了大量的时间等待资源解锁;二是Linux本身分配给服务的资源有限,某些请求需要等待其他请求释放资源后才能继续执行。

    内存持续上涨:在吞吐量固定的前提下,如果内存持续上涨,那么很有可能是被测服务存在明显的内存泄漏,需要使用valgrind等内存检查工具进行定位。

    性能瓶颈定位之拐点分析法

      “拐点分析”方法是一种利用性能计数器曲线图上的拐点进行性能分析的方法。它的基本思想就是性能产生瓶颈的主要原因就是因为某个资源的使用达到了极限,此时表现为随着压力的增大,系统性能却出现急剧下降,这样就产生了“拐点”现象。当得到“拐点”附近的资源使用情况时,就能定位出系统的性能瓶颈。

    软件性能的其它术语

    思考时间的计算公式

    Think Time,从业务角度来看,这个时间指用户进行操作时每个请求之间的时间间隔,而在做新能测试时,为了模拟这样的时间间隔,引入了思考时间这个概念,来更加真实的模拟用户的操作。

    在吞吐量这个公式中F=VU * R / T说明吞吐量F是VU数量、每个用户发出的请求数R和时间T的函数,而其中的R又可以用时间T和用户思考时间TS来计算:R = T / TS

    下面给出一个计算思考时间的一般步骤:

    1、首先计算出系统的并发用户数

    C=nL / T   F=R×C

    2、统计出系统平均的吞吐量

    F=VU * R / T   R×C = VU * R / T

    3、统计出平均每个用户发出的请求数量

    R=u*C*T/VU

    4、根据公式计算出思考时间

    TS=T/R

    软件性能的影响因素

    (1)硬件设施(部署结构、机器配置)

    (2)网络环境(客户端带宽、服务器端带宽)

    (3)操作系统(类型、版本、参数配置)

    (4)中间件(类型、版本、参数配置)

    (5)应用程序(性能)

    (6)并发用户数(系统当前访问状态)

    (7)客户端

    (8)数据服务器

    (9)编程语言、程序实现方式、算法

    软件性能的关注点

     

    首先,开发软件的目的是为了让用户使用,我们先站在用户的角度分析一下,用户需要关注哪些性能。

    对于用户来说,当点击一个按钮、链接或发出一条指令开始,到系统把结果已用户感知的形式展现出来为止,这个过程所消耗的时间是用户对这个软件性能的直观印象。也就是我们所说的响应时间,当相应时间较小时,用户体验是很好的,当然用户体验的响应时间包括个人主观因素和客观响应时间,在设计软件时,我们就需要考虑到如何更好地结合这两部分达到用户最佳的体验。如:用户在大数据量查询时,我们可以将先提取出来的数据展示给用户,在用户看的过程中继续进行数据检索,这时用户并不知道我们后台在做什么。

    用户关注的是用户操作的响应时间。

     

    其次,我们站在管理员的角度考虑需要关注的性能点。

    1、  响应时间
    2、 服务器资源使用情况是否合理
    3、 应用服务器和数据库资源使用是否合理
    4、 系统能否实现扩展
    5、 系统最多支持多少用户访问、系统最大业务处理量是多少
    6、 系统性能可能存在的瓶颈在哪里
    7、 更换那些设备可以提高性能
    8、 系统能否支持7×24小时的业务访问

    再次,站在开发(设计)人员角度去考虑。

    1、 架构设计是否合理
    2、 数据库设计是否合理
    3、 代码是否存在性能方面的问题
    4、 系统中是否有不合理的内存使用方式
    5、 系统中是否存在不合理的线程同步方式
    6、 系统中是否存在不合理的资源竞争

    那么站在性能测试工程师的角度,我们要关注什么呢?  一句话,我们要关注以上所有的性能点。

     

    性能测试的核心原理

    性能测试的核心原理,开发测试工具也是基于前两点:

    1、基于协议(前端后端通信机制),基于界面(决定和前端交互),基于代码(后端)。

    基于网络的分布式架构:基于网络协议去模拟用户发送请求;

    2、多线程:模拟多线程操作,多人同时操作,模拟大负载量(功能测试在于用以测试功能);

    3、模拟真实场景:真实的网络环境,用户操作时间不确定性,操作不确定,得出的数据是准确的,场景不对,数据也不一定可用。

    性能问题分析原则

     

    性能测试原则

    1)情况许可时,应使用几种测试工具或手段分别独立进行测试,并将结果相互印证,避免单一工具或测试手段自身缺陷影响结果的准确性;

    2)对于不同的系统,性能关注点是有所区别的,应该具体问题具体分析;

    3)查找瓶颈的过程应由易到难逐步排查:

         服务器硬件瓶颈及网络瓶颈(局域网环境下可以不考虑网络因素)

         应用服务器及中间件操作系统瓶颈(数据库、WEB服务器等参数配置)

         应用业务瓶颈(SQL语句、数据库设计、业务逻辑、算法、数据等)

    4)性能调优过程中不宜对系统的各种参数进行随意的改动,应该以用户配置手册中相关参数设置为基础,逐步根据实际现场环境进行优化,一次只对某个领域进行性能调优(例如对CPU的使用情况进行分析),并且每次只改动一个设置,避免相关因素互相干扰;

    5)调优过程中应仔细进行记录,保留每一步的操作内容及结果,以便比较分析;

    6)性能调优是一个经验性的工作,需要多思考、分析、交流和积累;

    7)了解“有限的资源,无限的需求”;

    8)尽可能在开始前明确调优工作的终止标准。

    性能测试的注意要点

     

    性能调优应该注意的要点

     

    性能测试流程

    采用自动化负载测试工具执行的并发性能测试,基本遵循的测试过程有:测试需求与测试内容,测试案例制定,测试环境准备,测试脚本录制、编写与调试,脚本分配、回放配置与加载策略,测试执行跟踪,结果分析与定位问题所在,测试报告与测试评估。

     

     

     

     

    一、性能测试需求分析

      性能需求分析是整个性能测试工作开展的基础,如果连性能的需求都没弄清楚,后面的性能测试执行其实是没有任何意义的,而且性能需求分析做的好不好直接影响到性能测试的结果。

      一些性能测试人员常犯的错误就是测试一开始就直接用工具对系统进行加压,没有弄清楚性能测试的目的,稀里糊涂做完了以后也不知道结果是否满足性能需求。市面上的书籍也大都是直接讲性能测试工具如LR,jmeter如何使用,导致很多新手一提到性能测试就直接拿工具来进行录制回放,使得很多人认为会使用性能测试工具就等于会性能测试了,殊不知工具其实只是性能测试过程中很小的一部分。

     在需求分析阶段,测试人员需要与项目相关的人员进行沟通,收集各种项目资料,对系统进行分析,建立性能测试数据模型,并将其转化为可衡量的具体性能指标,确认测试的目标。所以性能测试需求分析过程是繁杂的,需要测试人员有深厚的性能理论知识,除此之外还需要懂一些数学建模的知识来帮助我们建立性能测试模型。

    首先,让我们来看看通过性能需求分析我们需要得出哪些结论或目标:

    • 明确倒底要不要做性能测试?性能测试的目的是什么?
    • 明确被测系统是什么?被测试系统的相关技术信息如:架构、平台、协议等
    • 明确被测系统的基本业务、关键业务,用户行为
    • 明确性能测试点是什么?哪些需要测,为什么?哪些不需要测,又是为什么?
    • 明确被测系统未来的业务拓展规划以及性能需求?
    • 明确性能测试策略,即应该怎么测试?
    • 明确性能测试的指标,知道测试出来的结果怎么算通过?

    其次,需求分析阶段我们可以从以下几个方面入手:

    1、系统信息调研:

      指对被测试系统进行分析,需要对其有全面的了解和认识,这是我们做好性能测试的前提,而且在后续进行性能分析和调优时将会大有用处,试想如果连系统的架构、协议都不了解,我们如何进行准确的性能测试?如果进行性能分析与调优?

      需要分析的系统信息如下(包括但不仅限于如下这些):

     

     

     

    2、业务信息调研:

      指对被测试的业务进行分析,通过对业务的分析和了解,方便我们后续进行性能测试场景的确定以及性能测试指标的确定。

      需要分析的业务信息如下(包括但不仅限于如下这些):

     

    3、性能需求评估:

      在实施性能测试之前,我们需要对被测系统做相应的评估,主要目的是明确是否需要做性能测试。如果确定需要做性能测试,需要进一步确立性能测试点和指标,明确该测什么、性能指标是多少,测试通过or不通过的标准?性能指标也会根据情况评估,要求被测系统能满足将来一定时间段的业务压力。

      判断是否进行性能测试主要从下面两个方面进行思考:

    • 业务角度:

       系统是公司内部 or 对外?系统使用的人数的多少?如果一个系统上线后基本没几个人使用,无论系统多大,设计多么复杂,并发性的性能测试都是没必要的,前期可以否决。当然,除非在功能测试阶段发现非常明显的性能问题,使得用户体验较差的,此时可进行性能测试来排查问题。

    • 系统角度:系统又可以从以下3个方面进行分析

      a)系统架构:

         如果一个系统采用的框架是老的系统框架(通常大公司都有自己的统一框架),只是在此框架上增加一些应用,其实是没有必要做性能测试,因为老框架的使用肯定是经过了验证的。如果一个系统采用的是一种新的框架,可以考虑做性能测试。

      b)数据库要求:

         很多情况下,性能测试是大数据量的并发访问、修改数据库,而瓶颈在于连接数据库池的数量,而非数据库本身的负载、吞吐能力。这时,可以结合DBA的建议,来决定是否来做性能测试。

      c)系统特殊要求:

         从实时性角度来分析,某些系统对响应时间要求比较,比如证券系统,系统的快慢直接影响客户的收益,这种情况就有作并发测试的必要,在大并发量的场景下,查看这个功能的响应时间。

         从大数据量上传下载角度分析,某些系统经常需要进行较大数据量的上传和下载操作,虽然此种操作使用的人数不会太多,但是也有必要进行性能测试,确定系统能处理的最大容量,如果超过这个容量时系统需要进行相关控制,避免由于不人工误操作导致系统内存溢出或崩溃。

    4、确定性能测试点: 

      在上面第3点中,我们简单分析了如何确定一个系统是否需要做性能测试。下面简单总结下如果一个系统确定要做性能测试,我们如何确定被测系统的性能测试点?

      我们可以从下面几个方面进行分析:

    • 关键业务:

      确定被测项目是否属于关键业务,有哪些主要的业务逻辑点,特别是跟交易相关的功能点。例如转账,扣款等接口。如果项目(或功能点)不属于关键业务(或关键业务点),则可转入下面。

    • 日请求量:

      确定被测项目各功能点的日请求量(可以统计不同时间粒度下的请求量如:小时,日,周,月)。如果日请求量很高,系统压力很大,而且又是关键业务,该项目需要做性能测试,而且关键业务点,可以被确定为性能点。

    • 逻辑复杂度:

      判定被测项目各功能点的逻辑复杂度。如果一个主要业务的日请求量不高,但是逻辑很复杂,则也需要通过性能测试。原因是,在分布式方式的调用中,当某一个环节响应较慢,就会影响到其它环节,造成雪崩效应。

    • 运营推广活动:

      根据运营的推广计划来判定待测系统未来的压力。未雨绸缪、防患于未然、降低运营风险是性能测试的主要目标。被测系统的性能不仅能满足当前压力,更需要满足未来一定时间段内的压力。因此,事先了解运营推广计划,对性能点的制定有很大的作用。例如,运营计划做活动,要求系统每天能支撑多少 PV、多少 UV,或者一个季度后,需要能支撑多大的访问量等等数据。当新项目(或功能点)属于运营重点推广计划范畴之内,则该项目(或功能点)也需要做性能测试。

    以上 4 点,是相辅相成、环环相扣的。在实际工作中应该具体问题具体分析。例如,当一个功能点不满足以上 4 点,但又属于资源高消耗(内存、CPU),也可列入性能测试点行列。

    注:

    PV:访问一个URL,产生一个PV(Page View,页面访问量),每日每个网站的总PV量是形容一个 网站规模的重要指标。

    UV:作为一个独立的用户,访问站点的所有页面均算作一个UV(Unique Visitor,用户访问)

    5、确定性能指标: 

      性能需求分析一个很重要的目标就是需要确定后期性能分析用的性能指标,性能指标有很多,可以根据具体项目选取和设定,而具体的指标值则需要根据业务特点进行设定,本文不详细进行阐述,后续可考虑就此单独写一篇。

    二、性能测试准备

    1、测试环境准备:(见:四:测试脚本设计与开发)

      a)系统运行环境:这个通常就是我们的测试环境,有些时候需求比较多,做性能测试担心把环境搞跨了影响其它的功能测试,可能需要重新搭建一套专门用来做性能测试的环境。

      b)执行机环境:这个就是用来生成负载的执行机,通常需要在物理机上运行,而物理机又是稀缺资源,所以我们每次做性能测试都需要提前准备好执行机环境。

    2、测试场景设计:(见:四:测试脚本设计与开发)

    根据性能需求分析来设计符合用户使用习惯的场景,场景设计的好不好直接影响到性能测试的效果。

    3、性能工具准备:

      a)负载工具:根据需求分析和系统特点选择合适的负载工具,比如LR、Jmeter或galting等

      b)监控工具:准备性能测试时的服务器资源、JVM、数据库监控工具,以便进行后续的性能测试分析与调优。

    4、测试脚本准备:如果性能测试工具不能满足被测系统的要求或只能满足部分要求时,需要我们自己开发脚本配合工具进行性能测试。

    5、测试数据准备:

      a)负载测试数据:并发测试时需要多少数据?比如登录场景?

      b)DB数据量大小:为了尽量符合生产场景,需要模拟线上大量数据情况,那么要往数据库里提前插入一定的数据量。这可能需要花费一些时间,特点是关联系统较多,逻辑复杂的业务可能同时涉及多张表。

    6、性能测试团队组建:如果需要其它关联系统或专业人士如DBA配合的,也需要提前进行沟通。

    三、性能测试计划

    测试计划阶段最重要的是分析用户场景,确定系统性能目标。

    1、性能测试领域分析

    根据对项目背景,业务的了解,确定本次性能测试要解决的问题点;是测试系统能否满足实际运行时的需要,还是目前的系统在哪些方面制约系统性能的表现,或者,哪些系统因素导致系统无法跟上业务发展?确定测试领域,然后具体问题具体分析。

    2、用户场景剖析和业务建模

    根据对系统业务、用户活跃时间、访问频率、场景交互等各方面的分析,整理一个业务场景表,当然其中最好对用户操作场景、步骤进行详细的描述,为测试脚本开发提供依据。

    3、确定性能目标

    前面已经确定了本次性能测试的应用领域,接下来就是针对具体的领域关注点,确定性能目标(指标);其中需要和其他业务部门进行沟通协商,以及结合当前系统的响应时间等数据,确定最终我们需要达到的响应时间和系统资源使用率等目标;比如:

    ①登录请求到登录成功的页面响应时间不能超过2秒;

    ②报表审核提交的页面响应时间不能超过5秒;

    ③文件的上传、下载页面响应时间不超过8秒;

    ④服务器的CPU平均使用率小于70%,内存使用率小于75%;

    ⑤  各个业务系统的响应时间和服务器资源使用情况在不同测试环境下,各指标随负载变化的情况等;

    web性能测试之响应时间

    4、制定测试计划的实施时间

    预设本次性能测试各子模块的起止时间,产出,参与人员等等。

    (1)明确测试范围

    (2)制订时间(进度)计划

    (3)制订成本计划

    (4)制订环境计划

    (5)测试工具规划

    (6)测试风险分析

    四、测试脚本设计与开发

    性能测试中,测试脚本设计与开发占据了很大的时间比测试重。

    1、测试环境设计

    本次性能测试的目标是需要验证系统在实际运行环境中的性能外,还需要考虑到不同的硬件配置是否会是制约系统性能的重要因素!因此在测试环境中,需要部署多个不同的测试环境,

    在不同的硬件配置上检查应用系统的性能,并对不同配置下系统的测试结果进行分析,得出最优结果(最适合当前系统的配置)。

    这里所说的配置大概是如下几类:

    ①数据库服务器

    ②应用服务器

    ③负载模拟器

    ④软件运行环境,平台测试环境测试数据,可以根据系统的运行预期来确定,比如需要测试的业务场景,数据多久执行一次备份转移,该业务场景涉及哪些表,每次操作数据怎样写入,写入几条,需要多少的测试数据来使得测试环境的数据保持一致性等等。

    可以在首次测试数据生成时,将其导出到本地保存,在每次测试开始前导入数据,保持一致性。

    2、测试场景设计

    通过和业务部门沟通以及以往用户操作习惯,确定用户操作习惯模式,以及不同的场景用户数量,操作次数,确定测试指标,以及性能监控等。

    3、测试用例设计

    确认测试场景后,在系统已有的操作描述上,进一步完善为可映射为脚本的测试用例描述,用例大概内容如下:

    用例编号:查询表单_xxx_x1(命名以业务操作场景为主,简洁易懂即可)

    用例条件:用户已登录、具有对应权限等。。。

    操作步骤:

    ①进入对应页面。。。。。。

    ②查询相关数据。。。。。。

    ③勾选导出数据。。。。。。

    ④修改上传数据。。。。。。

    PS:这里的操作步骤只是个例子,具体以系统业务场景描述;

    4、脚本和辅助工具的开发及使用

    按照用例描述,可利用工具进行录制,然后在录制的脚本中进行修改;比如参数化、关联、检查点等等,最后的结果使得测试脚本可用,能达到测试要求即可;

    PS:个人而言,建议尽量自己写脚本来实现业务操作场景,这样对个人技能提升较大;一句话:能写就绝不录制!!!

    五、性能测试执行

    在这个阶段,只需要按照之前已经设计好的业务场景、环境和测试用例脚本,部署环境,执行测试并记录结果即可。

     1、人工边执行边分析

      通常我们做性能测试都是人工执行并随时观察系统运行的情况、资源的使用率等指标。性能测试的吸引力之一就在于它的不可预知性。当我们在做性能测试的时候,遇到跟预期不符的情况很正常,这个时候需要冷静的分析。但这个过程可能会很漫长,需要不断的调整系统配置或程序代码来定位问题,耗时耗人力。特别是在当前敏捷开发模式比较流行的大环境下,版本发布非常频繁且版本周期短(通常1~2周一个版本),没有那么长的时间来做性能测试。

    2、无人值守执行性能测试

      无人值守是最理想化的目标,目前我们也朝着这个方向努力。无人值守不是说没有人力介入,而是把人为的分析和执行过程分离,执行过程只是机器服从指令的运行而已。通常测试环境在白天比较繁忙,出现性能问题及定位难度较大且会影响功能测试。所以一般性能测试最好在晚上或周末进行,在相对较安静的条件有利于测试结果的稳定性。这种方法也相对比较适合敏捷的模式,不需要人工一直守着。只需要在拿到结果后进行分析就好了。同时,这种方式对测试人员能力的要求比较高,需要我们能进行自动化的收集各种监控数据、生成报表便于后续分析。

    六、结果分析与调优

    1、测试环境的系统性能分析

    根据我们之前记录得到的测试结果(图表、曲线等),经过计算,与预定的性能指标进行对比,确定是否达到了我们需要的结果;如未达到,查看具体的瓶颈点,然后根据瓶颈点的具体数据进行具体情况具体分析(影响性能的因素很多,这一点,可以根据经验和数据表现来判断分析)。

    2、硬件设备对系统性能表现的影响分析

    由于之前设计了几个不同的测试环境,故可以根据不同测试环境的硬件资源使用状况图进行分析,确定瓶颈是再数据库服务器、应用服务器抑或其他方面,然后针对性的进行优化等操作。

    3、其他影响因素分析

    影响系统性能的因素很多,可以从用户能感受到的场景分析,哪里比较慢,哪里速度尚可,这里可以根据258原则对其进行分析;

    至于其他诸如网络带宽、操作动作、存储池、线程实现、服务器处理机制等一系列的影响因素,具体问题具体分析,这里就不一一表述了。

    4、测试中发现的问题

    在性能测试执行过程中,可能会发现某些功能上的不足或存在的缺陷,以及需要优化的地方,这也是执行多次测试的优点。

    1.性能分析方法分类:

    (1)指标达成法:用于验证性能指标

    (2)最优化分析法:用于能力验证型测试

    2.常用性能分析方法:

    (1)快速瓶颈识别:

    ①硬件上的性能瓶颈        ②应用软件上的性能瓶颈     ③应用程序上的性能瓶颈  

    ④操作系统上的性能瓶颈    ⑤网络设备上的性能瓶颈

    (2)性能下降曲线:单用户区域、性能平坦区、压力区域、性能拐点

    (3)内存分析方法   (4)处理器分析方法   (5)磁盘IO分析方法      (6)进程分析方法   (7)网络分析方法

    七、测试报告与总结

       性能测试报告是性能测试的里程碑,通过报告能展示出性能测试的最终成果,展示系统性能是否符合需求,是否有性能隐患。性能测试报告中需要阐明性能测试目标、性能测试环境、性能测试数据构造规则、性能测试策略、性能测试结果、性能测试调优说明、性能测试过程中遇到的问题和解决办法等。

    性能测试工程师完成该次性能测试后,需要将测试结果进行备案,并作为下次性能测试的基线标准,具体包括性能测试结果数据、性能测试瓶颈和调优方案等。同时需要将测试过程中遇到的问题,包括代码瓶颈、配置项问题、数据问题和沟通问题,以及解决办法或解决方案,进行知识沉淀

    性能测试的实施过程

     

    客户端性能测试

    应用在客户端性能测试的目的是考察客户端应用的性能,测试的入口是客户端。它主要包括并发性能测试、疲劳强度测试、大数据量测试和速度测试等,其中并发性能测试是重点。

    并发性能测试的过程是一个负载测试和压力测试的过程,即逐渐增加负载,直到系统的瓶颈或者不能接收的性能点,通过综合分析交易执行指标和资源监控指标来确定系统并发性能的过程。负载测试(Load Testing)是确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统组成部分的相应输出项,例如通过量、响应时间、CPU负载、内存使用等来决定系统的性能。负载测试是一个分析软件应用程序和支撑架构、模拟真实环境的使用,从而来确定能够接收的性能过程。压力测试(Stress Testing)是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。

    并发性能测试的目的主要体现在三个方面:以真实的业务为依据,选择有代表性的、关键的业务操作设计测试案例,以评价系统的当前性能;当扩展应用程序的功能或者新的应用程序将要被部署时,负载测试会帮助确定系统是否还能够处理期望的用户负载,以预测系统的未来性能;通过模拟成百上千个用户,重复执行和运行测试,可以确认性能瓶颈并优化和调整应用,目的在于寻找到瓶颈问题。

    网络端性能测试

    应用在网络上性能的测试重点是利用成熟先进的自动化技术进行网络应用性能监控、网络应用性能分析和网络预测。

    网络应用性能分析的目的是准确展示网络带宽、延迟、负载和TCP端口的变化是如何影响用户的响应时间的。

    网络应用性能监控

    在系统试运行之后,需要及时准确地了解网络上正在发生什么事情;什么应用在运行,如何运行;多少PC正在访问LAN或WAN;哪些应用程序导致系统瓶颈或资源竞争,这时网络应用性能监控以及网络资源管理对系统的正常稳定运行是非常关键的。利用网络应用性能监控工具,可以达到事半功倍的效果,在这方面我们可以提供的工具是Network Vantage。通俗地讲,它主要用来分析关键应用程序的性能,定位问题的根源是在客户端、服务器、应用程序还是网络。在大多数情况下用户较关心的问题还有哪些应用程序占用大量带宽,哪些用户产生了最大的网络流量,这个工具同样能满足要求。

    网络预测

    考虑到系统未来发展的扩展性,预测网络流量的变化、网络结构的变化对用户系统的影响非常重要。根据规划数据进行预测并及时提供网络性能预测数据。我们利用网络预测分析容量规划工具PREDICTOR可以作到:设置服务水平、完成日网络容量规划、离线测试网络、网络失效和容量极限分析、完成日常故障诊断、预测网络设备迁移和网络设备升级对整个网络的影响。

    从网络管理软件获取网络拓扑结构、从现有的流量监控软件获取流量信息(若没有这类软件可人工生成流量数据),这样可以得到现有网络的基本结构。在基本结构的基础上,可根据网络结构的变化、网络流量的变化生成报告和图表,说明这些变化是如何影响网络性能的。PREDICTOR提供如下信息:根据预测的结果帮助用户及时升级网络,避免因关键设备超过利用阀值导致系统性能下降;哪个网络设备需要升级,这样可减少网络延迟、避免网络瓶颈;根据预测的结果避免不必要的网络升级。

    服务器端性能测试

    对于应用在服务器上性能的测试,可以采用工具监控,也可以使用系统本身的监控命令,例如Tuxedo中可以使用Top命令监控资源使用情况。实施测试的目的是实现服务器设备、服务器操作系统、数据库系统、应用在服务器上性能的全面监控,测试原理如下图。

    UNIX资源监控指标和描述

    监控指标 描述

    平均负载 系统正常状态下,最后60秒同步进程的平均个数

    冲突率 在以太网上监测到的每秒冲突数

    进程/线程交换率 进程和线程之间每秒交换次数

    CPU利用率 CPU占用率(%)

    磁盘交换率 磁盘交换速率

    接收包错误率 接收以太网数据包时每秒错误数

    包输入率 每秒输入的以太网数据包数目

    中断速率 CPU每秒处理的中断数

    输出包错误率 发送以太网数据包时每秒错误数

    包输入率 每秒输出的以太网数据包数目

    读入内存页速率 物理内存中每秒读入内存页的数目

    写出内存页速率 每秒从物理内存中写到页文件中的内存页数

    目或者从物理内存中删掉的内存页数目

    内存页交换速率 每秒写入内存页和从物理内存中读出页的个数

    进程入交换率 交换区输入的进程数目

    进程出交换率 交换区输出的进程数目

    系统CPU利用率 系统的CPU占用率(%)

    用户CPU利用率 用户模式下的CPU占用率(%)

    磁盘阻塞 磁盘每秒阻塞的字节数

    分析优化性能思路流程

    性能测试总结

    1、硬件上的性能瓶颈:

    一般指的是CPU、内存、磁盘读写等的瓶颈,为服务器硬件瓶颈。

    2、应用软件上的性能瓶颈:

    一般指的是服务器操作系统瓶颈(参数配置)、数据库瓶颈(参数配置)、web服务器瓶颈(参数配置)、中间件瓶颈(参数配置)等

    3、应用程序上的性能瓶颈:

    一般指的是开发人员,开发出来的应用程序(如sql语句、数据库设计、业务逻辑、算法等)。

    4、操作系统上的性能瓶颈:

    一般指的是Windows、linux等操作系统,如出现物理内存不足时,或虚拟内存设置不合理(虚拟内存设置不合理,会导致虚拟内存的交换率大大降低,从而导致行为的响应时间大大增加,可以认为在操作系统上出现了性能瓶颈)。

    5、网络设备上的性能瓶颈:

    一般指的是防火墙、动态负载均衡器、交换机等设备。

    2.安全测试

    安全测试是一个相对独立的领域,需要更多的专业知识。如:WEB的安全测试、需要熟悉各种网络协议、防火墙、CDN、熟悉各种操作系统的漏洞、熟悉路由器等。

    采用成熟的网络漏洞检查工具检查系统相关漏洞(即用最专业的黑客攻击工具攻击试一下,现在最常用的是 NBSI 系列和 IPhacker IP )

    安全测试主要是根据对应的项目来进行的安全测试用例设计及编写后执行安全测试。比如主要是对用户登录的校验、密码是否加密、权限;设计充值、提现等必须是否绑定手机号的短信验证码校验等;需要实名认证的,甚至人脸识别技术等;做压力测试的时候,比如需要考虑同一个IP地址的请求过多或频繁,需要有对应的判断是否为恶意攻击及判断后的相应解决措施等。

    3.兼容性测试

    兼容性测试主要是指,软件之间能否很好的运作,会不会有影响、软件和硬件之间能否发挥很好的效率工作,会不会影响导致系统的崩溃。

    平台测试

    浏览器测试

    软件本身能否向前或向后兼容

    测试软件能否与其它相关软件兼容

    数据兼容性测试

    最常见的兼容性测试就是浏览器的兼容性测试,不同浏览器在css,js解析上的不同会导致页面显示不同。

    常见的IE8的兼容性。

    4.文档测试

    国家有关计算机软件产品开发文件编制指南中共有14种文件,可分为3大类。

    开发文件:可行性研究报告、软件需求说明书、数据要求说明书、概要设计说明书、详细设计说明书、数据库设计说明书、模块开发卷宗。

    用户文件:用户手册、操作手册,用户文档的作用:改善易安装性;改善软件的易学性与易用性;改善软件可靠性;降低技术支持成本。

    管理文件:项目开发计划、测试计划、测试分析报告、开发进度月报、项目开发总结报告。

    在实际的测试中,最常见的就是用户文件的测试,例如:手册说明书等。

    文档测试关注的点:

    文档的术语

    文档的正确性

    文档的完整性

    文档的一致性

    文档的易用性

    5.易用性测试(用户体验测试)

    易用性(Useability)是交互的适应性、功能性和有效性的集中体现。又叫用户体验测试。

    6.业务测试

    业务测试是指:测试人员将系统的整个模块串接起来运行、模拟真实用户实际的工作流程。满足用户需求定义的功能来进行测试的过程。

    7.界面测试

    界面测试(简称UI测试),测试用户界面的功能模块的布局是否合理、整体风格是否一致、各个控件的放置位置是否符合客户使用习惯,此外还要测试界面操作便捷性、导航简单易懂性,页面元素的可用性,界面中文字是否正确,命名是否统一,页面是否美观,文字、图片组合是否完美等。

    8.安装与卸载测试

    安装测试是指:测试程序的安装、卸载。最典型的就是APP的安装、卸载。

    9.内存泄漏测试

    内存泄漏的检测:

    1、对于不同的程序可以使用不同的方法来进行内存泄露的检查,还可以使用一些专门的工具来进行内存问题的检查,例如MemProof. AQTime、Purify、BundsChecker等。 有些开发工具本身就带有内存问题检查机制.要确保程序员在编写程序和编译程序的时候打开这些功能。

    2、通过代码扫描分析工具来检查

    按测试实施组织的角度划分

    注:alpha测试和beta测试不能由程序员和测试员完成。

    1.α测试(Alpha Testing)

    α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试。

    α测试的目的是评价软件产品的FLURPS(即功能、局域化、可使用性、可靠性、性能和支持)。

    2.β测试(Beta Testing)

    Beta测试是一种验收测试。Beta测试由软件的最终用户们在一个或多个客户场所进行。

    α测试与Beta测试的区别:

    (1)测试的场所不同:Alpha测试是指把用户请到开发方的场所来测试,beta测试是指在一个或多个用户的场所进行的测试。

    (2)Alpha测试的环境是受开发方控制的,用户的数量相对比较少,时间比较集中。beta测试的环境是不受开发方控制的,用户数量相对比较多,时间不集中。

    (3)alpha测试先于beta测试执行。通用的软件产品需要较大规模的beta测试,测试周期比较长。

    3.第三方测试

    介于开发方和用户方之间的组织测试。

    按是否手工执行测试的角度划分

    1.手工测试(Manual testing)

    手工测试是由人一个一个的输入用例,然后观察结果,和机器测试相对应,属于比较原始但是必须的一个步骤。

    由专门的测试人员从用户视角来验证软件是否满足设计要求的行为。 
    更适用针对深度的测试和强调主观判断的测试 
    比如:众包测试和探索式测试

    优点:自动化测试无法代替探索性测试、发散思维类无既定结果的测试。

    缺点:执行效率慢,量大易错。

    2.自动化测试(Automation Testing)

    定义

    所谓自动化测试,就是在预设条件下运行系统或应用程序,评估运行结果。(预先条件包括:正常条件和异常条件)。简单来说,自动化测试就是是把人为驱动的测试行为,转化为机器执行的一种过程。通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的规程一步步执行测试,得到实际结果与期望结果的比较。在此过程中,为了节省人力、时间或硬件资源,提高测试效率,便引入了自动化测试的概念。

    分类

    自动化测试有:功能测试自动化、性能测试自动化、安全测试自动化。(一般情况下,我们说的自动化是指功能测试的自动化)

    自动化测试按照测试对象来分,还可以分为接口测试、UI测试等。接口测试的ROI(产出投入比)要比UI测试高。

    优点

     

     

    缺点

     

    适用范围

    自动化测试可以涉及和试用的范围主要在以下方面:

    基于Web UI的浏览器应用的界面测试

    基于WebService或者WebAPI的服务契约测试

    基于WCF、.net remoting、Spring等框架的服务的集成测试

    基于APP UI的移动应用界面测试

    基于Java、C#等编程文件进行的单元测试

    前提条件

    实施自动化测试之前需要对软件开发过程进行分析,以观察其是否适合使用自动化测试。通常需要同时满足以下条件:

    1) 需求变动不频繁;

    测试脚本的稳定性决定了自动化测试的维护成本。如果软件需求变动过于频繁,测试人员需要根据变动的需求来更新测试用例以及相关的测试脚本,而脚本的维护本身就是一个代码开发的过程,需要修改、调试,必要的时候还要修改自动化测试的框架,如果所花费的成本不低于利用其节省的测试成本,那么自动化测试便是失败的。项目中的某些模块相对稳定,而某些模块需求变动性很大。我们便可对相对稳定的模块进行自动化测试,而变动较大的仍是用手工测试。

    2) 项目周期足够长;

    自动化测试需求的确定、自动化测试框架的设计、测试脚本的编写与调试均需要相当长的时间来完成,这样的过程本身就是一个测试软件的开发过程,需要较长的时间来完成。如果项目的周期比较短,没有足够的时间去支持这样一个过程,那么自动化测试便成为笑谈。

    3) 自动化测试脚本可重复使用

    如果费尽心思开发了一套近乎完美的自动化测试脚本,但是脚本的重复使用率很低,致使其间所耗费的成本大于所创造的经济价值,自动化测试便成为了测试人员的练手之作,而并非是真正可产生效益的测试手段了。

    另外,在手工测试无法完成,需要投入大量时间与人力时也需要考虑引入自动化测试。比如性能测试、配置测试、大数据量输入测试等。

    适合场景

    通常适合于软件测试自动化的场合:

    (1)回归测试,重复单一的数据录入或是击键等测试操作造成了不必要的时间浪费和人力浪费;

    (2)此外测试人员对程序的理解和对设计文档的验证通常也要借助于测试自动化工具;

    (3)采用自动化测试工具有利于测试报告文档的生成和版本的连贯性;

    (4)自动化工具能够确定测试用例的覆盖路径,确定测试用例集对程序逻辑流程和控制流程的覆盖。

     

    注:自动化测试更适合用于回归测试,而不是用来发现新bug。

    自动化测试的流程

    测试计划:划定自动化测试的范围包含哪些需求,涉及到哪些测试过程

    测试策略:确定自动化测试的工具、编程方案、代码管理、测试重点

    测试设计:使用测试设计方法对被测试的需求进行设计,得出测试的测试点、用例思维导图等

    测试实施:根据测试设计进行用例编写,并且将测试用例用编程的方式实现测试脚本

    测试执行:执行测试用例,运行测试脚本,生成测试结果

    自动化实施的步骤

    (1)完成功能测试,版本基本稳定

    (2)根据项目特性,选择适合项目的自动化工具,并搭建环境

    (3)提取手工测试的测试用例转换为自动化测试的用例

    (4)通过工具、代码实现自动化的构造输入、自动检测输出结果是否符合预期

    (5)生成自动测试报告

    (6)持续改进、脚本优化

    自动化测试模型

    可以分为线性测试、模块化与类库、数据驱动测试和关键字驱动测试。

    线性测试通过录制或编写对应程序的操作步骤会产生相应的线性脚本,即单纯地模拟用户完整的操作场景。

    模块化与类库式把重复的操作单独封装成公共模块,在测试用例执行过程中,当需要用到模块封装时对其进行调用,这样就最大限度地消除了重复,从而提高测试用例的可维护性。

    数据驱动测试的定义:数据的改变驱动自动化测试的执行,最终引起测试结果的改变。就是把数据驱动所需要的测试数据参数化,我们可以用多种方式来存储和管理这些参数化的数据。

    关键字驱动测试又被称为表驱动测试或基于动作字测试。这类框架会把自动化操作封装为“关键字”,避免测试人员直接接触代码,多以“填表格”的形式降低脚本的编写难度。

    自动化测试框架

    自动化测试架构思想做一个对比:

    1)数据驱动测试:

       其思想是将我们的自动化测试脚本和测试数据放在共同的测试架构中,提供可重用的测试逻辑。这样做的目的是减少测试维护的工作量以及便于改善测试用例的覆盖率。测试用例需要输入的测试数据和测试完成后的测试结果数据都会被存储在同一个数据库或者数据源中,并且将测试的数据和测试逻辑分开。这样测试数据发生了变化时不会影响到我们的测试逻辑,并且同一套测试逻辑可以针对多种数据来进行测试,尽量提高测试逻辑的使用效率和复用效率。

    2)模块驱动测试:

       其思想是使用独立的脚本或者代码来对应每一个待测试的模块单元和功能。模块驱动测试引入的是编程语言中的面向对象编程中的抽象和模块独立封装的思想,即将测试代码和每一个测试模块进行解耦,减低自动化测试脚本或者自动化测试代码的维护成本,同时增加可扩展性。

    3)关键字驱动测试:

    Robot Framework和RedwoodHQ就是一种典型的关键字驱动测试的框架模式。关键字驱动测试通常也被认为是表格驱动测试,通过在表格中调用关键字来实现自动化测试。这种设计思想一般会将自动化测试拆分为设计和实现两个不同的阶段。

    4)行为驱动开发测试(BDD):

       是一种敏捷开发的思想,使用简单的、特定于领域的脚本语言(DSL)将结构化自然语言语句转换为通俗易懂的可执行测试。行为驱动开发的根基是一种“通用语言”,通俗易懂,同时被客户和开发者用来定义系统的行为。Cucumber就是一种行为驱动开发的自动化测试工具。

     

    自动化测试架构设计

     

    注:ant也可以换成maven,看项目代码是不是用maven

    分层自动化测试

     

    上图更多关注产品的UI层自动化测试,而分层自动化测试倡导产品不同阶段(层次)都需要自动化测试:

     

    unit :单元自动化测试,是对软件中最小的可测试单元进行检查与验证,如:C语言的最小的单元是一个元素,Java中最小的单元是一个类,图形化软件中的最小单元是一个窗口、按钮、菜单等。规范单元测试需要借助于单元测试框架(工具)

    单元测试(Code Review :中译 代码评审、代码审查):查找系统缺陷、保证软件真题质量,提高开发者自身水平。

    Service:接口自动化测试 分为:模块接口测试、web接口测试

    模块接口测试:测试模块间的调用与返回。如:类方法、函数调用并对返回结果进行验证

    Web接口测试:分为服务器接口测试、外部接口测试

    服务器接口测试:浏览器与服务器之间的接口,通过HTTP协议进行调用

    外部接口测试:调用接口,由第三方调用,如:调用微信、QQ、微博登陆接口

    UI层:是用户使用该产品的入口,所有功能都通过这一层提供并展示给用户,所以测试工作大多集中在这一层进行。为了减轻这一层的测试人力和时间成本,早期的自动化测试工具主要针对该层设计。

    除了UI层所展示的功能外,前端代码同样需要进行测试。在前端开发中最主要的是javascript脚本语言,而QUnit就是针对Javascript的一个强大的单元测试框架。

    分层自动化测试投入比例

    UI层自动化测试:投入比例小,原因:很难保证产品的质量,浪费人力、物力,因为越接近用户越容易变化

    什么样的项目适合自动化测试

    -任务测试明确,不会频繁变动。

    -每日构建后的测试验证。

    -比较频繁的回归测试。

    -软件系统界面稳定,变动少。

    -需要在多平台上运行的相同测试案例、组合遍历型的测试,大量的重复任务。

    -软件维护周期长。

    -项目进度压力不太大。

    -被测软件系统开发较为规范,能够保证系统的可测试性。

    -具备大量的自动化测试平台。

    -测试人员具备较强的编程能力。

    正常情况下满足三个:

    1、软件需求变动不频繁: 自动化脚本变化的大小、频率决定自动化维护成本,变化大,测试人员要进行扩展、修改、调试

    2、项目周期较长:需求确定,框架有好的设计,脚本开发调试时间较长

    3、自动化测试脚本可重复使用:测试项目之间是否存在很强的差异性,如:c/s、b/s之间的架构所展示的功能差不多,对脚本可重复使用,选用的技术、工具是否适应这种差异,测试人员是否有能力设计出满足条件的差异

    自动化测试及工具简述

    自动化测试的概念有广义和狭义之分:广义上讲:所有借助工具来辅助进行软件测试的方式都可以称为自动化测试;狭义上讲:主要是指基于UI层的功能自动化测试。

    1)UFT:(QTP:企业级自动化测试工具,提供强大、易用的录制回放功能,同时兼容对象和图像两种识别模式,支持B/S和C/S两种架构的软件测试 )

    2)Robot Framework:基于Python语言编写的自动化测试框架,具备良好的可扩展性,支持关键字驱动,同时可测试多种类型的客户端或接口,可进行移动端测试

    3)Watir:基于WEB测试,使用Roby语言开发

    4)Selenium:用于web应用程序测试工具,支持多平台,多浏览器,多语言去实现自动化测试

    下来我们探讨一下主流的自动化测试方案,无一例外,都有人机沟通的编程语言,加上机器操作的工具来组成。

    功能自动化测试

    VBScript + QTP(HP UFT),商用功能自动化测试方案

    Python/PHP/Java/C#/JavaScprit/Ruby + Selenium/Appium + 单元测试框架,开源功能自动化测试方案

    这里我们多介绍一点,Selenium/Appium 本身不能算是测试工具,而只是机器用来操作浏览器的工具,并且这个工具能听懂多种语言:

    Java,C# 这两个重 (zhòng) 语言

    Python,Ruby 这两个脚本轻语言

    PHP,JavaScript 这两个专门处理 Web 的语言

    工具外加指定的语言,可以让机器来操作浏览器,但是到此时还无法做到测试,于是才需要每个语言自己的单元测试框架,来一起完成这个功能自动化测试方案的构建。

    此外,业界还一种暂时临时的方案,就是 Python 2 + Robot Framework + Selenium Library 插件 + 单元测试框架 构成的一种测试方案,这个方案笔者不是非常推荐,主要基于两点:

    理念:这是一种基于关键字的方案,那么关键字是 QTP(HP UFT)的特长,并不是Selenium的本意

    Python/Java/C#/JavaScprit/Ruby + Gauge,又一款开源的功能自动化测试方案

    Thoughtworks 的基于BDD理念的自动化测试工具

    Gauge 本身就是完整的测试方案

    Gauge 是从需求分析师(BA)到测试工程师(QA)都覆盖的测试方案

    Java/Python + Macaca,阿里巴巴的功能自动化测试方案,缺点是文档少

    JavaScript + TestCafe,DevExpress 的开源功能自动化测试方案

    pure node.js - TestCafe不使用Selenium,并且不需要插件来在实际浏览器中运行测试。 它建立在node.js的顶部,因此它与现代开发工具集成和工作良好

    无需额外的设置或配置- TestCafe是所有设置后立即运行测试npm install

    完整的测试工具 - 使用单个启动命令,TestCafe启动浏览器,运行测试,收集结果并生成报告

    JavaScript + Postman,免费的Web接口功能自动化测试方案

    Groovy + SoapUI,开源的Web接口功能自动化测试方案

    性能自动化测试

    Java/C + HP LoadRunner,商业版性能测试方案

    Java + JMeter,开源版性能测试方案

    Python + locust,开源版性能测试方案

    学习自动化测试技术心得
    一、自动化测试的学习步骤

    1. 做好手工测试(了解各种测试的知识)->  2. 学习编程语言-> 3. 学习Web基础-> 4. 学习自动化测试工具 ->5. 学习自动化测试框架 -> 6. 实现自动化测试用例 -> 7. 开发自动化测试工具 ->8. 开发自动化测试框架

    按照这个步骤来说,基本上到第7步,难度就比较大了,这个时候也可以称呼自己为“测试开发”。

    二、自动化测试需要掌握的技术能力

    一、首先要学会一门语言,java或者Python,这里针对Python去说。如果要能够满足自动化测试的需求,不要求Python的能力上来就达到精通的水平,但是最起码的使用是要有的,然后在后期在逐步根据测试工具进行进阶。

    二、需要掌握前端的一些知识,无论学习语言还是前端知识,都是为了接下来的脚本和框架做铺垫。

    三、数据库的重要性不言而喻,MySQL必须掌握

    四、web端自动化测试工具selenium

    五、接口测试自动化工具jmeter、postman等

    六、移动端自动化测试appium

    在这里主要就是把自动化划分为了web自动化测试、接口自动化和移动端自动化。

    三、自动化测试的认识误区

    1、自动化的软件测试与手工的软件测试过程一样

    自动化测试所需要的技巧与手工测试所需要的技巧是不一样的。

    通常,你的项目经理会被那些测试工具销售们迷惑,认为自动化的软件测试就是简单地按一个录制的按钮,产生测试脚本。而事实上并没有那么简单。

    区分自动化测试所需要的技巧与手工测试所需要的技巧是非常重要的。最重要的是,自动化测试工程师需要掌握软件开发技巧,没有接受任何培训的手工测试人员,或者没有编程背景的手工测试人员,在实施自动化测试时会碰到很多困难。

    2、自动化测试一定会马上大量减少测试人员数量

    自动化测试不会马上大量减少测试人员数量。因为开展自动化测试初期需要投入一定的人力进行自动化测试脚本开发,并逐渐将自动化测试脚本用于日常的测试中,逐步减少手工测试人员从事重复劳动的时间和人数。为了缩短自动化测试脚本的开发时间,可以考虑将自动化测试脚本的开发工作借助外包的力量来早日实现大规模的自动化测试。

    3、测试自动化就是录制和回放

    仅仅录制得到的不是有效的自动化脚本。

    很多项目经理仍然把测试自动化等同于使用录制回放工具。而事实上,录制得到的脚本通常是不可重用的脚本,脚本中充满了硬编码的值,这些值应该被参数化,否则脚本仅仅适用于一个测试情况,脚本还应该加入条件判断、循环等结构,以便增强测试脚本的灵活性。

    4、自动化测试找不到bug

    自动化测试不直接找bug,而是通过解放有经验的测试工程师的生产力,让其从重复的回归测试中解放出来,从事新的测试方法和测试手段的研究。通过自动化测试解放出测试人员的时间和精力来间接地找到更多、更深层次的新bug,将产品质量再提高一个档次。

    5、自动化测试工具是“万能”的

    很多人一听到自动化测试,就认为自动化测试工具可以完成一切测试工作,从测试计划到测试执行再到测试结果分析,都不需要任何人工干预。显然,这是一种理想状态,现实中还没有哪个测试工具有这个能力,并且将来也不会有。在现实中有关的测试设计、测试案例,以及一些关键的测试任务还是需要人工参与的,即自动化测试是对手工测试的辅助和补充,它永远也不可能完全取代手工测试。

    6、自动化测试工具容易使用

    对于这一点,很多测试工程师有同样的错误观点,认为测试工具可以简单地通过捕获(录制)客户端操作生成脚本,且脚本不加编辑就可用于回放使用。事实上,自动化测试不是那么简单的,捕获的操作是否正确,以及脚本编辑是否合理都会影响测试结果。因此,自动化测试需要更多的技能,也需要更多的培训。

    7、自动化能提供百分百的测试覆盖率

    并非所有内容都可以被自动化地测试到。不可能覆盖所有可能的输入,所有可能的组合和路径。

    自动化测试可以增加测试的广度和深度,但是仍然无法达到100%的测试覆盖率,因为没有足够的时间或资源。

    8、忘记了测试的最终目标:找到BUG

    在自动化测试中,同样要注意把边界值分析、等价类分析、基于风险的测试方法、挑选最合适的测试用例等技术应用起来。

    通常在自动化测试过程中,我们都忙着搭建自动化框架和编写测试脚本,但是我们往往忘记了测试的本来目的:找bug。

    项目经理可能雇佣了最好的自动化开发人员来搭建框架,使用了最新最好的自动化开发技术,创建了成千上万的自动化测试脚本。但是如果BUG仍然被遗漏了,那些本该被自动化测试脚本捕捉到的BUG,结果没有被捕捉到,那么你的自动化测试仍然会被认为是失败的。

    9、所有测试用例都可以自动化

    不是所有的测试用例和测试步骤都可以转化为自动化测试。在自动化测试投入较多的行业,领先企业的自动化测试率有的能达到80%左右,但仍有20%左右的测试用例需要手工来进行。在国外,通常从开发第一版测试用例时,就同步进行自动化测试脚本的开发,所以自动化测试率普遍比中国企业高。

    10、只有性能测试才需要自动化

    自动化测试不光进行性能测试,更被大量应用于功能测试验证,在国外超过半数的自动化测试脚本都是用于功能验证测试的。

    11、测试工具可适用于所有的测试

    每种自动化测试工具都有它的应用范围和可用对象,所以不能认为一种自动化测试工具能够满足所有测试的需求。针对不同的测试目的和测试对象,应该选择合适的测试工具来对它进行测试。在很多情况下,需要利用多种测试工具或者开发自动化测试框架才能达到自动化测试的目的。商业和开源的测试工具能够用来进行自动化测试,但是我们需要根据自身产品的特点,开发自动化测试框架,在框架中提供常用的测试用例,加快测试速度,达到测试用例复用,这是今后测试自动化发展的道路。

    12、自动化测试能发现大量新缺陷

    发现更多的新缺陷应该是手工测试的主要目的,不能期望自动化测试去发现更多新缺陷。事实上,自动化测试主要用于发现原来的缺陷。自动化测试用于回归测试,而大量的新业务测试更多地还是依赖手工测试。

    除了以上列举的常见误区外,还有其他不同的认识误区。自动化测试认识误区的产生,归根到底最本质的原因是由于对自动化测试不现实的期望,也就是期望过高造成的。

    3.手工测试和自动化测试的区别

     

    按测试地域的角度划分

    1.国际化测试

    软件的国际化和软件的本地化是开发面向全球不同地区用户使用的软件系统的两个过程。而本地化测试和国际化测试则是针对这类软件产品进行的测试。由于软件的全球化普及,还有软件外包行业的兴起,软件的本地化和国际化测试俨然成为了一个独特的测试专门领域。

    本地化和国际化测试与其他类型的测试存在很多不同之处。下面是本地化和国际化测试 的一些要点。

    1、本地化后的软件在外观上与原来版本是否存在很大的差异,外观是否墼齐、不走样。

    2、是否对所有界面元素都进行了本地化处理,包括对话框、菜单、工具栏、状态栏、提示信息(包括声音的提示)、日志等。

    3、在不同的屏幕分辨率下界面是否正常显示。

    4、是否存在不同的字体大小,字体设置是否恰当。

    5、日期、数字格式、货币等是否能适应不同国家的文化习俗。例如,中文是年月日,而英文是月日年。

    6、排序的方式是否考虑了不同语言的特点。例如,中文按照第一个字的汉语拼音顺序排序,而英文按照首字母排序。

    7、在不同的国家采用不同的度量单位,软件是否能自适应和转换。

    8、软件是否能在不同类型的硬件上正常运行,特别是在当地市场上销售的流行硬件上。

    9、软件是否能在Windows或者其他操作系统的当地版本上正常运行。

    10、联机帮助和文档是否已经翻译,翻译后的链接是否正常。正文翻译是否正确、恰当, 是否有语法错误。

    软件本地化和国际化测试是一个综合了翻译行业和软件测试行业的测试类型。它要求测 试人员具备一定的翻译能力、语言文化,同时具备测试人员的基本技能。

    2.本地化测试

    之前我们一起学习的测试都是本地化测试。

    * 测试过程按4个步骤进行,即单元测试、集成测试、确认测试和系统测试及发布测试。

    * 开始是单元测试,集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。

    *集成测试把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。

    * 确认测试则是要检查已实现的软件是否满足了需求规格说明中确定了的各种需求,以及软件配置是否完全、正确。

    * 系统测试把已经经过确认的软件纳入实际运行环境中,与其它系统成份组合在一起进行测试。

    单元测试 (Unit Testing)

    * 单元测试又称模块测试,是针对软件设计的最小单位 ─ 程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。

    * 单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。

    1. 单元测试的内容

    * 在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/O条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应。

    (1) 模块接口测试

    * 在单元测试的开始,应对通过被测模块的数据流进行测试。测试项目包括:

    – 调用本模块的输入参数是否正确;

    – 本模块调用子模块时输入给子模块的参数是否正确;

    – 全局量的定义在各模块中是否一致

    * 在做内外存交换时要考虑:

    – 文件属性是否正确;

    – OPEN与CLOSE语句是否正确;

    – 缓冲区容量与记录长度是否匹配;

    – 在进行读写操作之前是否打开了文件;

    – 在结束文件处理时是否关闭了文件;

    – 正文书写/输入错误,

    – I/O错误是否检查并做了处理。

    (2) 局部数据结构测试

    * 不正确或不一致的数据类型说明

    * 使用尚未赋值或尚未初始化的变量

    * 错误的初始值或错误的缺省值

    * 变量名拼写错或书写错

    * 不一致的数据类型

    * 全局数据对模块的影响

    (3) 路径测试

    * 选择适当的测试用例,对模块中重要的执行路径进行测试。

    * 应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误。

    * 对基本执行路径和循环进行测试可以发现大量的路径错误。

    (4) 错误处理测试

    * 出错的描述是否难以理解

    * 出错的描述是否能够对错误定位

    * 显示的错误与实际的错误是否相符

    * 对错误条件的处理正确与否

    * 在对错误进行处理之前,错误条件是否已经引起系统的干预等

    (5) 边界测试

    * 注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性。对这些地方要仔细地选择测试用例,认真加以测试。

    * 如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素。

    2. 单元测试的步骤

    * 模块并不是一个独立的程序,在考虑测试模块时,同时要考虑它和外界的联系,用一些辅助模块去模拟与被测模块相联系的其它模块。

    – 驱动模块 (driver)

    – 桩模块 (stub) ── 存根模块

    * 如果一个模块要完成多种功能,可以将这个模块看成由几个小程序组成。必须对其中的每个小程序先进行单元测试要做的工作,对关键模块还要做性能测试。

    * 对支持某些标准规程的程序,更要着手进行互联测试。有人把这种情况特别称为模块测试,以区别单元测试。

    集成测试(Integrated Testing)

    * 集成测试 (组装测试、联合测试)

    * 通常,在单元测试的基础上,需要将所有模块按照设计要求组装成为系统。这时需要考虑的问题是:

    – 在把各个模块连接起来的时候,穿越模块接口的数据是否会丢失;

    – 一个模块的功能是否会对另一个模块的功能产生不利的影响

    – 各个子功能组合起来,能否达到预期要求的父功能;

    – 全局数据结构是否有问题;

    – 单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。

    在单元测试的同时可进行集成测试,发现并排除在模块连接中可能出现的问题,最终构成要求的软件系统。

    * 子系统的集成测试特别称为部件测试,它所做的工作是要找出集成后的子系统与系统需求规格说明之间的不一致。

    * 通常,把模块集成成为系统的方式有两种

    – 一次性集成方式

    – 增殖式集成方式

    1. 一次性集成方式(big bang)

    * 它是一种非增殖式组装方式。也叫做整体拼装。

    * 使用这种方式,首先对每个模块分别进行模块测试,然后再把所有模块组装在一起进行测试,最终得到要求的软件系统。

    2. 增殖式集成方式

    * 这种集成方式又称渐增式集成

    * 首先对一个个模块进行模块测试,然后将这些模块逐步组装成较大的系统

    * 在集成的过程中边连接边测试,以发现连接过程中产生的问题

    * 通过增殖逐步组装成为要求的软件系统。

    (1) 自顶向下的增殖方式

    * 这种集成方式将模块按系统程序结构,沿控制层次自顶向下进行组装。

    * 自顶向下的增殖方式在测试过程中较早地验证了主要的控制和判断点。

    * 选用按深度方向组装的方式,可以首先实现和验证一个完整的软件功能。

    (2) 自底向上的增殖方式

    * 这种集成的方式是从程序模块结构的最底层的模块开始集成和测试。

    * 因为模块是自底向上进行组装,对于一个给定层次的模块,它的子模块(包括子模块的所有下属模块)已经组装并测试完成,所以不再需要桩模块。在模块的测试过程中需要从子模块得到的信息可以直接运行子模块得到。

    * 自顶向下增殖的方式和自底向上增殖的方式各有优缺点。

    * 一般来讲,一种方式的优点是另一种方式的缺点。

    (3) 混合增殖式测试

    * 衍变的自顶向下的增殖测试

    – 首先对输入/输出模块和引入新算法模块进行测试;

    – 再自底向上组装成为功能相当完整且相对独立的子系统;

    – 然后由主模块开始自顶向下进行增殖测试。

    * 自底向上-自顶向下的增殖测试

    – 首先对含读操作的子系统自底向上直至根结点模块进行组装和测试;

    – 然后对含写操作的子系统做自顶向下的组装与测试。

    * 回归测试

    – 这种方式采取自顶向下的方式测试被修改的模块及其子模块;

    – 然后将这一部分视为子系统,再自底向上测试。

    关键模块问题

    * 在组装测试时,应当确定关键模块,对这些关键模块及早进行测试。

    * 关键模块的特征:

    ① 满足某些软件需求

    ② 在程序的模块结构中位于较高的层次(高层控制模块)

    ③ 较复杂、较易发生错误

    ④ 有明确定义的性能要求。

    确认测试(Validation Testing)

    * 确认测试又称有效性测试。任务是验证软件的功能和性能及其它特性是否与用户的要求一致。

    * 对软件的功能和性能要求在软件需求规格说明书中已经明确规定。它包含的信息就是软件确认测试的基础。

    1. 进行有效性测试(黑盒测试)

    * 有效性测试是在模拟的环境 (可能就是开发的环境) 下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。

    * 首先制定测试计划,规定要做测试的种类。还需要制定一组测试步骤,描述具体的测试用例。

    * 通过实施预定的测试计划和测试步骤,确定

    – 软件的特性是否与需求相符;

    – 所有的文档都是正确且便于使用;

    – 同时,对其它软件需求,例如可移植性、兼容性、出错自动恢复、可维护性等,也都要进行测试

    * 在全部软件测试的测试用例运行完后,所有的测试结果可以分为两类:

    – 测试结果与预期的结果相符。这说明软件的这部分功能或性能特征与需求规格说明书相符合,从而这部分程序被接受。

    – 测试结果与预期的结果不符。这说明软件的这部分功能或性能特征与需求规格说明不一致,因此要为它提交一份问题报告。

    2. 软件配置复查

    软件配置复查的目的是保证软件配置的所有成分都齐全;

    各方面的质量都符合要求;

    具有维护阶段所必需的细节;

    而且已经编排好分类的目录。

    应当严格遵守用户手册和操作手册中规定的使用步骤,以便检查这些文档资料的完整性和正确性。

    系统测试(System Testing)

    * 系统测试,是将通过确认测试的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其它系统元素结合在一起,在实际运行环境下,对计算机系统进行一系列的组装测试和确认测试。

    * 系统测试的目的在于通过与系统的需求定义作比较, 发现软件与系统的定义不符合或与之矛盾的地方。

    验收测试(Acceptance Testing)

    * 在通过了系统的有效性测试及软件配置审查之后,就应开始系统的验收测试。

    * 验收测试是以用户为主的测试。软件开发人员和QA(质量保证)人员也应参加。

    * 由用户参加设计测试用例,使用生产中的实际数据进行测试。

    * 在测试过程中,除了考虑软件的功能和性能外,还应对软件的可移植性、兼容性、可维护性、错误的恢复功能等进行确认。

    *确认测试应交付的文档有:

    – 确认测试分析报告

    – 最终的用户手册和操作手册

    – 项目开发总结报告。

    其他汇总

    1.回归测试(Regression Testing)

    回归测试指修改了旧的代码之后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。(自动回归测试将大幅度降低系统测试、维护升级等阶段的成本)。在软件变更之后,对软件重新进行的测试。其目标是检验对软件进行的修改是否正确,保证改动不会带来不可预料的行为或者另外的错误。

    在整个软件测试过程中占有很大的工作比重,软件开发的各个阶段都会进行多次回归测试。随着系统的庞大,回归测试的成本越来越大,通过正确的回归测试策略来改进回归测试的效率和有效性是很有意义的。

    2.冒烟测试(smoke testing)

    该术语来自硬件,指对一个硬件或一组硬件进行更改或修复后,直接给设备加电。如果没有冒烟,则该组件就通过了测试,也可以理解为该种测试耗时短,仅用一袋烟的功夫就足够了。

    在《微软项目求生法则》一书第14章“构建过程”关于冒烟测试,就是开发人员在个人版本的软件上执行目前的冒烟测试项目,确定新的程序代码不出故障。

    冒烟测试的对象是每一个新编译的需要正式测试的软件版本,目的是确认软件基本功能正常,可以进行后续正式的测试工作。

    冒烟测试的执行者是版本编译人。现基本执行对象为测试人员,在正规测试一个新版本之前,投入较少的人力和时间验证基本功能,通过则测试准入。

    冒烟测试一般在开发人员开发完毕后送给测试人员来进行测试时,测试人员会先进行冒烟测试,保证基本功能正常,不阻碍后续测试。

    3.接口测试

     原理:模拟客户端向服务器发送请求报文,服务器接收请求报文后对相应的报文做处理并向客户端返回应答,客户端接收应答的过程;

    重点:检查数据的交换,传递和控制管理过程,还包括处理的次数;

    核心:持续集成是接口测试的核心;

    优点:为高复杂性的平台带来高效的缺陷监测和质量监督能力,平台越复杂,系统越庞大,接口测试的效果越明显(提高测试效率,提升用户体验,降低研发成本);

     

    接口的定义

    接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。

    直白点讲就是:通过测试不同情况下的入参与之相对应的出参信息来判断接口是否和符合或满足相应的功能性、安全性要求。

    接口测试的目的

    接口测试的目的是测试接口的正确性和稳定性,尤其是那些与系统相关联的外部接口,测试的重点是要检查数据的交换,传递和控制管理过程,还包括处理的次数。外部接口测试一般是作为系统测试来看待的。

     

    接口通信过程

     

    接口类型

    接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。
    系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们写好的方法来获取数据,你引用他提供的接口就能使用他写好的方法,从而达到数据共享的目的,比如说咱们用的app、网址这些它在进行数据处理的时候都是通过接口来进行调用的。
    程序内部的接口:方法与方法之间,模块与模块之间的交互,程序内部抛出的接口,比如bbs系统,有登录模块、发帖模块等等,那你要发帖就必须先登录,要发帖就得登录,那么这两个模块就得有交互,它就会抛出一个接口,供内部系统进行调用。

     

     

     

     

     

    接口协议分类及特点

    接口的分类:1.webservice接口 2.http api接口

    webService接口是走soap协议通过http传输,请求报文和返回报文都是xml格式的,我们在测试的时候都用通过工具才能进行调用,测试。

    http api接口是走http协议,通过路径来区分调用的方法,请求报文都是key-value形式的,返回报文一般都是json串,有get和post等方法,这也是最常用的两种请求方式。

    json是一种通用的数据类型,所有的语言都认识它。(json的本质是字符串,他与其他语言无关,只是可以经过稍稍加工可以转换成其他语言的数据类型,比如可以转换成Python中的字典,key-value的形式,可以转换成JavaScript中的原生对象,可以转换成java中的类对象等。)

     

    接口测试工具

    1、webService接口:可以使用的工具有SoapUI、jmeter、loadrunner等;webservice接口开发框架:Axis2、cxf、xfire

    2、http api接口:可以使用的工具有postman、RESTClient、jmeter、loadrunner等;

    Mozilla Firefox下的两款接口测试工具RESTClient和HttpRequester。

    Google chrome下的三款接口测试工具Advanced REST Client和Postman和RESTED。

    接口测试的类型

    主要包含三种测试:

    Web接口测试;

    应用程序接口(API, application programming interface)测试;

    数据库测试。

    实际上意义就是UI界面到数据库之间,数据流经过的所有过程。

    接口测试用例设计

    用例设计重点:通常情况下主要测试最外层的两类接口:数据进入系统接口(调用外部系统的参数为本系统使用)和数据流出系统接口(验证系统处理后的数据是否正常)

     

    接口测试主要是在开发接口联调完毕后进行接口测试;当接口测试通过后,进入系统集成测试阶段,先冒烟测试通过后再进行功能测试,等到回归测试且系统比较稳定后,达到能进行对应的业务功能全链路的UI自动化测试和接口自动化等;

    接口测试质量评估标准

      1. 业务功能覆盖是否完整

      2. 业务规则覆盖是否完整

      3. 参数验证是否达到要求(边界、业务规则)

      4. 接口异常场景覆盖是否完整

      5. 接口覆盖率是否达到要求

      6.  代码覆盖率是否达到要求

      7. 性能指标是否满足要求

      8. 安全指标是否满足要求

    其他关联知识
    get请求,post请求的区别:

    1、GET使用URL或Cookie传参。而POST将数据放在BODY中。
    2、GET的URL会有长度上的限制,则POST的数据则可以非常大。
    3、POST比GET安全,因为数据在地址栏上不可见。而post只有条件数据在url上。
    4、一般get请求用来获取数据,post请求用来发送数据。
    其实上面这几点,只有最后一点说的是比较靠谱的,第一点post请求也可以把数据放到url里面,get请求其实也没长度限制,post请求看起来参数是隐式的,稍微安全那么一些些,但是那只是对于小白用户来说的,就算post请求,你通过抓包也是可以抓到参数的。(唯一区别就是这一点,上面3点区别都是不准确的)

    Get请求方法:可以比喻成发送一次请求给服务器就完事了。

    Post请求方法:

     

    可以比喻成发送两次请求给服务器,第一次先把header信息头发送给服务器,服务器返回同意你发body信息给他了,然后客户端再把body信息发送给服务器。

     

    http状态码:

    1、200 2开头的都表示这个请求发送成功,最常见的就是200,就代表这个请求是ok的,服务器也返回了。
    2、300 3开头的代表重定向,最常见的是302,把这个请求重定向到别的地方了。
    3、400 400代表客户端发送的请求有语法错误,401代表访问的页面没有授权,403表示没有权限访问这个页面,404代表没有这个页面。
    4、500 5开头的代表服务器有异常,500代表服务器内部异常,504代表服务器端超时,没返回结果。

    webservice接口怎么测试:

    它不需要你在拼报文了,会给一个webservice的地址,或者wsdl文件,直接在soapui导入,就可以看到这个webservice里面的所有接口,也有报文,直接填入参数调用,看返回结果就可以了。

    cookie与session的区别:

    1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

    2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。

    3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。

    4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

    5、所以个人建议:将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中

    确认测试

    确认测试:又称有效性测试。其任务就是确认软件的有效性,即确认软件的功能和性能及其它特性是否与用户的要求一致。这一阶段要做的主要工作是进行功能测试和软件配置复审。

    Alpha和Beta测试:Alpha测试是用户在开发环境下进行的测试,也可以是产品供应商内部的用户在模拟实际操作环境下进行的测试。软件在一个自然设置状态下使用,开发者坐在用户旁边,随时记下错误情况和使用中的问题。这是在受控制环境下进行的测试。Beta测试是由多个用户在一个或多个用户的实际使用环境下进行的测试。通常是在不受控制的环境下进行的测试,开发者通常不在现场。用户记录在测试过程中遇到的一切问题(真实的或想象的),并且定期把这些问题报告给开发者。

    随机测试(Ad-hoc Testing)

    随机测试主要是根据测试者的经验对软件进行功能和性能抽查。

    根据测试说明书执行用例测试的重要补充手段,是保证测试覆盖完整性的有效方式和过程。

    随机测试主要是对被测软件的一些重要功能进行复测,也包括测试那些当前的测试用例(TestCase)没有覆盖到的部分。

    安全测试(Security Testing) 

    安全测试是在IT软件产品的生命周期中,特别是产品开发基本完成到发布阶段,对产品进行检验以验证产品符合安全需求定义和产品质量标准的过程 。

    Findyou觉现在对安全知识的普及,大家意识都提上来了。比如现在越来越多的不支持HTTP协议,转用HTTPS等。

     探索性测试(Exploratory testing)

    探索性测试可以说是一种测试思维技术。它没有很多实际的测试方法、技术和工具,但是却是所有测试人员都应该掌握的一种测试思维方式。探索性强调测试人员的主观能动性,抛弃繁杂的测试计划和测试用例设计过程,强调在碰到问题时及时改变测试策略。

    探索性测试自动化暂时无法代替。Findyou也无法被代替。

    测试阶段

    测试流程

    测试用例

    定义

    软件测试用例的重要性

     

     

    测试用例设计及其选取

     

    如何编写软件测试用例

     

     

     

    软件测试应该具备的常识

     

    缺陷基本理论知识

    缺陷:软件表现与需求不符合的问题—bug /defect

    缺陷的属性

    1状态 :new(新的 ) 测试人员刚刚发现新缺陷

         Open(打开)   开发人员看到了这个缺陷

                Fixed(修复的)  开发人员已经修复了

                Reopen(重新打开) 测试验证没修复,重新给开发

               Close(关闭)  测试验证成功

    2严重程度 :致命的: 软件崩溃、死机、蓝屏

                         严重的: 出现多个问题的

                         一般的: 一个问题

                        轻微的: 界面的没对齐,错别字等

                        建议的: 使得软件完善的想法

    3优先级: 缺陷修改的优先次序

    4缺陷编号:标识缺陷

    5缺陷标题:缺陷的简单描述(在哪里发生了什么 )

    6缺陷描述: 步骤描述、预期和实际结果

    7 提交人:  缺陷发现

    8提交日期:发现缺陷的时间

    9附件 :   缺陷的截图

    10 分配人: 分配的开发

    缺陷跟踪流程: 缺陷和角色之间的跟踪顺序

     

    软件测试的基本理论知识

    定义

    软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。

    软件测试的标准定义是:使用人工或自动的手段来运行或测定某个软件系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。

    概念

    狭义的概念

    程序测试是为了发现错误而执行程序的过程。

    广义的概念

    “静态测试”和“动态测试”。这样,静态测试和动态测试就构成了一个全过程的、完整的软件测试,而且静态测试显得更为重要。

    静态测试的主要活动是评审,即通过对需求、设计、配置、程序和其他各类文档的审查来检验相应的内容是否满足用户的需求。由于静态测试不需要运行程序,所以测试对象是属于静态的. 
          动态测试通过运行程序来发现软件系统中的问题,在程序运行过程中发现缺陷,它具有动态性。

    测试目的

    软件测试的目的是发现问题,发现至今未发现的问题。检验软件系统(或者说是产品)是否满足需求。

     

    测试对象      

    软件测试是不等同于程序测试,软件测试贯穿于软件定义和开发的整个期间。需求分析,概要设计,详细设计以及程序编码等各个阶段所得到的文档,包括需求规格说明书、概要设计规格说明,详细设计规格说明以及源程序,都是软件测试的对象。

    1.程序。

    2.数据。

    3.文档。

    测试目标

    1.发现一些可以通过测试避免的开发风险。

    2.实施测试来降低所发现的风险。

    3.确定测试何时可以结束。

    4.在开发项目的过程中将测试看作是一个标准项目。

    测试原则

    1.所有的测试都应追溯到用户需求。

    2.尽早不断测试的原则:错误发现的越早,修正它所需的费用越少。 测试应该尽早进行,最好在需求阶段就开始介入,因为最严重的错误不外乎是系统不能满足用户的需求。我们常常强调软件测试人员应该站在客户的角度去进行测试,除了发现程序中的错误,还要发现需求定义的错误、设计规格说明书的缺陷。

    3.IPO原则:测试用例由测试输入数据,测试执行步骤和预期输出结果三部分组成。

    4.独立测试原则:程序员应避免检查自己的程序,程序设计机构也不应测试自己开发的程序,软件测试应该由第三方来负责。

    5.合法和非合法原则:设计测试用例时,应包括合法的输入条件和不合法的输入条件以及各种边界条件,特殊情况下还要制造极端状态和意外状态,如网络异常中断、电源断电等。

    6.错误群集原则:软件错误呈现群集现象。程序某部分存在更多的错误可能性与该部分已发现的错误的数量成正比。

    7.严格性原则:严格执行测试计划,排除测试的随意性。一定要制定严格的测试计划,并且要有指导性。测试时间安排尽量宽松,不要希望在极短的时间内完成一个高水平的测试。

    8.覆盖原则:应对每一个测试结果做全面的检查。对错误结果要进行一个确认过程。一般由A测试出来的错误,一定要由B来确认。严重的错误可以召开评审会议进行讨论和分析,对测试结果要进行严格地确认,是否真的存在这个问题以及严重程度等。

    9.定义功能测试原则:不仅要检查程序是否做了它该做的事,还要检查程序是否做了它不该做的事。

    10.回归测试原则:应妥善保留测试用例,不仅可以用于回归测试,也可以为以后的测试提供参考。妥善保存测试计划、测试用例、出错统计和最终分析报告,为维护提供方便。

    11.错误不可避免原则:在测试时不能首先假设程序中没有错误。

    测试内容

    从标准观点来看,可以定义为“验证”和“有效性确认”的活动所够成的整体,即软件测试=V&V

    “验证”是检验软件是否已正确地实现了软件需求规格说明书所定义的系统功能和特性。验证过程提供证据表明软件相关产品与所有生命周期活动的要求(如正确性、完整性、一致性、准确性等)一致。相当于以软件产品设计规格说明书为标准进行软件测试的活动。

    “有效性确认”是确认所开发的软件是否满足用户真正需求的活动。一切从客户出发,理解客户的需求,并对软件需求定义和设计存疑,以发现需求定义和产品设计中的问题。主要通过各种软件评审活动来实现,保证让客户参加评审和测试活动。

    当然,软件测试的对象是产品(包括阶段性产品,如市场需求说明书、产品规格说明书、技术设计文档、数据字典、程序包、用户文档等),而质量保证和管理的对象集中于软件开发的标准、流程和方法等上。

    软件测试的过程阶段

    1.测试需求分析阶段:阅读需求,理解需求,主要就是对业务的学习,分析需求点,参与需求评审会议。

    2.测试计划阶段:主要任务就是编写测试计划,参考软件需求规格说明书,项目总体计划,内容包括测试范围(来自需求文档),进度安排,人力物力的分配,整体测试策略的制定。风险评估与规避措施有一个制定。

    3.测试设计阶段:主要是编写测试用例,会参考需求文档(原型图),概要设计,详细设计等文档,用例编写完成之后会进行评审。

    4.测试执行阶段:搭建环境,执行冒烟测试(预测试)-然后进入正式测试,bug管理直到测试结束。

    5.测试评估阶段:出测试报告,对整体过程做总结,对当前版本质量评估,确认是否可以上线。

    6.验收阶段:出用户手册,操作指引,公司严格评审流程,保证每一步输出的有效。

     

    测试分类

    1.按软件开发阶段的角度划分:单元测试、集成测试、系统测试、验收测试

    2.按是否查看源代码的角度划分:黑盒测试、灰盒测试、白盒测试

    3.按是否执行程序的角度划分:静态测试、动态测试

    4.按测试实施组织的角度划分:α测试、β测试、第三方测试

    5.按是否手工执行测试的角度划分:手工测试、自动化测试

    6.按测试对象的角度划分:性能测试、安全测试、兼容性测试、文档测试、易用性测试(用户体验测试)、业务测试、界面测试、安装测试

    7.按测试地域的角度划分:本地化测试、国际化测试

    按软件开发阶段的角度划分

    1.单元测试(Unit Testing)

    单元测试,又称模块测试。对软件的组成单位进行测试,其目的是检验软件基本组成单位的正确性。测试的对象是软件里测试的最小单位:模块。

    测试阶段:编码后或者编码前(TDD:测试驱动开发)

    测试对象:最小模块

    测试人员:白盒测试工程师或开发人员

    测试依据:代码和注释+详细文档

    测试方法:白盒测试

    测试内容:模块接口测试、局部数据结构测试、独立执行路径测试、错误处理路径测试、边界条件测试

    补充说明:

    (1)学习测试依据时,我们可以对比软件测试的“V”模型结合记忆

    (2)白盒测试不是单元测试,单元测试是白盒测试

    (3)测试驱动开发(TDD):测试人员先编写测试用例,开发人员根据测试用例写程序

    单元测试的目的

    单元测试的目的在于发现各模块内部可能存在的各种错误,主要是基于白盒测试。(也就是说,在单元测试过程中,用的最多的是白盒测试方法,也可能会有灰盒或者黑盒。单元测试和白盒测试是不同的划分,不存在包含关系)。

    在单元测试阶段对应的文档是详细设计文档(LLD);对应的代码就是单元代码,因此单元测试的目的主要有3点:

    1、验证代码是与设计相符合的;

    2、发现设计和需求中存在的错误;

    3、发现在编码过程中引入的错误。

    单元测试的特点

    1. 程序单元是应用的最小可测试部件,通常基于类或者类的方法进行测试。

    2. 程序单元和其他单元是相互独立的。

    3. 单元测试的执行速度很快

    4. 单元测试发现的问题相对容易定位。

    5. 单元测试通常由开发人员来完成。

    6. 通过了解代码的实现逻辑进行测试,通常称之为白盒测试。

    单元测试过程

    测试四部曲:

    1. 初始化数据
    2. 执行要测试的业务

    3. 验证测试的数据

    4. 清理数据

    单元测试策略

    1、孤立的单元测试策略(Isolation Unit Testing)

    方法:不考虑每个模块与其它模块之间的关系,为每个模块设计桩模块和驱动模块,每个模块进行独立的单元测试。

    优点:这个方法比较简单,最容易操作,可以达到很高的结构覆盖率,可以并行开展,该方法是纯粹的单元测试。

    缺点:桩函数和驱动函数工作量很大,效率低。

    2、自顶向下的单元测试策略(Top Down Unit Testing)

    方法:先对最顶层的单元进行测试,把顶层所调用的单元做成桩模块,其次对第二层进行测试,使用上面已经测试过的单元做驱动模块,以此类推,直到测试完所有模块。

    优点:可以节省驱动函数的开发工作,效率高。

    缺点:随着被测单元一个一个被加入,测试过程将变得越来越复杂,并且开发和维护的成本将增加。

    3、自底向上的单元测试策略(Bottom Up Unit Testing)

    方法:先对最底层的模块进行单元测试,将模拟调用该模块的模块设置为驱动模块,然后再对上面一层做单元测试,用下面已经测试好的模块做桩模块,以此类推,直到测试完所有模块。

    优点:可以节省桩函数的开发工作量,测试效率较高。

    缺点:不是纯粹的单元测试,底层函数的测试质量对上层函数的测试将产生很大影响。

    单元测试工具

    JavaScript单元测试工具 JsTestDriver和Venus和Buster.JS

    C单元测试工具 greatest

    C++单元测试工具 QTRunner和ECUT

    单元测试维护工具 Unitils

    Qt单元测试工具 QTestlib

    存储过程单元测试工具 SQLUnit

    数据库单元测试工具 DbUnit

    NoSQL的单元测试工具 NoSQLUnit

    单元测试框架

     Arquillian、The Grinder、

    JUnit 和TestNG是一个 Java 语言的单元测试框架;

     AndroidJUnit4 是Android的单元测试框架;

    C++ 单元测试框架 cipra

    Python单元测试框架 PyUnit、unittest、pytest

    Python 模拟测试框架 CaptureMock

    gtest是一个跨平台的(Liunx、Mac OS X、Windows、Cygwin、Windows CE and Symbian)C++单元测试框架,由google公司发布。

    2.集成测试(Integration Testing)

    集成测试也称联合测试(联调)、组装测试:将程序模块采用适当的集成策略组装起来,对系统的接口及集成后的功能进行正确性检测的测试工作。集成主要目的是检查软件单位之间的接口是否正确。

    测试阶段:一般是单元测试之后

    测试对象:模块间的接口

    测试人员:白盒测试工程师或开发工程师

    测试依据:单元测试的文档+概要设计文档

    测试方法:黑盒测试与白盒测试(灰盒测试)

    测试内容:模块之间数据传输、模块之间功能冲突、模块组装功能的正确性、全局数据结构、单模块缺陷对系统的影响

    补充说明:

    单元测试是一个模块内部的测试,集成测试是在模块之间进行测试(至少两个)。

    集成测试的目的

    集成测试的目标是按照设计要求使用那些通过单元测试的构件来构造程序结构。单个模块具有高质量但不足以保证整个系统的质量。有许多隐蔽的失效是高质量模块间发生非预期交互而产生的。

    以下两种测试技术是用于集成测试:

    1)功能性测试。使用黑盒测试技术针对被测模块的接口规格说明进行测试。

    2)非功能性测试。对模块的性能或可靠性进行测试。

    另外,集成测试的必要性还在于一些模块虽然能够单独地工作,但并不能保证连接起来也能正常工作。程序在某些局部反映不出来的问题,有可能在全局上会暴露出来,影响功能的实现。此外,在某些开发模式中,如迭代式开发,设计和实现是迭代进行的。在这种情况下,集成测试的意义还在于它能间接地验证概要设计是否具有可行性。

    集成测试是确保各单元组合在一起后能够按既定意图协作运行,并确保增量的行为正确。它所测试的内容包括单元间的接口以及集成后的功能。使用黑盒测试方法测试集成的功能。并且对以前的集成进行回归测试。

    集成测试的内容

    集成测试的内容包括模块之间接口以及集成后的功能。它主要使用黑盒测试方法测试继承的功能,并对以前的集成进行回归测试。具体来说,集成测试的内容包括以下方面: 
    (1)、将各个具有相互调用关系的模块组装起来时,检查相应模块接口的数据是否会丢失。 
    (2)、判断各个子功能组合起来是否能够达到预期要求的父功能。 
    (3)、检查一个模块的功能是否对其他模块的功能产生不良影响。 
    (4)、检查全局数据结构是否正确,以及在完成模块功能的过程中是否会被异常修改。 
    (5)、单个模块的误差累计起来,是否会放大到不可接受的程度。

    集成测试过程

    1.计划阶段: 依据需求规格说明书、概要设计文档和开发计划,拟定软件集成测试计划;

    2设计阶段:依据被测对象的结构、待集成模块、接口、集成测试策略、测试工具等进行分析,拟定集成测试设计方案;

    3实现阶段:主要进行集成测试用例设计和集成测试代码设计;

    4执行阶段: 执行测试,生成测试报告。

    集成测试原则

    1.所有的公共接口都要被测试到;

    2.关键模块必须进行充分的测试;

    3.集成测试应该按一定的层次进行;

    4.集成测试的策略应该综合考虑质量、进度、成本;

    5.当测试计划中的结束标准满足时,集成测试结束;

    6.集成测试根据集成测试的计划和方案进行,防止测试的随意性;

    7.项目管理者保证测试用例经过审查;

    8.测试的执行结果应该如实的被记录。

    集成测试技术和步骤

    技术: 

       以黑盒测试技术为主、白盒测试技术为辅(灰盒测试技术)

    步骤:

       与集成测试策略相关

    集成测试策略

    基于功能分解的集成测试:非渐增式集成、渐增式集成、瞬时集成。

     

     

    瞬时集成测试策略又称大爆炸测试、一次性集成。首先对每个模块分别进行模块测试,然后将所有模块集成起来在一起进行测试,最终得到要求的软件系统。

    集成测试工具

    Jenkins持续集成自动化构建发布工具

    开源的 Restful Api 集成测试工具 Hitchhiker

    集成测试的三个级别

    由于集成的力度不同,一般可以把集成测试划分为三个级别:

    1、模块内集成测试。

    2、子系统内集成测试。

    3、子系统间集成测试。

    3.系统测试(System Testing)

    系统测试:将软件系统看成是一个系统的测试。包括对功能、性能以及软件所运行的软硬件环境进行测试。时间大部分在系统测试执行阶段,包括回归测试和冒烟测试。

    测试阶段:集成测试阶段之后

    测试对象:整个系统(软件、硬件)

    测试人员:黑盒测试工程师

    测试依据:需求规格说明文档

    测试方法:黑盒测试

    测试内容:功能、界面、可靠性、易用性、性能、兼容性、安全性等

    补充说明:

    (1)系统测试是从完整的角度,广面去看待问题,不再看模块;

    (2)虽然系统测试包括冒烟测试和回归测试,但三者之间是有严格的先后顺序的,即:先冒烟、再系统、后回归。

    系统测试的目的

    系统测试的目的是验证最终软件系统是否满足用户规定的需求。

    系统测试目标

    1、 确保系统测试的活动是按计划进行的;

    2、 验证软件产品是否与系统需求用例不相符合或与之矛盾;

    3、 建立完善的系统测试缺陷记录跟踪库;

    4、 确保软件系统测试活动及其结果及时通知相关小组和个人。

    系统测试主要分为以下几种:

    1.恢复测试

    2.安全测试

    3.强度测试

    4.性能测试

    系统测试原则

    1、测试机构要独立;

    2、要精心设计测试计划,包括负载测试、压力测试、用户界面测试、可用性测试、逆向测试、安装测试、验收测试;

    3、要进行回归测试;

    4、测试要遵从经济性原则。

    系统测试的方法

    功能测试:功能测试属于黑盒测试,是系统测试中最基本的测试。功能测试主要根据产品的需求规格说明和测试需求列表,验证产品是否符合需求规格说明。

    协议一致性测试:主要用于分布式系统。在分布式系统中,很多功能的实现是通过多台计算机相互协作来完成的,这要求计算机之间能相互交换信息,所以需要制定一些规则(协议)。对协议进行测试,通常包括:协议一致性测试、协议性能测试、协议互操作性测试、协议健壮性测试。

    性能测试:主要用于实时系统和嵌入式系统,性能测试是指测试软件在集成系统中的运行性能,目标是量度系统的性能和预先定义的目标有多大差距。一种典型的性能测试是压力测试,当系统同时接收极大数量的用户和用户请求时,需要测量系统的应对能力。性能测试要有工具的支持,在某种情况下,测试人员必须自己开发专门的接口工具。

    压力测试:又称强度测试,是在各种超负荷的情况下观察系统的运行情况的测试。

    容量测试:在系统正常运行的范围内测试并确定系统能够处理的数据容量。容量测试是面向数据的,主要目的就是检测系统可以处理目标内确定的数据容量。

    安全性测试:安全性测试就是要验证系统的保护机制是否抵御入侵者的攻击。保护测试是安全性测试中一种常见的测试,主要用于测试系统的信息保护机制。评价安全机制的性能与安全功能本身一样重要,其中安全性的性能主要包括:有效性、生存性、精确性、反应时间、吞吐量。

    失效恢复测试:验证系统从软件或者硬件失效中恢复的能力。失效恢复测试采用各种人为干预方式使软件出错,造成人为的系统失效,进而检测系统的恢复能力。如果恢复需要人为干预,则应考虑平均修复时间是否在限定的范围内。

    备份测试:备份测试是失效恢复测试的补充,目的是验证系统在软件或者硬件失效的实践中备份其数据的能力。

    GUI测试:GUI测试与用户友好性测试和可操作性测试有重复,但GUI测试更关注对图形界面的测试。GUI测试分为两个部分,一方面是界面实现与界面设计的情况要符合;另一方面是要确认界面能够正确处理事件。

                     GUI测试设计测试用例一般要从以下4方面考虑:

                     (1)划分界面元素,并根据界面的复杂性进行分层。通常把界面划分为三个层次,第一层是界面原子层;第二层是界面组合元素层;第三层是一个完整的窗口。

                     (2)在不同的界面层次确定不同的测试策略。

                     (3)进行测试数据分析,提取测试用例。

                     (4)使用自动化测试工具进行脚本化工作。

    健壮性测试:又称容错测试,用于测试系统在出故障时,是否能够自动恢复或者忽略故障继续运行。健壮性测试的一般方法是软件故障插入测试,在软件故障插入测试中,需要关注三个方面:目标系统、故障类型和插入故障的方法。

    兼容性测试:检验被测的应用系统对其他系统的兼容性。

    易用性测试:与可操作性类似。检测用户在理解和使用系统方面是否方便。易用性测试是面向用户的系统测试,包括对被测系统的系统功能、系统发布、帮助文本和过程等的测试。最好在开发阶段就开始进行。

    安装测试验证成功安装系统的能力。

    文档测试:主要是针对系统提交给用户的文档进行验证。文档测试的目标是验证用户文档的正确性并保证操作手册的过程能正常工作。

    在线帮助测试:用于检验系统的实时在线帮助的可操作性和准确性。

    数据转换测试:目标是验证已存在数据的转换并载入一个新的数据库是否有效。

    4.验收测试(Acceptance Testing)

    验收测试(交付测试):是部署软件之前的最后一个测试操作。它是技术测试的最后一个阶段,也称为交付测试。是以用户为主的测试,软件开发人员和质量保证人员也应参加,由用户参加设计测试用例,使用用户界面输入测试数据,并分析测试的输出结果。

    验收测试的目的是确保软件准备就绪,按照项目合同、任务书、双方约定的验收依据文档,向软件购买者系统测试展示该软件系统满足原始需求。

    测试阶段:系统测试通过后

    测试对象:整个系统(包括软硬件)

    测试人员:主要是最终用户或者需求方

    测试依据:用户需求、验收标准

    测试方法:黑盒测试

    测试内容:同系统测试(功能、各类文档等)

    补充说明:

    验收测试包括alpha测试和beta测试。alpha测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试。Beta测试由软件的最终用户们在一个或多个客房场所进行。

    验收测试分类

    用户验收测试可以分为两个大的部分:软件配置审核和可执行程序测试,其大致顺序可分为:文档审核、源代码审核、配置脚本审核、测试程序或脚本审核、可执行程序测试。

    验收测试策略

    实施验收测试的常用策略有三种,它们分别是:

    1· 正式验收

    2· 非正式验收或 Alpha 测试

    3· Beta 测试

    您选择的策略通常建立在合同需求、组织和公司标准以及应用领域的基础上。

    验收测试过程

    1. 软件需求分析:了解软件功能和性能要求、软硬件环境要求等,并特别要了解软件的质量要求和验收要求。

    2. 编制《验收测试计划》和《项目验收准则》:根据软件需求和验收要求编制测试计划,制定需测试的测试项,制定测试策略及验收通过准则,并经过客户参与的计划评审。

    3. 测试设计和测试用例设计:根据《验收测试计划》和《项目验收准则》编制测试用例,并经过评审。

    4. 测试环境搭建:建立测试的硬件环境、软件环境等。(可在委托客户提供的环境中进行测试)

    5. 测试实施:测试并记录测试结果。

    6. 测试结果分析:根据验收通过准则分析测试结果,作出验收是否通过及测试评价。

    7. 测试报告:根据测试结果编制缺陷报告和验收测试报告,并提交给客户。

    验收测试的内容

    通常可以包括:安装(升级)、启动与关机、功能测试(正例、重要算法、边界、时序、反例、错误处理)、性能测试(正常的负载、容量变化)、压力测试(临界的负载、容量变化)、配置测试、平台测试、安全性测试、恢复测试(在出现掉电、硬件故障或切换、网络故障等情况时,系统是否能够正常运行)、可靠性测试等。

     

    按是否查看代码的角度划分

    1.黑盒测试(Black-box Testing)

    黑盒测试也是功能测试,测试中把被测的软件当成一个黑盒子,不关心盒子的内部结构是什么,只关心软件的输入数据和输出数据。

    黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。黑盒测试着眼于程序外部结构,不考虑内部逻辑结构,主要针对软件界面和软件功能进行测试。

    黑盒测试是以用户的角度,从输入数据与输出数据的对应关系出发进行测试的。很明显,如果外部特性本身设计有问题或规格说明的规定有误,用黑盒测试方法是发现不了的。

    作用

    黑盒测试法注重于测试软件的功能需求,主要试图发现下列几类错误。

    功能不正确或遗漏;

    界面错误;

    输入和输出错误;

    数据库访问错误;

    性能错误;

    初始化和终止错误等。

    优点 

    1、对于子系统甚至系统,效率要比白盒测试高。 

    2、测试人员不需要了解实现的细节,包括特定的编程语言。 

    3、测试人员和编程人员彼此独立。 

    4、从用户的角度进行测试,很容易理解和接受。 

    5、有助于暴露规格的不一致或有歧义的问题。 

    6、测试用例可以在规格完成后马上进行。

    缺点 

    1、只有一小部分输入被测试到,要测试每个可能的输入几乎不可能。 

    2、没有清晰、简明的规格,测试用例很难设计。 

    3、如果测试人员不被告知开发人员已经执行过的用例,在测试数据上会存在不必要的重复。 

    4、有很多程序路径没有被测试到。 

    5、不能直接针对特定程序段测试,而这些程序段可能很复杂,有可能隐藏更多的问题。 

    6、大部分和研究相关的测试都是直接针对白盒测试的。

    测试用例设计方法

    从理论上讲,黑盒测试只有采用穷举输入测试,把所有可能的输入都作为测试情况考虑,才能查出程序中所有的错误。实际上测试情况有无穷多个,人们不仅要测试所有合法的输入,而且还要对那些不合法但可能的输入进行测试。这样看来,完全测试是不可能的,所以我们要进行有针对性的测试,通过制定测试案例指导测试的实施,保证软件测试有组织、按步骤,以及有计划地进行。黑盒测试行为必须能够加以量化,才能真正保证软件质量,而测试用例就是将测试行为具体量化的方法之一。具体的黑盒测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法、场景法等。

    等价类划分法

    等价类是指某个输入域的子集合。在该子集合中,各个输入数据对于揭露程序中的错误都是等效的,并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类。

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

    无效等价类:与有效等价类的定义恰巧相反。

    设计测试用例时,要同时考虑这两种等价类.因为,软件不仅要能接收合理的数据,也要能经受意外的考验.这样的测试才能确保软件具有更高的可靠性。

    划分等价类的原则

    ①  在输入条件规定了取值范围或值的个数的情况下,则可以确立一个有效等价类和两个无效等价类。

    例:输入值是学生成绩,范围是0~100:

     

    ②  在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可确立一个有效等价类和一个无效等价类。

    ③  在输入条件是一个布尔类型的情况下,可确定一个有效等价类和一个无效等价类。

    ④在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类。

    ⑤在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。

    ⑥在确知已划分的等价类中各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步的划分为更小的等价类。

    建立等价类表

    设计测试用例:在确立了等价类后,可建立等价类表,列出所有划分出的等价类:

    确定测试用例

    输入条件 有效等价类 或  无效等价类

    然后从划分出的等价类中按以下三个原则设计测试用例:

    ①  为每一个等价类规定一个唯一的编号。

    ②  设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖地有效等价类,重复这一步.直到所有的有效等价类都被覆盖为止。

    ③  设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步.直到所有的无效等价类都被覆盖为止。

    举例:判断三角形类别

    【问题描述】程序要求:输入三个整数 a 、 b 、 c 分别作为三角形的三边长度,通过程序判定所构成的三角形的类型;当三角形为一般三角形、等腰三角形或等边三角形时,分别作处理 。 

    【问题分析】

    (1) 输入值域的显/隐式要求:A 整数、B 三个、C 正数、D 两边之和大于第三边、E 三边均不相等、F 两边相等但不等于第三边、G 三边相等;(D~G由输出值域的等价类隐性确定)

    (2) 输出值域的等价类:R1={不构成三角形}、R2={一般三角形}、R3={等腰三角形}、R4={等边三角形};

    【问题解答】
    (1) 列出等价类表并编号 

    (2) 设计覆盖有效等价类的测试用例 
     

    (3) 设计覆盖无效等价类的测试用例 
     

    【问题描述】程序要求:输入三个数 a 、 b 、 c 分别作为三角形的三边长度,通过程序判定所构成的三角形的类型;当三角形为一般三角形、等腰三角形或等边三角形时,分别作处理 。注:a、b、c非空。 

     

    【问题分析】

    (1) 输入值域的显/隐式要求:B 三个、C 正数、D 两边之和大于第三边、E 三边均不相等、F 两边相等但不等于第三边、G 三边相等;(D~G由输出值域的等价类隐性确定)

    (2) 输出值域的等价类:R1={不构成三角形}、R2={一般三角形}、R3={等腰三角形}、R4={等边三角形};

    【问题解答】
    (1) 列出等价类表并编号 

     

     (2) 设计覆盖有效/无效等价类的测试用例

    边界值分析法

    边界值分析是通过选择等价类边界的测试用例。边界值分析法不仅重视输入条件边界,而且也必须考虑输出域边界。它是对等价类划分方法的补充。

    (1)边界值分析方法的考虑:

    长期的测试工作经验告诉我们,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部.因此针对各种边界情况设计测试用例,可以查出更多的错误。

    使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入和输出等价类的边界,就是应着重测试的边界情况.应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据。

    (2)基于边界值分析方法选择测试用例的原则:

       1)如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据。

       2)如果输入条件规定了值的个数,则用最大个数,最小个数,比最小个数少一,比最大个数多一的数作为测试数据。

       3)根据规格说明的每个输出条件,使用前面的原则1)。

       4)根据规格说明的每个输出条件,应用前面的原则2)。

       5)如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例。

       6)如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构的边界上的值作为测试用例。

       7)分析规格说明,找出其它可能的边界条件。

    举例:区间值的边界值取值问题

    用边界值分析法,假定1<X<10,那么X在测试中应该取的边界值是( A )

    X=1,X=2,X=9,X=10

    X=2,X=9

    X=1,X=10

    X=1,X=5,X=6,X=10

    这里涉及到开闭区间和离点的概念,在边界值分析时,有下面几个点:

    上点:就是指得边界上得点,无论此时得域是开区间还是闭区间,开区间得话,上点就是在域外,闭区间得话,上点就是在域内。

    离点:指得就是离上点最近得点,这里就跟是闭区间还是开区间就有关系了,如果是开区间,那么离点就在域内,如果是闭区间,那么离点就在域外。

    内点:域内得任意点都是内点。

    题目中给的是开区间,不包括等于的情况。这里上点是1和10,因为是开区间,所以离点是在区间内,即2和9。所以边界值要覆盖1 2 9 10。

    上点很好理解,但是开区间的离点为什么在区间内,0和11需要覆盖吗?

    其实可以这么理解,对开区间,范围不包括边界,上点是在范围之外的,所以需要再测一个在范围之内,又离上点最近的点,这个值就是范围内离上点最近的点。

    另外,假如题目给的条件是1≦x≦10,那答案就是0 1 10 11,如果是1<x≦10,那答案就应该是1 2 10 11。

    举例:判断三角形类别

    【问题描述】程序要求:输入三个不超过200的整数 a 、 b 、 c 分别作为三角形的三边长度,通过程序判定所构成的三角形的类型;当三角形为一般三角形、等腰三角形或等边三角形时,结果打印出来 。 

    【问题分析】

    (1) 输入值域的显/隐式要求:A 整数、B 三个、C 正数、D 两边之和大于第三边、E 三边均不相等、F 两边相等但不等于第三边、G 三边相等;(D~G由输出值域的等价类隐性确定)

    (2) 输出值域的等价类:R1={不构成三角形}、R2={一般三角形}、R3={等腰三角形}、R4={等边三角形};

    (3)边界值:0、1、2、100、199、200、201

    当仅有一个变量取边界值,其他取正常值,从一般边界值的角度考虑{1、2、100、199、200},(4n+1=13,n=3)如下表所示。

    序号

    输入及操作说明

    期望的测试结果

    1

    1、100、100

    等腰三角形

    2

    2、100、100

    3

    199、100、100

    4

    200、100、100

    非三角形

    5

    100、1、100

    等腰三角形

    6

    100、2、100

    7

    100、199、100

    8

    100、200、100

    非三角形

    9

    100、100、1

    等腰三角形

    10

    100、100、2

    11

    100、100、199

    12

    100、100、200

    非三角形

    13

    100、100、100

    等边三角形

    当仅当有一个变量取边界值,其他取正常值,从健壮边界值的角度考虑{0、1、2、100、199、200、201},(6n+1=19,n=3) 如下表所示。

    序号

    输入及操作说明

    期望的测试结果

    1

    0、100、100

    非三角形

    2

    1、100、100

    等腰三角形

    3

    2、100、100

    4

    199、100、100

    5

    200、100、100

    非三角形

    6

    201、100、100

    7

    100、0、100

    8

    100、1、100

    等腰三角形

    9

    100、2、100

    10

    100、199、100

    11

    100、200、100

    非三角形

    12

    100、201、100

    13

    100、100、0

    14

    100、100、1

    等腰三角形

    15

    100、100、2

    16

    100、100、199

    17

    100、100、200

    非三角形

    18

    100、100、201

    19

    100、100、100

    等边三角形

     当所有变量取边界值时,介于篇幅原因,可使用上述表中的边界值自行完成53、73个测试用例。

       

    总结:

      由于多变量同时取边界值,关注的是变量同时取值对功能的影响,三角形问题的各个变量之间相对独立,因此对于三角形问题仅考虑使用一个变量取边界值,其他变量取正常值即可

    错误推测法

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

    错误推测方法的基本思想: 列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例。 例如,在单元测试时曾列出的许多在模块中常见的错误. 以前产品测试中曾经发现的错误等,这些就是经验的总结。还有,输入数据和输出数据为0的情况. 输入表格为空格或输入表格只有一行. 这些都是容易发生错误的情况。可选择这些情况下的例子作为测试用例。

    它的要素共有三点,分别为:经验、知识、直觉。关于如何使用的问题,我们提炼出两点:

      1.列举出程序中所有可能有的错误和容易发生错误的特殊情况;

      2.根据他们选择测试用例。

      我们知道经验是错误推测法的一个重要要素,也就说带有主观性,那么这就决定了错误猜测法的优缺点,首先我们来看优点:

      1.充分发挥人的直觉和经验;

      2.集思广益;

      3.方便使用;

      4.快速容易切入;

      对应的缺点有:

      1.难以知道测试的覆盖率;

      2.可能丢失大量未知的区域;

      3.带有主观性且难以复制;

    举例:手机终端通话功能

    例如:测试手机终端的通话功能,可以设计哪些通话失败的情况来补充测试用例

         1、无SIM 插入是进行呼出(非紧急呼叫)

         2、插入已欠费SIM卡进行呼出

         3、射频器件损坏或无信号区域插入有效SIM卡呼出

         4、网络正常、插入有效SIM卡,呼无效号码(如1、888、33333、不输入任何号码等)

         5、网络正常,插入有效SIM卡,使用“快速拔号”功能呼出设置无效号码的数字

    因果图法

    前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系,相互组合等。 考虑输入条件之间的相互组合,可能会产生一些新的情况. 但要检查输入条件的组合不是一件容易的事情,即使把所有输入条件划分成等价类,他们之间的组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例. 这就需要利用因果图(逻辑模型)。

    因果图方法最终生成的就是判定表。它适合于检查程序输入条件的各种组合情况。

    应用场景

    在一个界面中有多个控件,测试的时候要考虑各个控件的组合关系,不同控件的组合关系会产生不同的输出结果的组合,考虑用因果图。

    生成测试用例

    (1) 分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),并给每个原因和结果赋予一个标识符。

    (2) 分析软件规格说明描述中的语义。找出原因与结果之间,原因与原因之间对应的关系. 根据这些关系,画出因果图。

    (3) 由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况不可能出现. 为表明这些特殊情况,在因果图上用一些记号标明约束或限制条件。

    (4) 把因果图转换为判定表。

    (5) 把判定表的每一列拿出来作为依据,设计测试用例。

    从因果图生成的测试用例(局部,组合关系下的)包括了所有输入数据的取TRUE与取FALSE的情况,构成的测试用例数目达到最少,且测试用例数目随输入数据数目的增加而线性地增加。

    前面因果图方法中已经用到了判定表。判定表(Decision Table)是分析和表达多逻辑条件下执行不同操作的情况下的工具.在程序设计发展的初期,判定表就已被当作编写程序的辅助工具了.由于它可以把复杂的逻辑关系和多种条件组合的情况表达得既具体又明确。

    因果图标识

     原因和结果之间的关系有: 
     

     

    ①恒等:若C1是1,则E1也是1;若C1是0,则E1也是0。 
    ②非:若C1是1,则E1是0;若C1是0,则E1是1。 
    ③或:若c1或c2是1,则E1是1;否则E1为0。 或的含义:只有所有条件都为0时,结果为0,有任何1个条件为1(或者所有条件为1)时,结果为1
    ④与:若c1和c2都是1,则E1为1;否则E1为0。与的含义:只有所有条件都为1时,结果为1,有任何一个条件为0(或者所有条件为0)那么结果为0.

    因果图约束

    约束条件符号: 

     

      

    输入条件的约束有以下4类: 
    1. E约束(互斥/异):a和b中至多有一个可能为1,即a和b不能同时为1。含义:可以不选,如果选,只能选1个 
    2. I约束(或):a、b和c中至少有一个必须是1,即 a、b 和c不能同时为0。含义:至少选1个(可以多选,不能不选,最少得选1个) 
    3. O约束(唯一);a和b必须有一个,且仅有1个为1。含义:有且只有1个(必须要选,而且只能选1个)

    4. R约束();若a为1时,则b必须为1。而当a为0时,b的值不定。

    输出条件约束类型 

    输出条件的约束只有M约束(屏蔽/强制):若结果a是1,则结果b强制为0。而当a为0时,b的值不定。

    因果图法测试用例的设计步骤

    (1)  确定软件规格(需求)中的原因和结果

    分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件), 并给每个原因和结果赋予一个标识符。

    (2)  确定原因和结果之间的逻辑关系

    分析软件规格说明描述中的语义。找出原因与结果之间,原因与原因之间对应的关系。根据这些关系,画出因果图。

    (3)  确定因果图中的各个约束(constraints)

    由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况下不可能出现。 为表明这些特殊情况,在因果图上用一些记号表明约束或限制条件。

    (4)画出因果图并转换为决策表

    (5)根据决策表设计测试用例

    因果图法优缺点

    优点:

    ①  考虑到了输入情况的各种组合以及各个输入情况之间的相互制约关系。

    ②  能够帮助测试人员按照一定的步骤,高效率的开发测试用例。

    ③  因果图法是将自然语言规格说明转化成形式语言规格说明的一种严格的方法,可以指出规格说明存在的不完整性和二义性。

    缺点:

    ①  因果图来设计测试用例时,作为输入条件的原因与输出结果之间的因果关系,有时很难从软件需求规格说明中得到。

    ②  而且往往因果关系非常庞大,以至于据此因果图而得到的测试用例数目多的惊人,给软件测试,特别是手工测试带来沉重的负担,为了有效地,合理地减少测试的工时与费用,可利用正交实验设计方法进行测试用例的设计。

    举例:自动售货机

    产品说明书:有一个处理单价为1元5角钱的盒装饮料的自动售货机软件。若投入1元5角硬币,按下“可乐”、“雪碧”、或“红茶”按钮,相应的饮料就送出来。若投入的是2元硬币,在送出饮料的同时退还5角硬币。

     

     

    判定表法

    1.判定表是分析和表达多逻辑条件下执行不同操作的情况的工具。判定表通常由四个部分组成:

    条件桩(Condition Stub):列出了问题的所有条件.通常认为列出的条件的次序无关紧要。

    动作桩(Action Stub):列出了问题规定可能采取的操作.这些操作的排列顺序没有约束。

    条件项(Condition Entry):列出针对它左列条件的取值.在所有可能情况下的真假值。

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

     

    2.规则:任何一个条件组合的特定取值及其相应要执行的操作.在判定表中贯穿条件项和动作项的一列就是一条规则.显然,判定表中列出多少组条件取值,也就有多少条规则,既条件项和动作项有多少列。

     

    3. 判定表的化简:合并判定表中两条或多条具有相同动作,并且其条件项之间存在着极为相似关系的规则这一过程。

    4. 判定表使用场景:如果程序中多个条件决定一个动作,并且每个条件的取值只有两种,且条件和动作之间的逻辑关系明确

    5. 优点:能够将复杂的问题按照各种可能的情况全部列举出来,简明并且可以避免遗漏。

    判定表的建立步骤:(根据软件规格说明)

    1.列出所有的条件桩和动作桩。

    2.确定规则的个数。假如有n个条件.每个条件有两个取值(0,1),故有2n种规则。

    3.填入条件项。

    4.填入动作项.等到初始判定表。

    5.简化.合并相似规则(相同动作)。

    有两个或者多条规则具有相同的动作,并且条件项之间存在极为相似的关系就可以进行合并。

    判定表设计测试用例的条件:

    规格说明以判定表形式给出,或很容易转换成判定表。

    ①  条件的排列顺序不会也不影响执行哪些操作。

    ②  规则的排列顺序不会也不影响执行哪些操作。

    ③  每当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则。

    ④  如果某一规则得到满足要执行多个操作,这些操作的执行顺序无关紧要。

    判定表法优缺点

    判定表的优点:

          1)  充分考虑了输入条件简的组合,对组合情况覆盖充分;

          2)  最终每个用例覆盖多种输入情况,有利于提高测试效率;

          3)  设计过程中,对输入条件间的约束关系做了考虑,避免了无效用例,用例的有效性高;

          4)  能同时得出每个测试项目的预期输出。

    判定表的缺点:

          1)  当被测试特性输入较多时,会造成判定表规格庞大;

          2)  输入之间的约束条件不能有效区分输入是否确实需要进行组合测试,会造成不需要组合测试的输入做了组合,从而产生用例冗余。

    举例:判断三角形类别

     

     

     

     

    正交试验设计法

    就是使用已经造好了的正交表格来安排试验并进行数据分析的一种方法,目的是用最少的测试用例达到最高的测试覆盖率。

    使用正交试验设计法首先要知道正交表,正交表是研究多因素多水平的一种设计方法,它是格局正交性从全面试验中挑选出部分有代表性的点进行试验,这些有代表性的点具备了“均匀分散,齐整可比”的特点,正交试验设计是一种基于正交表的、高效率、快速、经济的试验设计方法。

    正交表由三个成分构成:

    Runs:正交表的行数,即实验的次数;

    Factors:正交表的列数,即因素数;

    Levels:水平数,任何单个因素能够取得的值的最大个数。正交表中的包含的值为从0到数“水平数-1”或从1到“水平数”

    正交表的表现形式是:L行数(水平数因素数)    L runs(levels^factors  )。

    设计过程

    1)确定试验因素及水平数;

    2)选用合适的正交表;

    3)列出试验方案及试验结果;

    4)对正交试验设计结果进行分析,包括极差分析和方差分析;

    5)确定最优或较优因素水平组合。

    用正交表设计测试用例的步骤:

    1. 有哪些因素(变量);

    2. 每个因素有哪几个水平(变量的取值):用等价类划分出来的;

    3. 选择一个合适的正交表;

    4. 把变量的值映射到表中;

    5. 把每一行的各因素水平的组合作为一个测试用例;

    6. 加上你认为可以且没有在表中出现的组合。

    如何选择正交表呢?取行数最少的一个,情况分三种:

    1.因素数(变量)、水平数(变量值)相符;

    2.因素数不相同: 取因素数最接近但略大的实际值的表;

    3.水平数不相同: 有五个因素(变量)A、B、C、D和E。两个因素有两个水平(变量的取值)、两个因素有三个水平,一个因素有六个水平。行数取最少的一个( 行数取最少的一个(L49(78)、 L18(3661)

    教你用Minitab进行正交试验设计(极差)分析

    首先,根据实验要求,确定你实验条件的因素、水平数,最好通过列表形式明确(如图:以影响大豆出油率为例)。

     

    然后,可以通过Minitab创建以上确定的正交表,依次选择工具栏“统计”—“DOE”—“田口”—“创建田口设计”选项,调出“田口设计”对话框。

    如图:

    在“田口设计”对话框中,根据需求选择合适的因素、水平数,并点击“设计”按钮,选择合适正交表。

    注意:要考虑到试验过程中的误差,所选正交表安排完因素后,要有一列空白列,以考察试验误差进行方差分析。(故本例:选4因素,3水平,L9表)。

    如图,创建的“四因素三水平正交表”(注意:此处不考虑交互作用)。

     

     

    在正交设计表等的基础上,将所选正交表中各列的“数字”换成对应因素的具体“实验水平值”(每一因素的某一水平均唯一对应一个实验条件值),便形成了试验方案。如图:

    此时可以根据此表安排实验方案。

     

    经过实验后,得到对应的数据结果后,填入正交表对应位置(本例:“大豆出油率/%”),进行实验数据分析。如图:

     

    接着可进行数据分析:依次选择工具栏“统计”—“DOE”—“田口”—“分析田口设计”选项,调出“分析田口设计”对话框。如图:

     

     

    然后,将实验数值列选择到“响应数据位于”(本例:C5 “大豆出油率/%”)框内,再点击“分析”按钮,选择要分析的项(本例:均值)如图:

    最后,依次点击“确定”按钮,即可得极差分析结果(如图)。本例中由于大豆出油率越大越好(B>A>D>C),所以最优水平为:B3 A2 D1 C2

     

    另外,Minitab软件还进行方差分析哦,(这里不再详述,请自行学习!)。

    希望能对你有帮助!

     

    场景法

    软件几乎都是用事件触发来控制流程的,事件触发的情景便形成了场景,而同一事件不同的触发顺序和处理结果就形成事件流。这种在软件设计方面的思想也可以引入到软件测试中,可以比较生动地描绘出事件触发时的情景,有利于测试设计者设计测试用例,同时使测试用例更容易理解和执行。

    场景法组成:基本流和备选流:如下图所示,图中经过用例的每条路径都用基本流和备选流来表示,直黑线表示基本流,是经过用例的最简单的路径。备选流用不同的色彩表示,一个备选流可能从基本流开始,在某个特定条件下执行,然后重新加入基本流中(如备选流1和3);也可能起源于另一个备选流(如备选流2),或者终止用例而不再重新加入到某个流(如备选流2和4)。

     

    备选流

    每个经过用例的可能路径,可以确定不同的用例场景。从基本流开始,再将基本流和备选流结合起来,可以确定以下用例场景:

    场景 1 基本流

    场景 2 基本流 备选流 1

    场景 3 基本流 备选流 1 备选流 2

    场景 4 基本流 备选流 3

    场景 5 基本流 备选流 3 备选流 1

    场景 6 基本流 备选流 3 备选流 1 备选流 2

    场景 7 基本流 备选流 4

    场景 8 基本流 备选流 3 备选流 4

    场景法的核心概念

    1、基本流(正确流):模拟用户正确的操作流程

    目的:验证软件的业务流程和主要功能

    2、备选流(错误流):模拟用户错误的操作流程

    目的:验证软件的错误处理能力

    场景法的本质

    1、场景法是一种基于等价类划分的测试技术(技术层面)

    2、场景法的应用是基于对软件业务(需求)的深入理解(业务层面)

    用例设计步骤

    1. 根据说明,描述出程序的基本流及各项备选流

    2. 根据基本流和各项备选流生成不同的场景

    3. 对每一个场景生成相应的测试用例

    4. 对生成的所有测试用例重新复审,去掉多余的测试用例,测试用例确定后,对每一个测试用例确定测试数据值

    举例:分析ATM取款机的场景流程

    例子:分析ATM取款机的场景流程,并设计测试用例和测试数据 

    1、根据需求,找到基本流和备选流(找出正确的操作流程和可能出错的环节)

    基本流:1.插入磁卡

         2.ATM验证账户正确

         3.输入密码正确,通过验证

         4.输入取款金额

         5.取出金额

         6.取卡

    备选流一:账户不存在或者受限制

    备选流二:密码不正确,还有输入机会

    备选流三:密码不正确,没有输入机会

    备选流四:卡中余额不足

    备选流五:ATM机中余额不足

    备选流六:超过每日最大提款限额

    备选流七:输入金额非100的倍数

     

    2.白盒测试(White-box Testing)

    白盒测试又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。盒子指的是被测试的软件,白盒指的是盒子是可视的,你清楚盒子内部的东西以及里面是如何运作的。

    "白盒"法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。"白盒"法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。白盒测试是指打开盒子,去研究里面的源代码和程序结果。

    白盒测试也是接口测试的一种。

    目的

    1.保证一个模块中的所有独立路径至少被执行一次;

    2.对所有的逻辑值均需要测试真、假两个分支;

    3.在上下边界及可操作范围内运行所有循环;

    4.检查内部数据结构以确保其有效性。

    测试方法

    白盒测试的测试方法有代码检查法、静态结构分析法、静态质量度量法、逻辑覆盖法、基本路径测试法、域测试、符号测试、Z路径覆盖和程序变异。

    白盒测试法的覆盖标准有逻辑覆盖、循环覆盖和基本路径测试。

    覆盖标准

    逻辑覆盖有:语句覆盖、判定覆盖(分支覆盖)、条件覆盖、判定/条件覆盖、条件组合覆盖、路径覆盖;

    控制结构覆盖有:基本路径测试、循环测试、条件测试、数据流测试 

    代码检查法

       代码检查是白盒测试的一种静态测试方法,是一种对程序代码进行静态检查。代码检查包括桌面检查、代码审查和走查等,主要检查:

    1. 检查代码和设计的一致性;
    2. 代码的可读性及对软件设计标准的遵循情况;
    3. 代码逻辑表达的正确性;
    4. 代码结构的合理性;
    5. 发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分;
    6. 违背程序编程风格的内容,包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容。

    代码检查方法

    (1)  桌面检查:

    这是一种传统的检查方法,由程序员检查自己编写的程序。程序员在程序通过编译之后,对源程序代码进行分析、检验,并补充相关文档,目的是发现程序中的错误。由于程序员熟悉自己的程序及其程序设计风格,桌面检查由程序员自己进行可以节省很多的检查时间,但应避免主观片面性。

    (2)代码审查
        由若干程序员和测试员组成一个审查小组,通过阅读、讨论和争议,对程序进行静态分析的过程。代码审查分两步:第一步,小组负责人提前把设计规格说明书、控制流程图、程序文本及有关要求、规范等分发给小组成员,作为审查的依据。小组成员在充分阅读这些材料后,进入审查的第二步,召开程序审查会。在会上,首先由程序员逐句简介程序的逻辑。在此过程中,程序员或其他小组成员可以提出问题,展开讨论,审查错误是否存在。实践表明,程序员在讲解过程中能发现许多原来自己没有发现的错误,而讨论和争议则促进了问题的暴露。
        在会前,应当给审查小组每个成员准备一份常见错误的清单,把以往所有可能发生的常见错误罗列出来,供与会者对照检查,以提高审查的失效。这个常见的错误清单也成为检查表,它把程序中可能发生的各种错误进行分类,对每一类错误列出尽可能多的典型错误,然后把它们制成表格,供再审查时使用。
    (3)走查
        与代码审查基本相同,分为两步,第一步也是把材料分给走查小组的每个成员,让他们认真研究程序,然后再开会。开会的程序与代码审查不同,不是简单地读程序和对照错误检查表进行检查,而是让与会者“充当”计算机,即首先由测试组成员为所测试程序准备一批有代表性的测试用例,提交给走查小组。走查小组开会,集体扮演计算机角色,让测试用例沿程序的逻辑运行一遍,随时记录程序的踪迹,供分析和讨论用。

    代码检查应在编译和动态测试之前进行,在检查前,应准备好需求描述文档、程序设计文档、程序的源代码清单、代码编译标准和代码缺陷检查表等。在实际使用中,代码检查能快速找到缺陷,发现30%~70%的逻辑设计和编码缺陷,而且代码检查看到的问题本身而非征兆。但是代码检查非常耗费时间,而且代码检查需要知识和经验的积累。
        代码检查可以使用测试软件进行自动化测试,以利于提高测试效率,降低劳动强度,或者使用人工进行测试,以充分发挥人力的逻辑思维能力。

    代码检查项目

    变量交叉引用表;标号的交叉引用表;检查子程序、宏、函数;等价性检查;常量检查;标准检查;风格检查;比较控制流;选择、激活路径;补充文档
    根据检查项目可以编制代码规则、规范和检查表等作为测试用例,如编码规范、代码检查规范、缺陷检查表等。

    编码规范

    编码规范是指程序在编写过程中必须遵循的规则,一般会详细制定代码的语法规则、语法格式等。

    代码检查规范

    在代码检查中,需要依据被测软件的特点,选用适当的标准与规则规范。在使用测试软件进行自动化代码检查时,测试工具一般会内置许多的编码规则。在自动化测试基础上使用桌面检查、代码走查、代码审查等人工检查的方法仔细检查程序的结构、逻辑等方面的缺陷。

    缺陷检查表

    在进行人工代码检查时,代码缺陷检查表是我们用到的测试用例。代码缺陷检查表中一般包括容易出错的地方和在以往的工作中遇到的典型错误。

    静态结构分析法

    在静态结构分析中,测试者通过使用测试工具分析程序源代码的系统结构、数据结构、内部控制逻辑等内部结构,生成函数调用关系图、模块控制流图、内部文件调用关系图、子程序表、宏和函数参数表等各类图形图标,可以清晰地标识整个软件系统的组成结构,使其便于阅读和理解,然后可以通过分析这些图标,检查软件有没有存在缺陷或错误。

    其中函数调用关系图通过应用程序中各函数之间的调用关系展示了系统的结构。通过查看函数调用关系图,可以检查函数之间的调用关系是否符合要求,是否存在递归调用,函数的调用是否过深,有没有存在独立的没有被调用的函数。从而可以发现系统是否存在结构缺陷,发现哪些函数是重要的,哪些是次要的,需要使用什么级别的覆盖要求等。

      模块控制流图是与程序流程图相类似的,由许多节点和连接节点的边组成的一种图形,其中一个节点代表一条语句或数条语句,边代表节点间控制流向,它显示了一个函数的内部逻辑结构。模块控制流图可以直观地反映出一个函数的内部逻辑结构,通过检查这些模块控制流图,能够很快发现软件的错误与缺陷。

    检查项:代码风格和规则审核;程序设计和结构的审核;业务逻辑的审核;走查、审查与技术复审手册。

     

     

     

    静态质量度量法

    1、度量规则

      度量规则使用了代码行数、注释频度等参数度量软件的各种行为属性。

    2、分类标准

      软件的可维护性采用以下四个分类标准来评估:可分析性(ANALYZABILITY)、可修改性(CHANGEABILITY)、稳定性(STABILITY)、可测性(TESTABILITY)。每个分类标准由一系列度量规则组成,各个规则分配一个权重,由规则的取值与权重值计算出每个分类标准的取值。

      function_TESTABILITY_DRCT_CALLS+LEVL+PATH+PARA

    3、质量因素

      质量因素的取值与分类标准的计算方式类似:依据各分类标准取值组合权重方法计算。

      function_MAINTAINABILITY=function_ANALYZABILITY + function_CHANGEABILITY + function_ATABILITY + function_TESTABILITY

    质量度量模型(从上到下)

    质量因素(Factors):与分类标准的计算方式相似,依据各分类标准取值组合权重方法来计算,依据结果将软件质量分为四个等级,与分类标准等级内容相同。

    分类标准(criteria):对某一软件质量分为不同的分类标准,每个分类标准由一系列度量规则组成,每个规则分配一个权重,每个分类标准的取值由规则的取值与权重值计算得出,依据结果将软件质量分为四个等级:

    优秀(exceent):符合本模型框架中的所有规则(可以接受)

    良好(good):未大量偏离模型框架中的规则(可以接受)

    一般(fair):违背了模型框架中的大量规则(可以接受)

    较差(poor):无法保障正常的软件可维护性(不可以接受)

    度量规则(Metrics):使用代码行数、注释频度等参数度量软件各种行为属性

    逻辑覆盖

    逻辑覆盖是以程序内部的逻辑结构为基础的设计测试用例的技术。其中逻辑覆盖包括语句覆盖、判定覆盖、条件覆盖、判定条件组合覆盖、条件组合覆盖和路径覆盖。六种覆盖标准发现错误的能力呈由弱到强的变化:

    1.语句覆盖每条语句至少执行一次。

    2.判定覆盖每个判定的每个分支至少执行一次。

    3.条件覆盖每个判定的每个条件应取到各种可能的值。

    4.判定/条件覆盖同时满足判定覆盖和条件覆盖。

    5.条件组合覆盖每个判定中各条件的每一种组合至少出现一次。

    6.路径覆盖使程序中每一条可能的路径至少执行一次。

     

     

    逻辑覆盖原则

     

    语句覆盖

    定义

    “语句覆盖”是一个比较弱的测试标准,它的含义是:在测试时,首先设计若干个测试用例,然后运行被测程序, 使程序中的每个可执行语句至少执行一次。这时所谓“若干个”,自然是越少越好。即用最少得测试用例来达到语句全覆盖。

    用例设计

    为使程序中每个语句至少执行一次,只需设计一个能通过路径ace的例子就可以了,例如选择输入数据为: A=2,B=0,X=4 

    这样该程序段的4个语句均得到执行,从而作到了语句覆盖。

     

    优点

    可以很直观地从源代码得到测试用例,无须细分每条判定表达式。

    缺点

    由于这种测试方法仅仅针对程序逻辑中显式存在的语句(即可执行语句),但对于隐藏的条件和可能到达的隐式逻辑分支,是无法测试的。

    判定覆盖

    定义

    比“语句覆盖”稍强的覆盖标准是“判定覆盖”(或称branch coverage分支覆盖)标准。判定覆盖准则进行测试是指,设计若干测试用例,运行被测程序,使得程序中每个判断的取真分支和取假分支至少经历一次,即判断的真假值均曾被满足。判定覆盖又称为分支覆盖。设计测试用例只需要用最少条数,以判定条件结果为全真或者全假的思路来编写测试用例。

    用例设计

    如果设计两个例子,使它们能通过路径ace和abd,或者通过路径acd和abe,就可达到“判定覆盖”标准,为此,可以选择输入数据为: 
    ①A=2,B=0,X=4(沿判定条件结果为全真路径ace执行)

    ②A=1,B=1,X=1(沿判定条件结果为全假路径abd执行) 

     

    优点

    判定覆盖比语句覆盖要多几乎一倍的测试路径,当然也就具有比语句覆盖更强的测试能力。同样判定覆盖也具有和语句覆盖一样的简单性,无须细分每个判定就可以得到测试用例。

    缺点

    往往大部分的判定语句是由多个逻辑条件组合而成(如,判定语句中包含AND、OR、CASE),若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径。

    条件覆盖

    定义

    条件覆盖于分支覆盖不同,条件覆盖要求所设计的测试用例能使每个判定中的每一个条件都获得可能的取值,即每个条件至少有一次真值、有一次假值。

    用例设计

    A>1、B=0、A=2、X>1

    为了达到“条件覆盖”标准,需要执行足够的测试用例使得在判定条件1处有:  

    A>1、A≤1、B=0、B≠0

    等各种结果出现,以及在判定条件2处有:A=2、A≠2、X>1、X≤1等各种结果出现。

    现在只需设计以下两个测试用例就可满足这一标准:

    ①  A=2,B=0,X=4(沿判定条件中的各个条件都为真路径ace执行);

    ②  A=1,B=1,X=1(沿判定条件中的各个条件都为假路径abd执行) 

     

    优点

    增加了对条件判定情况的测试,增加了测试路径。

    缺点

    条件覆盖不一定包含判定覆盖。条件覆盖只能保证每个条件至少有一次为真,而不考虑所有的判定结果。

    判定条件组合覆盖

    定义

    执行足够的测试用例,使得判定中每个条件取到各种可能的值,并使每个判定取到各种可能的结果。

    用例设计

    A>1、B=0、A=2、X>1

    为了达到“条件覆盖”标准,需要执行足够的测试用例使得在判定条件1处有:  

    A>1、A≤1、B=0、B≠0

    等各种结果出现,以及在判定条件2处有:A=2、A≠2、X>1、X≤1等各种结果出现。

    另外也要满足判定条件1处结果出现一次真和一次假,则要保证(A>1 AND B=0)为真(A=2,B=0)和为假(A=1,B=1),同时也满足了条件覆盖说的每个条件都要出现一次真和一次假。(A=2为真,B=0为真)和为假(A=1为假,B=1为假)。

    同理判定条件2处结果出现一次真和一次假,则要保证(A=2 OR X>1)为真(A=2,X=4)和为假(A=1,X=1),同时也满足了条件覆盖说的每个条件都要出现一次真和一次假。(A=2为真,X=4为真)和为假(A=1为假,X=1为假)。

    现在只需设计以下两个测试用例就可满足这一标准:

    ①  A=2,B=0,X=4(沿判定条件中的各个条件都为真,同时也满足判定条件结果均为真路径ace执行);

    ②  A=1,B=1,X=1(沿判定条件中的各个条件都为假,同时也满足判定条件结果均为假路径abd执行) 

     

    优点

    能同时满足判定、条件两种覆盖标准。

    缺点

    判定/条件覆盖准则的缺点是未考虑条件的组合情况。

    条件组合覆盖

    定义

    执行足够的例子,使得每个判定中条件的各种可能组合都至少出现一次。显然,满足“条件组合覆盖”的测试用例是一定满足“判定覆盖”、“条件覆盖”和“判定/条件覆盖”的。

    用例设计

     

    条件组合覆盖说的判定条件里的每个条件组合在一起形成的各种可能。

    使得下面8种条件组合都能够出现:

    1)A>1, B=0    2)A>1, B≠0     3)A≤1, B=0    4)A≤1, B≠0   

    5)A=2, X>1    6)A=2, X≤1     7)A≠2, X>1    8)A≠2, X≤1

    判定条件1里有2个条件,所以条件组合的情况是2*2=4个的情况;排列组合里的组合逻辑形成的个数。如果有3个条件,则就有2*2*2=8个的情况,以此类推。

    判定条件1:(A=2为真,B=0为真)、(A=2为真,B=1为假)、(A=1为假,B=0为真)、(A=1为假,B=1为假)。

    判定条件2:(A=2为真,X=4为真)、(A=2为真,X=1为假)、(A=1为假,X=4为真)、(A=1为假,X=1为假)。

    现在只需设计以下两个测试用例就可满足这一标准:

    ①  A=2,B=0,X=4(沿判定条件中的各个条件A=2为真,B=0为真,A=2为真,X=4为真,路径ace执行);

    ②  A=2,B=1,X=1(沿判定条件中的各个条件A=2为真,B=1为假,A=2为真,X=1为假,路径abe执行);

    ③  A=1,B=0,X=2(沿判定条件中的各个条件A=1为假,B=0为真,A=1为假,X=2为真,路径abe执行);

    ④  A=1,B=1,X=1(沿判定条件中的各个条件A=1为假,B=1为假,A=1为假,X=1为假,路径abd执行) 

    上面四个例子虽然满足条件组合覆盖,但并不能覆盖程序中的每一条路径,例如路径acd就没有执行,因此,条件组合覆盖标准仍然是不彻底。

    优点

    能同时满足判定、条件两种覆盖标准。条件组合覆盖准则满足判定覆盖、条件覆盖和判定/条件覆盖准则。

    缺点

    线性地增加了测试用例的数量。

    路径覆盖

    定义

    选取足够多的测试数据,使程序的每条可能路径都至少执行一次(如果程序图中有环,则要求每个环至少经过一次)。

    对于比较简单的小程序来说,实现路径覆盖是可能的,但是如果程序中出现了多个判断和多个循环,可能的路径数目将会急剧增长,以致实现路径覆盖是几乎不可能的。

    所以我们需要路径分析,计算程序中的路径数(复杂度)。

    以下的公式:V(G)=e-n+2

    PS:其中e为边数,n为结点数。

    优点

    这种测试方法可以对程序进行彻底的测试,比前面五种的覆盖面都广。

    缺点

    需要设计大量、复杂的测试用例,使得工作量呈指数级增长,不见得把所有的条件组合都覆盖。

    基本路径测试法

    在程序控制图的基础上,通过分析控制构造的环行复杂性,导出基本可执行路径集合,从而设计测试用例。设计出的测试用例要保证在测试中程序的每一个基本独立路径至少执行一次。

    在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例。

    包括以下4 个步骤

    1. 程序的控制流图:描述程序控制流的一种图示方法。

    2. 程序圈复杂度:McCabe复杂性度量。从程序的环路复杂性可导出程序基本路径集合中的独立路径条数,这是确定程序中每个可执行语句至少执行一次所必须的测试用例数目的上界。

    3. 导出测试用例:根据圈复杂度和程序结构设计用例数据输入和预期结果。

    4. 准备测试用例:确保基本路径集中的每一条路径的执行。

    一个工具方法: 

    图形矩阵:是在基本路径测试中起辅助作用的软件工具,利用它可以实现自动地确定一个基本路径集。

    另外,对于测试用例的选择除了满足所选择的覆盖程度(或覆盖标准)外还需要尽可能的采用边界值分析法、错误推测法等常用地设计方法。采用边界值分析法设计合理的输入条件与不合理的输入条件;条件边界测试用例应该包括输入参数的边界与条件边界(if,while,for,switch ,SQL Where子句等)。错误推测法,列举出程序中所有可能的错误和容易发生错误的特殊情况,根据它们选择测试用例;在编码、单元测试阶段可以发现很多常见的错误和疑似错误,对于这些错误应该作重点测试,并设计相应的测试用例。

    控制流图

    基本语句对应的控制流图:

     

    程序流程图->控制流图

     

    如何根据程序流程图画出控制流程图?

      在将程序流程图简化成控制流图时,应注意:

      1)在选择或多分支结构中,分支的汇聚处应有一个汇聚结点。

      2)边和结点圈定的范围叫做区域,当对区域计数时,图形外的区域也应记为一个区域。

    如下图所示:

    三种计算方法:

    1. 控制流图中区域的数量

    2. V(G)= E-N+2,E是边数,N是结点数

    3. V(G)= P+1,P是判定结点的数量

    圆圈称为控制流图的一个结点,表示一个或多个无分支的语句或源程序语句

    独立路径( 基本路径)

    一条程序执行的路径 ,至少包含一条在定义该路径之前的其他基本路径中所不曾用过的边( 即:至少引入程序的一个新处理语句集合或一个新条件)

    注意:独立路径不应该经过同一个判定结点的左右两侧,否则这条路径如果出现错误,则不知道是哪一侧出现错误。

    设计测试用例步骤 

    第一步:画出控制流图

      流程图用来描述程序控制结构。可将流程图映射到一个相应的流图(假设流程图的菱形决定框中不包含复合条件)。在流图中,每一个圆,称为流图的结点,代表一个或多个语句。一个处理方框序列和一个菱形决策框可被映射为一个结点,流图中的箭头,称为边或连接,代表控制流,类似于流程图中的箭头。一条边必须终止于一个结点,即使该结点并不代表任何语句(例如:if-else-then结构)。由边和结点限定的范围称为区域。计算区域时应包括图外部的范围。

    画出其程序流程图和对应的控制流图如下

           

    第二步:计算圈复杂度

      圈复杂度是一种为程序逻辑复杂性提供定量测度的软件度量,将该度量用于计算程序的基本的独立路径数目,为确保所有语句至少执行一次的测试数量的上界。独立路径必须包含一条在定义之前不曾用到的边。

      有以下三种方法计算圈复杂度:

      流图中区域的数量对应于环型的复杂性;

      给定流图G的圈复杂度V(G),定义为V(G)=E-N+2,E是流图中边的数量,N是流图中结点的数量;

      给定流图G的圈复杂度V(G),定义为V(G)=P+1,P是控制流图G中判定结点的数量。

      

    第三步:导出测试用例

      根据上面的计算方法,可得出四个独立的路径。(一条独立路径是指和其他的独立路径相比,至少引入一个新处理语句或一个新判断的程序通路。V(G)值正好等于该程序的独立路径的条数。)

      路径1:4-14

      路径2:4-6-7-14

      路径3:4-6-8-10-13-4-14

      路径4:4-6-8-11-13-4-14

      根据上面的独立路径,去设计输入数据,使程序分别执行到上面四条路径。

    第四步:准备测试用例

      为了确保基本路径集中的每一条路径的执行,根据判断结点给出的条件,选择适当的数据以保证某一条路径可以被测试到,满足上面例子基本路径集的测试用例是:

    工具方法:图形矩阵

    导出控制流图和决定基本测试路径的过程均需要机械化,为了开发辅助基本路径测试的软件工具,称为图形矩阵(graph matrix)的数据结构很有用。利用图形矩阵可以实现自动地确定一个基本路径集。一个图形矩阵是一个方阵,其行/列数控制流图中的结点数,每行和每列依次对应到一个被标识的结点,矩阵元素对应到结点间的连接(即边)。

    对每个矩阵项加入连接权值(link  weight),图矩阵就可以用于在测试中评估程序的控制结构,连接权值为控制流提供了另外的信息。最简单情况下,连接权值是 1(存在连接)或0(不存在连接),但是,连接权值可以赋予更有趣的属性:

    执行连接(边)的概率。

    穿越连接的处理时间。

    穿越连接时所需的内存。

    穿越连接时所需的资源。

    上图为图形矩阵:

    连接权为“1”表示存在一个连接,在图中如果一行有两个或更多的元素“1”,则这行所代表的结点一定是一个判定结点,通过连接矩阵中有两个以上(包括两个)元素为“1”的个数,就可以得到确定该图圈复杂度的另一种算法。

    循环测试

         从本质上来说,循环测试的目的就是检查循环结构的有效性。

    四种循环 :简单循环 、嵌套循环 、串接循环、无结构循环(非结构循环)

    简单循环

    对于简单循环,测试应包括以下几种,其中的n 表示循环允许的最大次数。

    1.零次循环:从循环入口直接跳到循环出口。 (换句话说:跳过循环)

    2. 一次循环:查找循环初始值方面的错误。

    3. 二次循环:检查在多次循环时才能暴露的错误。

    4. m次循环:此时的m<n-1(通常取m=n/2),也是检查在多次循环时才能暴露的错误。

    5. n(最大)次数循环、n+1(比最大次数多一)次的循环、n-1(比最大次数少一)次的循环。

    嵌套循环

    1.从最内层循环开始,设置所有其他层的循环为最小值;

    2.对最内层循环使用简单循环的全部测试。测试时保持所有外层循环的循环变量(迭代参数)为最小值。另外,对越界值和非法值增加一些额外的测试。

    3.逐步外推,对其外面一层循环进行测试。测试时保持所有外层循环的循环变量取最小值,所有其它嵌套内层循环的循环变量取“典型”值。

    4.反复进行,直到所有各层循环测试完毕。

    5.对全部各层循环同时取最小循环次数,或者同时取最大循环次数。对于后一种测试,由于测试量太大,需人为指定最大循环次数。

    举例说明

    1 案例描述 

    昨天去面试,面试官出了一道面试题目,但是知道一个初步的优化,但不知道为什么会有性能提高,下去上网才恍然大悟:

    题目是这样的:请对以下的代码进行优化 

    Java代码  

    for (int i = 0; i < 1000; i++)  

        for (int j = 0; j < 100; j++)  

            for (int k = 0; k < 10; k++)  

                testFunction (i, j, k);  

    (注:为了同后面的内容一致,这里对原题目进行了部分修改) 
    2 案例分析 

    从给出的代码可知,不论如何优化,testFunction执行的次数都是相同的,该部分不存在优化的可能。那么,代码的优化只能从循环变量i、j、k的实例化、初始化、比较、自增等方面的耗时上进行分析。 
    首先,我们先分析原题代码循环变量在实例化、初始化、比较、自增等方面的耗时情况:

    变量

    实例化(次数)

    初始化(次数)

    比较(次数)

    自增(次数)

    i

    1

    1

    1000

    1000

    j

    1000

    1000

    1000 * 100

    1000 * 100

    k

    1000 * 100

    1000 * 100

    1000 * 100 * 10

    1000 * 100 * 10

    (注:由于单次耗时视不同机器配置而不同,上表相关耗时采用处理的次数进行说明) 
    该代码的性能优化就是尽可能减少循环变量i、j、k的实例化、初始化、比较、自增的次数,同时,不能引进其它可能的运算耗时。 
    3 解决过程 
    从案例分析,对于原题代码,我们提出有两种优化方案: 
    3.1 优化方案一 
    代码如下: 

    Java代码  

    for (int i = 0; i < 10; i++)  

        for (int j = 0; j < 100; j++)  

            for (int k = 0; k < 1000; k++)  

                testFunction (k, j, i);  

    该方案主要是将循环次数最少的放到外面,循环次数最多的放里面,这样可以最大程度的(注:3个不同次数的循环变量共有6种排列组合情况,此种组合为最优)减少相关循环变量的实例化次数、初始化次数、比较次数、自增次数,方案耗时情况如下: 

    变量

    实例化(次数)

    初始化(次数)

    比较(次数)

    自增(次数)

    i

    1

    1

    10

    10

    j

    10

    10

    10 * 100

    10 * 100

    k

    10 * 100

    10 * 100

    10 * 100 * 1000

    10 * 100 * 1000

    3.2 优化方案二 
    代码如下: 

    Java代码  

    int i, j, k;  

    for (i = 0; i < 10; i++)  

        for (j = 0; j < 100; j++)  

            for (k = 0; k < 1000; k++)  

                testFunction (k, j, i);  

    该方案在方案一的基础上,将循环变量的实例化放到循环外,这样可以进一步减少相关循环变量的实例化次数,方案耗时情况如下: 

    变量

    实例化(次数)

    初始化(次数)

    比较(次数)

    自增(次数)

    i

    1

    1

    10

    10

    j

    1

    10

    10 * 100

    10 * 100

    k

    1

    10 * 100

    10 * 100 * 1000

    10 * 100 * 1000

    4 解决结果 
    那么,提出的优化方案是否如我们分析的那样有了性能上的提升了呢?我们编写一些测试代码进行验证,数据更能说明我们的优化效果。 
    4.1 测试代码 

    Java代码  

    public static void testFunction(int i, int j, int k) {  

            System.out.print("");   // 注:该方法不影响整体优化,这里只有简单输出  

        }  

         public static void testA() {  

            long start = System.nanoTime();  

            for (int i = 0; i < 1000; i++)  

                for (int j = 0; j < 100; j++)  

                    for (int k = 0; k < 10; k++)  

                        testFunction(i, j, k);  

            System.out.println("testA time>>" + (System.nanoTime() - start));  

        }  

          public static void testB() {  

            long start = System.nanoTime();  

            for (int i = 0; i < 10; i++)  

                for (int j = 0; j < 100; j++)  

                    for (int k = 0; k < 1000; k++)  

                        testFunction(k, j, i);  

            System.out.println("testB time>>" + (System.nanoTime() - start));  

        }  

          public static void testC() {  

            long start = System.nanoTime();  

            int i;  

            int j;  

            int k;  

            for (i = 0; i < 10; i++)  

                for (j = 0; j < 100; j++)  

                    for (k = 0; k < 1000; k++)  

                        testFunction(k, j, i);  

            System.out.println("testC time>>" + (System.nanoTime() - start));  

    }  

    4.2 测试结果 
    1、测试机器配置:Pentium(R) Dual-Core CPU E5400 @2.70GHz 2.70GHz, 2GB内存; 
    2、循环变量i、j、k循环次数分别为10、100、1000,进行5组测试,测试结果如下: 

    第1组

    第2组

    第3组

    第4组

    第5组

    原方案

    171846271

    173250166

    173910870

    173199875

    173725328

    方案一

    168839312

    168466660

    168372616

    168310190

    168041251

    方案二

    168001838

    169141906

    168230655

    169421766

    168240748

    从上面的测试结果来看,优化后的方案明显性能优于原方案,达到了优化的效果。但优化方案二并没有如我们预期的优于方案一,其中第2、4、5组的数据更是比方案一差,怀疑可能是循环次数太少,以及测试环境相关因素影响下出现的结果。 
    3、重新调整循环变量i、j、k循环次数分别为20、200、2000,进行5组测试,测试结果如下: 

    第1组

    第2组

    第3组

    第4组

    第5组

    原方案

    1355397203

    1358978176

    1358128281

    1350193682

    1354786598

    方案一

    1343482704

    1348410388

    1343978037

    1347919156

    1340697793

    方案二

    1342427528

    1343897887

    1342662462

    1342124048

    1336266453

    从上面的测试结果来看,优化后的方案基本符合我们的预期结果。 
    5 总结 
    从案例分析和解决过程中的三个表的分析可知,优化方案一和优化方案二的性能都比原代码的性能好,其中优化方案二的性能是最好的。在嵌套For循环中,将循环次数多的循环放在内侧,循环次数少的循环放在外侧,其性能会提高;减少循环变量的实例化,其性能也会提高。从测试数据可知,对于两种优化方案,如果在循环次数较少的情况下,其运行效果区别不大;但在循环次数较多的情况下,其效果就比较明显了。

    串接循环

    对于串接循环,要区别两种情况。

    1.如果各个循环互相独立,则串接循环可以用与简单循环相同的方法进行测试。

    2.如果有两个循环处于串接状态,而前一个循环的循环变量的值是后一个循环的初值。则这几个循环不是互相独立的,则需要使用测试嵌套循环的办法来处理。

     

    对于非结构循环,不能测试, 应重新设计循环结构,使之成为其它循环方式,然后再进行测试。

    条件测试

    条件测试方法注重于测试程序中的条件。是检查程序模块中所包含逻辑条件的测试用例设计方法。

    条件

    程序中的条件分为简单条件和复合条件。

    简单条件是一个布尔变量或一个可能带有NOT(“!”)操作符的关系表达式。关系表达式的形式如:

    E1<关系操作符>E2

    其中E1和E2是算术表达式,而<关系操作符>是下列之一:“<”、“≤”、“=”、“≠”(“!=”)、“>”、或“≥”。

    复合条件由简单条件通过逻辑运算符(AND、OR、NOT)和括号连接而成,不含关系表达式的条件称为布尔表达式。

    所以条件的成分类型包括:布尔操作符、布尔变量、布尔括弧(括住简单或复杂条件)、关系操作符、算术表达式。

    条件测试的目的

    条件测试是测试程序条件错误和程序的其他错误。如果程序的测试集能够有效地检测程序中的条件错误,则该测试集可能也会有效地检测程序中的其他错误。此外,如果测试策略对检测条件错误有效,则它也可能有效地检测程序错误。

    条件测试策略

    1) 穷举测试(条件组合)

    有n个变量的布尔表达式需要2n个可能的测试(n>0)。这种策略可以发现布尔操作符、变量和括弧的错误,但是只有在n很小时实用。

    2) 分支测试

    分支测试可能是最简单的条件测试策略,它是真假分支必须至少执行一次的路径策略,对于复合条件C,C的真分支和假分支以及C中的每个简单条件都需要至少执行一次。

    域测试是对于大于、小于和等于的值的测试路径策略。域测试要求从有理表达式中导出三个或四个测试,有理表达式的形式如:

    E1<关系操作符>E2

    需要三个测试分别用于计算E1的值是大于、等于或小于E2的值。如果<关系操作符>错误,而E1和E2正确,则这三个测试能够发现关系算式的错误。为了发现E1和E2的错误,计算E1小于或大于E2的测试应使两个值间的差别尽可能小。

    3) BRO(branch and relational) 测试

    如果在一个判定的复合条件表达式中每个布尔变量和关系运算符最多只出现一次,而且没有公共变量,应用一种称之为BRO(分支与关系运算符)的测试法可以发现多个布尔运算符或关系运算符错,以及其他错误。

    BRO策略引入条件约束的概念。设有n个简单条件的复合条件C,其条件约束为D= (D1,D2,…,Dn) ,其中Di(0<i≤n)是条件C中第i个简单条件的输出约束。如果在C的执行过程中,其每个简单条件的输出都满足D中对应的约束,则称条件C的条件约束D由C的执行所覆盖。对于布尔变量或布尔表达式B,B的输出约束必须是真(t)或假(f);对于关系表达式,其输出约束为符号>、=、< 。

    域测试

     

     

    由于程序中每条路径对应着一个输入域,是程序的一个子计算。如果程序的控制流有错误,则对某一特定的输入可能执行的是一条错误路径,这种错误被称为路径错误或域错误。

    而域测试主要是针对域错误进行的测试。

    域测试的基本步骤如下:

    (1):根据各个分支谓词,给出子域的分割图;

    (2):对每个子域的边界,采用ON-OFF-ON原则选取测试点。

    (3):在子域内选取一些测试点。

    (4):针对这些测试点进行测试。

    符号测试

     

    Z路径覆盖测试

     

    实施步骤

    1.测试计划阶段:根据需求说明书,制定测试进度。

    2.测试设计阶段:依据程序设计说明书,按照一定规范化的方法进行软件结构划分和设计测试用例。

    3.测试执行阶段:输入测试用例,得到测试结果。

    4.测试总结阶段:对比测试的结果和代码的预期结果,分析错误原因,找到并解决错误。

    优缺点
    优点

    1.迫使测试人员去仔细思考软件的实现

    2.可以检测代码中的每条分支和路径

    3.揭示隐藏在代码中的错误

    4.对代码的测试比较彻底

    5.最优化

    缺点

    1.代价有些高,需要测试人员有编程能力

    2.无法检测代码中遗漏的路径和数据敏感性错误

    3.不能直接验证需求的正确性

    局限

    即使每条路径都测试了仍然可能有错误。可能出现的情况如下:

    穷举路径测试决不能查出程序违反了设计规范,即程序本身是个错误的程序。

    穷举路径测试不可能查出程序中因遗漏路径而出错。

    穷举路径测试可能发现不了一些与数据相关的错误。

    3.灰盒测试(Gray-Box Testing)

    灰盒测试是介于白盒测试和黑盒测试之间的一种,灰盒测试多用于集成测试阶段,不仅关注输入、输出的正确性,同时也关注程序内部的情况。灰盒测试不像白盒测试那样详细、完整,但又比黑盒测试更关注程序的内部逻辑,常常是通过一些表征性的现象、事件、标志来判断内部的运行状态。有时候输出是正确的,但内部其实已经错误了,这种情况非常多,如果每次都通过白盒测试来操作,效率会很低,因此需要采取这样的一种灰盒的方法。

    灰盒测试:功能+接口

    定义

    灰盒测试由方法和工具组成,这些方法和工具取材于应用程序的内部知识和与之交互的环境,能够用于黑盒测试以增强测试效率、错误发现和错误分析的效率。灰盒测试涉及输入和输出,但使用关于代码和程序操作等通常在测试人员视野之外的信息设计测试。

    目的

    一、确认软件的质量

    二、提供信息,提供给开发人员或程序经理的反馈信息,为风险评估所准备的信息。

    三、软件测试不仅是在测试软件产品的本身,而且还包括软件开发的过程。

    测试任务

    1、寻找Bug;

    2、避免软件开发过程中的缺陷;

    3、衡量软件的品质;

    4、关注用户的需求。

    如何做好灰盒测试?
    1. 测试定位要清晰。灰盒测试的对象应该是整个产品,而非各个组件,应从整个测试产品的业务出发进行测试设计。
    2. 测试阶段要正确。灰盒测试应该在集成测试中采用,他并不适合于单元测试。
    3. 测试辅助要必备。灰盒测试需要深入产品代码逻辑,对于测试人员来说,业务逻辑图是必不可少的,测试人员需要根据业务逻辑图进行功能点划分,并扩展用例。另外可以借助于测试覆盖率等工具辅助查找遗漏功能点。
    4. 运行状态检查点要仔细选择。灰盒测试对于程序运行状态的检查往往采用标志来判断,测试人员一定要仔细考虑,否则很容易遗漏某些bug。
    做灰盒测试需要哪些条件呢?

    1、需要在测试中,除了部署产品之外,还有就是程序源代码,不管外部是多少漂亮界面或易用的功能,最终都是由源代码来实现的。所以在部署时,要安装源代码。从源代码编译生成的目录中运行软件。
    2、需要代码覆盖率工具的配置;部署可以针对本软件开发语言的代码覆盖率工具;
    3、测试人员要具备阅读代码的能力,其对开发语言的熟悉程度和程序设计经验多少决定了采用灰盒测试能够取得多大的好处,所以配置这方面的测试人员或进行必要的培训是必要的。
    那么有人可能问,服务器端软件适合做灰盒测试吗?回答是肯定的。任何一个项目都可以从灰盒测试中获得裨益。不管是手机中使用的各种嵌入式软件、还是web页面和服务器端的任何脚本,都可以运用这种测试方法。

    优点

    1、 能够进行基于需求的覆盖测试和基于程序路径覆盖的测试;
    2、 测试结果可以对应到程序内部路径,便于bug的定位、分析和解决;
    3、 能够保证设计的黑盒测试用例的完整性,防止遗漏软件的一些不常用的功能或功能组合;
    4、 能够需求或设计不详细或不完整对测试造成的影响。

    缺点

    1、    投入的时间比黑盒测试大概多20-40%的时间;

    2、    对测试人员的技术要求更高;

    灰盒测试的好处

    测试者可能知道系统组件之间是如何互相作用的,但缺乏对内部程序功能和运作的详细了解。对于内部过程,灰盒测试把程序看作一个必须从外面进行分析的黑盒。灰盒测试通常与web服务应用一起使用,因为尽管应用程序复杂多变,并不断发展进步,因特网仍可以提供相对稳定的接口。由于不需要测试者接触源代码,因此灰盒测试不存在侵略性和偏见。开发者和测试者间有明显的区别,人事冲突的风险减到最小。

    灰盒测试相对于黑盒测试和白盒测试有什么特点?

    1.灰盒测试比白盒测试效率高,从程序的整体出发,而非细节.
    2.灰盒测试健壮性好,相对于白盒测试降低了程序代码改变而导致用例失效的风险。
    3.灰盒测试更细致。灰盒测试要求测试人员关注程序的代码逻辑,根据代码逻辑扩充用例,更加细致。

    按是否执行程序的角度划分

    1.静态测试(Static testing)

    定义

    静态方法是指不运行被测程序本身,而只是静态地检查程序代码、界面或文档中可能存在的错误的过程。仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性,对需求规格说明书、软件设计说明书、源程序做结构分析、流程图分析、符号执行来找错的过程。

    静态测试主要包括各阶段的评审(人工检查)、代码检查、静态结构分析、代码质量度量等,用于对被测程序进行特性分析。

    分析如下:

    检查项:代码风格和规则审核;程序设计和结构的审核;业务逻辑的审核;走查、审查与技术复审手册。

    静态质量:度量所依据的标准是ISO9126。在该标准中,软件的质量用以下几个方面来衡量,即功能性(Functionality)、可靠性(Reliability)、可用性(Usability)、有效性(Efficiency)、可维护性(Maintainability)、可移植性(Portability)。具体到静态测试,这里主要关注的是可维护性。要衡量软件的可维护性,可以从四个方面去度量,即可分析性(Analyzability)、可改变性(Changeability)、稳定性(Stability)以及可测试性(Testability)。具体到软件的可测试性怎么去衡量。又可以从三个度量元去考虑,例如圈复杂度、输入/输出的个数等。圈复杂度越大,说明代码中的路径越多;路径越多,意味着要去做测试,需要写更多的测试用例。输入/输出的个数同样的道理。

    为什么要进行静态测试?

    静态分析潜在收益是很高的: 在软件开发生命周期中,越是后来发现的缺陷,其去除成本呈指数上涨,所以缺陷越早发现越好。静态分析是所有测试中可以最先发现缺陷的方法,极大的降低了软件的修复成本。

    对软件经理,静态分析有助于:

    1) 减少部署后存在错误的风险,去除此时发现的错误是非常昂贵的;

    2) 缩短产品上市时间;

    3) 减少代码审查和测试的成本和时间;

    4) 自动化(部分)审查,没有或多个有限的人工检查;

    5) 消除明显的错误以便改善测试的速度和重点;

    6) 提高代码质量(坚持编码标准);

    7) 实现更高的覆盖率(更多的代码检查):与测试覆盖率相关但并不完全一样,因为重点不同。

    对软件开发人员,静态分析有助于:

    1) 提早找到/阻止错误(在错误变得很难处理之前):工具可用作开发周期的一部分,像编译器;更直接,明显的反馈。

    2) 发现/阻止“难以测试”的错误:例如,静态分析善于检测潜在的内存泄露和缓冲区溢出,从而使开发人员更高效,花费更少的时间调试。

    包括三个方面

    代码测试、界面测试和文档测试

      对于代码测试,主要测试代码是否符合相应的标准和规范。

     对于界面测试,主要测试软件的实际界面与需求中的说明是否相符。

     对于文档测试,主要测试用户手册和需求说明是否符合用户的实际需求。

    对界面和文档的静态测试相对容易,只要测试人员对用户需求仔细分析研究,就很容易发现界面和文档中的缺陷。对程序代码的静态测试相对复杂,需要按照相应语言的代码规范模板(无统一标准,各公司有自己的标准)来逐行检查程序代码。

    静态测试主要检查点:

     

    下面分别从代码、界面、文档三个方面进行详细说明每一部分应该如何进行测试。

    1) 界面测试:

     

     

     

    主要从联机功能、接口测试、报表测试和批量测试几个方面进行阐述。

    2) 文档测试

    主要是需求文档与实际设计和实现是否相符,可以根据界面测试中的点进行测试。

    3) 代码测试

    程序代码的静态测试要复杂得多,需要我们按照相应的代码规范模板来逐行检查程序代码。

    对代码的检查我们推荐使用现有的工具进行。那么我们从哪里获得这个规范模板呢?其实没有一个统一的标准,每个公司内部一般都有自己的编码规范,比如《c/c++编码规范》,你只需要按照上面的条目逐条测试就可以了。

     

    这段C语言编写的小程序,比较简单,实现的功能为:在主函数里输入两个单精度的数a和b,

    然后调用max子函数来求a和b中的大数,最后将大数输出。我们现在就对代码进行静态分析,主要根据一些C语言的基础知识来检查。

    我们把问题分为两种,一种必须修改的,另一种建议修改的。

    必须修改的问题有三个:

    1)程序没有注释。

    注释是程序中非常重要的组成部分,一般占到总行数的1/4左右。程序开发出来不仅是给程序员看,其他程序员和测试人员也要看。有了注释,别人就能很快地了解程序实现的功能。注释应该包含作者,版本号、创建日期等,以及主要功能模块的含义。

    2)子函数max没有返回值的类型。

    由于类型为单精度,我们可以在max()前面加一个float类型声明。

    3)精度丢失问题。

    大家注意“c=max(a,b)”语句,我们知道c的类型为整型int ,而max(a,b)的返回值z为单精度float, 将单精度的数赋值给一个整型的数,c语言的编译器会自动地进行类型转换,将小数部分去掉,比如z=2.5,赋给c则为2,最后输出的结果就不是a和b 中的大数,而是大数的整数部分。

    建议修改的问题也有三个;

    1)Main函数没有返回值类型和参数列表。

    虽然main函数没有返回值和参数,但是我们将其改为void main(void),来表明main函数的返回值和参数都为空,因为在有的白盒测试工具的编码规范中,如果不写void会认为是个错误。

    2)一行代码只定义一个变量。

    3)程序适当加些空行。空行不占内存,会使程序看起来更清晰。

    解释和说明一下静态测试技术

    静态测试不以测试数据的执行而是对测试对象的分析过程。 

    静态测试存在于软件生命周期的各级测试。如:需求分析、概要设计、详细设计及组件测试、集成测试和系统测试的阶段或层级。 

    静态测试的方法主要有人工(手工)评审与静态分析(人工或机器自动检测)两大类。通常可分别采用一种方法或混合使用两种方法。 

    静态测试中的评审(或审查)的基本思想和目标是对软件缺陷或错误的一种预防措施。因而软件技术文档的审查是静态测试的主要任务之一。

    静态测试的技术方法构成和说明:

     

    针对需求分析和概要设计进行的评审。评审在需求分析和概要分析阶段 建立的评审基础上开展,有人工评审和静态技术分析两个过程。 

    人工评审分为正式评审和非正式评审。正式评审是执行对被测对象(文档或程序)检查的活动及过程(也称为技术评审);非正式评审主要采用对文档或程序的走查活动及过程。如,对某一个具体程序的走查。走查通常采用单独或集体审阅的方式进行。

    静态测试内容及过程

    (1)静态测试内容 

    静态测试的内容包含:测试需求分析、测试概要分析、测试详细设计、测试执行与测试结果分析 

    (2)静态测试过程 

    进行测试需求分析:这是静态测试过程的首个阶段,将确定测试的需求,建立起测试基础与评审基础。 

    进行测试概要设计:在测试需求分析基础上,完成对测试方案的制定。如,测试内容、测试目标、测试策略、测试方法等。 

    进行测试详细设计:这个阶段主要完成测试进程中,各项具体任务安排和实施的细节考虑。如,测试用例设计等。 

    测试执行与结果分析:根据静态测试的计划进行静态测试执行的过程,各项测试任务的完成,并提交测试工作交付物。 

    静态测试的实施与执行 

    (1) 静态测试的实施 

    静态测试通常采用两种策略:人工静态分析和借用工具静态分析。 

    人工静态分析发挥人的智力和具有的逻辑思维优势,在分析过程中也常借助专用的静态测试分析工具来辅助。目前,实际工作中基本都是采用两种方法的混合模式,既充分发挥了发挥人的智慧,又运用了机器(工具)分析的高效便捷。

    (2) 静态分析的过程有别于编译过程 

    编译的功能是不能替代测试的。虽然编译系统也能检查软件(程序)中的错误,但其主要的作用是检查程序的语法等错误。这是因为编译系统并不具备软件测试的功能,并无针对性的去寻找特定的软件测试对象中的缺陷、错误的功效。

    而测试通常是要通过执行测试用例来实现的。同时,编译是无法检测到程序的逻辑错误或缺陷的。 

    (3) 代码检查 

    代码检查的内容主要包括:代码走查、桌面检查、代码审查等活动及过程。主要检查代码和设计的一致性,代码对标的遵循、可读性,代码的逻辑表达的正确性,代码结果的合理性等方面。

    代码检查的具体内容:变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等。

    代码检查的优点:是能快速找到软件缺陷或错误。测试业界实践表明,通过代码(通常是源代码)的走查过程,可检查到程序中 30-70%的程序逻辑设计及编码中的缺陷或者错误。代码检查在实际软件开发过程中被普遍采用,特别是针对组件(即单元)测试。

    代码检查的缺点:非常耗费时间,而且代码检查需要知识和经验的积累。 

    一般代码审查以下方面:

    1、 代码是否与设计一致,是否符合软件需求、概要和详细设计,这不仅可以看出代码问题,也可以反过来更早发现需求或设计是否正确。

    2、 代码书写的规范性和可读性。每个项目都有代码编写规范,如Java编写规范,C语言编写规范等。规范的代码包括清晰且充分的注释、漂亮的对齐、没有冗余、规范的命名等等。

    3、 代码逻辑是否正确,有没有死循环、内存泄露,异常处理是否充分,事务处理是否正确等等。

    4、 代码是否有安全漏洞、易被攻击。

    5、 代码文件组织目录是否合理,代码的结构是否合理

    6、 代码的重用性或复用性是高还是低

    7、 代码嵌套调用是否过多等等

    静态测试的结构分析方法 

    (1)以图形方式表现程序内部结构 

    静态结构分析主要以图形的方式来表达程序内部的结构关系。如,函数调用关系图,函数内部控制流图等。函数调用关系图是以直观的图形方式描述一个程序中各个函数的调用和被调用的关系; 函数内部控制流图以有向图来表达函数内部的程序控制逻辑。 

    (2) 以程序的控制流图显示程序函数的逻辑结构 

    程序的控制流图由多个节点和连接的边所构成。一个节点代表一条语句或数条语句,连接结点叫作边,边表示节点之间的控制流向。 

     

    (3)检查项 

    静态测试的检查项,主要有:代码风格和规则的审核;程序设计和结构的审核;业务逻辑的审核。 

    (4) 代码的质量度量 

    针对软件的可测试性、可读性(可维护性),通常有 3 种不同的代码质量度量 

    参数。 

     Line(行)复杂度。Line 复杂度是以代码的行数作为计算度量的基准。

     Halstead(运算符与运算元)复杂度。Halstead 复杂度是以程序中使用到的运算符与运算元数量作为计数目标(直测指标),据此来计算程序的容量和工作量。 

     McCabe(圈)复杂度。它是将程序流程图结构转化为有向图结构,以图形(有向图)为基础来衡量软件或程序的复杂度度量。 

    代码质量度量常常通过静态测试来获得,所以静态测试方法也称为静态分析,静态测试是对被测程序进行质量特性分析方法的总称。 

    (5)检查与规范、标准的一致性 

    通过静态测试工具可检查测试对象是否与应用的程序规范、标准的相一致,以检查软件程序是否遵循了大部分的编程规则与标准规范。以工具检查的优势是可快速并准确的帮助开发者与测试人员进行自动化检测过程,以发现被测对象与规范、标准的一致性。 

    2.动态测试(Dynamic testing)

    动态测试是指通过运行被测程序,输入相应的测试数据,检查实际输出结果与预期结果的差异,并分析运行效率、正确性、健壮性、性能等。

    (1)动态测试有三部分组成:构造测试用例、执行程序、分析程序的输出结果。

    (2)大多数软件测试都属于动态测试。所谓软件的动态测试,就是通过运行软件来检验软件的动态行为和运行结果的正确性。目前,动态测试也是公司的测试工作的主要方式。

    是否查看代码角度和是否执行程序角度的关系

    黑盒测试有可能是动态测试(运行程序,只看输入和输出),也有可能是静态测试(不运行程序,只是查看界面)

    白盒测试有可能是动态测试(运行程序,并分析代码结构),也有可能是静态测试(不运行程序,只是静态查看代码)

    动态测试有可能是黑盒测试(运行程序,只看输入和输出),也有可能是白盒测试(运行程序,并分析代码结构)

    静态测试有可能是黑盒测试(不运行程序,只是查看界面),也有可能是白盒测试(不运行程序,只是静态查看代码)

    按测试对象的角度划分

    性能测试

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

    中国软件评测中心将性能测试概括为三个方面:应用在客户端性能的测试、应用在网络上性能的测试和应用在服务器端性能的测试。通常情况下,三方面有效、合理的结合,可以达到对系统性能全面的分析和瓶颈的预测。

    定义

    狭义的性能测试主要用于描述常规的性能测试,是指通过模拟生产运行的业务压力或用户使用场景来测试系统的性能是否满足生产性能的要求。
    广义的性能测试则是压力测试、负载测试、强度测试、并发(用户)测试、大数据量测试、配置测试、可靠性测试等和性能相关的测试统称。

    基本策略

    测试的基本策略是自动负载测试,通过在一台或几台PC机上模拟成百或上千的虚拟用户同时执行业务的情景,对应用程序进行测试,同时记录下每一事务处理的时间、中间件服务器峰值数据、数据库状态等。通过可重复的、真实的测试能够彻底地度量应用的可扩展性和性能,确定问题所在以及优化系统性能。预先知道了系统的承受力,就为最终用户规划整个运行环境的配置提供了有力的依据。

    目的

    目的是验证软件系统是否能够达到用户提出的性能指标,同时发现软件系统中存在的性能瓶颈,以优化软件,最后起到优化系统的目的。

    包括以下几个方面:

    1.评估系统的能力,测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策。

    2.识别体系中的弱点:受控的负荷可以被增加到一个极端的水平,并突破它,从而修复体系的瓶颈或薄弱的地方。

    3.系统调优:重复运行测试,验证调整系统的活动得到了预期的结果,从而改进性能。

    4. 检测软件中的问题:长时间的测试执行可导致程序发生由于内存泄露引起的失败,揭示程序中的隐含的问题或冲突。

    5.验证稳定性(resilience)、可靠性(reliability):在一个生产负荷下执行测试一定的时间是评估系统稳定性和可靠性是否满足要求的唯一方法。

    类型

    性能测试类型包括负载测试,压力测试,容量测试,稳定性测试等。

     

    负载测试(Load Testing)

    定义

    负载测试是一种主要为了测试软件系统是否达到需求文档设计的目标,譬如软件在一定时期内,最大支持多少并发用户数,软件请求出错率等,测试的主要是软件系统的性能。

    负载测试是不断增加系统的负载,直到负载达到阈值——评估系统在预期工作负载下的性能的测试。这里增加负载的意思是在测试中增加并发用户数量、用户交互等,通常是在可控的环境下进行。典型的负载测试包括在负载测试过程中确定响应时间,吞吐量,误码率等。该方法可以找到系统的性能极限,可以为性能调优提供相关数据。该类方法通常要基于或模拟系统真实运行环境,且选取的业务场景也要尽可能地与实际情况相符。

    狭义的定义:是指对系统不断地增加压力或增加一定压力下的持续时间,直到系统的某项或多项性能指标达到安全临界值,例如某种资源已经达到饱和状态等。运用场景:此类型的测试目前运用得比较少。一般情况下,是以服务器资源安全临界值为界限的测试。如果要模拟某个应用在指定服务器上最大且安全的负载量,则属于负载测试。

    目标

    确定并确保系统在超出最大预期工作量的情况下仍能正常运行。此外,负载测试还要评估性能特征。例如,响应时间、事务处理速率和其他与时间相关的方面。

    负载测试的目标是测试在一定负载情况下系统性能(不关注稳定性,也就是说不关注长时间运行,只是得到不同负载下相关性能指标即可);实际中我们常从比较小的负载开始,逐渐增加模拟用户的数量(增加负载), 观察不同负载下应用程序响应时间、所耗资源,直到超时或关键资源耗尽,这就是所说的负载测试,它是测试系统的不同负载情况下的性能指标。

    目的

    负载测试是为了发现系统的性能问题,负载测试需要通过系统性能特性或行为来发现问题,从而为性能改进提供帮助,从这个意义看,负载测试可以看作性能测试的一部分。但它们两者的目的是不一样的,负载测试是为了发现缺陷,而性能测试是为了获取性能指标。因为性能测试过程中,也可以不调整负载,而是在同样负载情况下改变系统的结构、改变算法、改变硬件配置等等来得到性能指标数据,从这个意义看,负载测试可以看作是性能测试所用的一种技术,即性能测试使用负载测试的技术、使用负载测试的工具。性能测试要获得在不同的负载情况下的性能指标数据。

    通过负载测试和压力测试都可以获得系统正常工作时的极限负载或最大容量。容量测试,自然也是采用负载测试技术来实现,而在破坏性的压力测试中,容量的确可以看作是一种副产品——间接结果。

    负载测试的必要准备

    1.什么是你真正需要了解的?

    2.确定用户数量

    3.研究你的分析

    4.组建你的团队

    5.准备你的浏览器

    6.准备测试你的应用

    7.预留时间分析结果

    8.预留时间修改

    9.计划一个敏捷测试方法

    压力测试(Stress Testing)

    定义

    压力测试是在强负载(大数据量、大量并发用户等)下的测试,查看应用系统在峰值使用情况下操作行为,从而有效地发现系统的某项功能隐患、系统是否具有良好的容错能力和可恢复能力。压力测试分为高负载下的长时间(如24小时以上)的稳定性压力测试和极限负载情况下导致系统崩溃的破坏性压力测试。

    压力测试可以被看作是负载测试的一种,即高负载下的负载测试,或者说压力测试采用负载测试技术。通过压力测试,可以更快地发现内存泄漏问题,还可以更快地发现影响系统稳定性的问题。例如,在正常负载情况下,某些功能不能正常使用或系统出错的概率比较低,可能一个月只出现一次,但在高负载(压力测试)下,可能一天就出现,从而发现有缺陷的功能或其它系统问题。通过负载测试,可以证明这一点,某个电子商务网站的订单提交功能,在10个并发用户时错误率是零,在50个并发用户时错误率是1%,而在200个并发用户时错误率是20%。

    狭义的定义:压力测试是指超过安全负载的情况下,对系统不断施加压力,是通过确定一个系统的瓶颈或不能接收用户请求的性能点,来获得系统能提供的最大服务级别的测试。运用场景:此类型的测试目前运用得比较少。但对于大型的共享中心或者核心的应用也会用到。

    目标

    压力测试的目标是测试在一定的负载下系统长时间运行的稳定性,尤其关注大业务量情况下长时间运行系统性能的变化(例如是否反应变慢、是否会内存泄漏导致系统逐渐崩溃、是否能恢复);压力测试是测试系统的限制和故障恢复能力,它包括两种情况:
    稳定性压力测试:在选定的压力值下,长时间持续运行。通过这类压力测试,可以考察各项性能指标是否在指定范围内,有无内存泄漏、有无功能性故障等;
    破坏性压力测试:在稳定性压力测试中可能会出现一些问题,如系统性能明显降低,但很难暴露出其真实的原因。通过破坏性不断加压的手段,往往能快速造成系统的崩溃或让问题明显的暴露出来。

    目的

    压力测试主要是为了发现在一(任意)定条件下软件系统的性能的变化情况,通过改变应用程序的输入以对应用程序施加越来越大的负载(并发,循环操作,多用户) 并测量在这些不同的输入时性能的改变,也就是通常说的概念:压力测试考察当前软硬件环境下系统所能承受的最大负荷并帮助找出系统瓶颈所在。其实这种测试也 可以称为负载测试,但是负载测试通常描述一种特定类型的压力测试——增加用户数量以对应用程序进行压力测试。比如实际中我们说从比较小的负载开始,逐渐增加模拟用户的数量, 直到应用程序响应时间超时,就是说的负载测试。

    压力测试主要是为了测试硬件系统是否达到需求文档设计的性能目标,譬如在一定时期内,系统的cpu利用率,内存使用率,磁盘I/O吞吐率,网络吞吐量等,压力测试和负载测试最大的差别在于测试目的不同。压力测试是指当硬件资源如cpu、内存、磁盘空间等不充足时对软件稳定性的检查。压力测试属于负面测试(Negative testing),使大量并发用户/进程加载软件以使系统硬件资源不能应付,这个测试也被称为是疲劳测试(Fatigue testing),通过超出其能力的测试来捕获应用程序的稳定性。压力测试的主要思想是确定系统故障,关注系统如何优雅地恢复正常,这种质量被称为是可恢复性。

    负面测试(Negative testing)是相对于正面测试(Positive testing)而言的。正面测试就是测试系统是否完成了它应该完成的功能;而负面测试就是测试系统是否不执行它不应该完成的操作。

    配置测试

    同功能测试一样,如果需求规格说明中有明确的性能需求,例如完成复杂运算处理的解算时间要求,解算精度要求,网络传输吞吐量,数据库的最大容量,服务器能允许的同时在线访问数量等等,都要反映在配置项测试里。如果没有明确指出性能要求,测试人员可根据软件产品所处行业,自行产生测试需求。——这很考验测试人员的素质和水平的哦。例如前面所提到的,服务器能允许的最大同时在线访问量,就是互联网行业的一个性能需求。当然,还有常规的空间性能(存储和占用计算机硬件资源)和时间性能(软件处理一个任务所用时间),如今的计算机资源,基本都满足要求,除非你是航空发射,武器控制等特殊行业,才需要非常关注

    配置测试主要指通过测试找到系统各项资源的最优分配原则。配置测试是系统调优的重要依据。例如,可以通过不停地调整 Oracle 的内存参数来进行测试,使之达到一个较好的性能。可以看出,配置测试本质上是前面提到的某些种类的性能测试组合在一起而进行的测试。

     

    并发测试

    定义

       所谓并发,它的特点是“并行”和“同时”。

       测试多个用户同时访问同一个应用、同一个模块或者数据记录时是否存在死锁或者其他性能问题,几乎所有的性能测试都会涉及一些并发测试。通常的测试方法是设置集合点。

    目的

    测试目的并非为了获得性能指标,而是为了发现并发引起的问题。

    并发概念的浅谈

    想确定用户并发数;必须知道系统所承载的在线用户数;

    对于并发,我过去接触了几种理解,在接触的第一种理解中,“并发”是由loadrunner中获取,即脚本中所有或部分vuser执行至集合点函数时进行停留,等待触发条件发生以后,同时执行集合点函数后的请求操作的这一个过程,为“并发”(这一个请求操作一般存在多个http请求),可惜这种“并发”是无法直接用于衡量系统性能的。

    LoadRuner的并发很好理解,就是虚拟用户数。因为LR有个集合点,可以在所有虚拟用户初始化且到达集合点后,再一起执行后续操作,从而达到同时且并行的效果。

    而在接触的第二种理解中,“并发”的理解是相对于服务器某一个时间区间内接收的请求数,也就是每秒的点击率(loadrunner考虑到这点,也就是analysis里面的hits/s),为“并发”,这种“并发”是可以用于对系统性能状况进行量化的,但是这种测试思想只是比较片面的从性能指标的角度去衡量系统性能,不能体现出系统性能带给用户何种性能体验(这也是不少开源性能测试工具的问题)。

    前一种“并发”的理解普遍获得了loadrunner初级用户的认可,后一种“并发”的理解普遍获得系统运维、开发人员的认可,在沟通中为了方便区别开来,在两种角色里面,当大家意识到并发的理解存在差异时,大家把前一种被称为“狭义上的并发”,而后一种被称为“广义上的并发”。后来,又从淘宝团队里面了解了一种定义,貌似淘宝QA把“并发”定义为一个完整的事务请求数量过程(loadrunner也考虑到这点,也就是analysis里面的Transactions per Second)。一直以来,还有一种技术范围以外对“并发”的粗略的理解被第三方测试拿来用了,那就是用户在线数中的某个百分比即并发数。

    如果一个团队里面对“并发”的理解有这么多种,那么当我们在讨论性能需求的“支持并发数”时,我们究竟在讨论什么呢?

    个人认为,有一部分的原因是由于loadrunner是惠普saas(软件即服务的解决方案)的一部分,所以并不是一个纯粹技术人员使用的测试工具,它同时也是一个业务人员可以相对轻易掌握的性能测试工具,因此loadrunner内很多名词解释也不能单纯从技术人员的角度从字面意义上理解。

    通常来说,面对同样100笔业务交易量,普遍会认为100vuser对服务器产生的负载会比50vuser要高,但是在性能脚本能够在较快的响应时间中完成时,由于50vuser执行过程中每一个vuser都需要发生两次迭代,导致了性能场景中vuser在脚本action部分停留的时间更长,因此反而能够得到比100vuser的更高的vuser在线数,更高在线数带来的也就是更大的负载,也就是说:

    同等业务量的情况下,50线程所产生的负载完全有可能比100线程所产生的负载要高。

    为了避免发生这种问题,“并发(集合点)”的真正作用就体现出来了,通过集合点函数控制了vuser的行为相对一致,降低了初始化过程和事务前后文请求产生的时间差影响。测试工具中并发存在的真正意义也就在这里,对集合点所理解的“并发”,和现场实际用户里面同时触发的请求关系不是太大。

    分析并发需求时的一些典型:

    a)     某个业务系统里面有10000用户,但是能够访问这个系统的终端数只有1000个、或者所需测试的业务每个月上限是1000笔,那么最高在线用户数就不可能超过1000、业务量也不可能超过1000。所以,有些时候在分析性能需求的时候,去统计一个业务系统的用户数还不如去统计能够访问这个系统的终端数、甚至业务量靠谱。

    b)     某个业务系统里面,各个业务模块都不一样,那么就是说完成一笔业务交易,所产生的请求数也是不一样的,例如表单新增,有的需要填写20个字段,有的只需要填写5个字段,各个表单都不一样,那么为了更接近的去模拟用户现场负载,请求数都不一样的各种业务混在一起,并发数又应该是多少呢?

    为了解决这些问题,需要首先考虑并发的粒度,以真实的业务场景为例:

    a)     把粒度控制在用户上来看,假定所有用户访问一次系统平均耗时500秒,一个业务峰值会有800用户在线,则800/500=1.6。理论上,系统的性能需求是每秒要成功处理1.6个用户的请求;

    b)     把粒度控制在事务上来看,假定所有用户执行一次完整的、成功的业务操作平均需要500秒,一个业务峰值有2000笔所关注的业务需要去执行,则2000/500=4。理论上,系统的性能需求是每秒要成功处理4笔业务交易;

    c)      把粒度控制在请求上来看,假定所有用户执行一次完整的、不管成功或者失败的HTTP请求操作平均需要0.08秒,一个业务峰值有28000个请求需要去完成,则28000/0.08=350000。理论上,系统的性能需求是每秒要成功处理350000个请求。

    分类

    1、独立业务性能测试:核心业务模块的某一业务并发性能测试; 

    2、组合业务性能测试:一个或多个模块的多个业务同时进行并发测试。

     

    独立业务性能测试

    1、完全一样功能的并发测试:检查程序对同一时刻并发操作的处理,例如模拟多个用户在

    同一时刻向数据库写入相同数据,或者多个用户在同一时刻发出请求测试系统能否正确响应。

    2、完全一样操作的并发测试:在同一时刻完成完全一样的操作,即从宏观上看操作对系统

    的影响是一致的,例如同时单击保存按钮。这类测试目的在于验证大量用户使用同一功能时系统能否正常工作。

    3、相同/不同的子功能并发测试:同一模块大多数功能相互耦合,针对一些子功能较多的

    模块做组合测试。组合的依据就是用户使用的场景,每个不同的子功能都模拟一定的用户数量进行并发测试。

    组合业务性能测试

    1、不同核心业务模块的用户进行并发,模块之间具有一定耦合:这种测试比较接近用户使

    用情况,测试的对象是多个模块组,每个组相关的模块之间具有一定耦合关系。组与组之间的关系相对独立。例如实际中各类型的用户都会对应一组模块,相当于不同的业务组并发的访问系统。

    2、具有耦合关系的核心模块组进行并发,每组模块内部存在耦合关系:主要测试多用户并发条件下一些存在耦合或者数据接口的模块是否正常运行,可以参考集成测试用例和概要设计文档,分析出一些核心模块的接口。

    3、基于用户场景的并发测试:选择用户的一些经典场景做测试,测试对象可以使核心模块,也可以是非核心模块。这种测试更接近用户使用的实际情况,测试需要充分考虑实际场景。设计组合模块用户并发性测试用例一般用不同“子功能”或者“子事务”为单位,来进行各种模块的不同核心功能组合。

    并发用户数量设计方法

     

    容量测试(Volume Testing)

    定义

        所谓容量,即系统处于最大负载状态或某项指标达到所能接受的最大阈值下对请求的最大处理能力。

    容量测试是一种非功能的测试,它通过向应用程序中添加大量的数据来实现检查被测系统处理大数据量的能力。

    可以通过向数据库插入大量的数据或让应用程序处理一个大型文件来进行测试应用程序。通过容量测试,可以识别应用程序中具有大数据时的瓶颈,检查应用程序的效率,进而得到不同数据量级下应用程序的性能。确定系统最大承受量,譬如系统最大用户数,最大存储量,最多处理的数据流量等。

     

    举例:
    在一个新开发的网络游戏应用程序中,在进行容量测试时,可以通过向数据库中插入数百万行的数据,然后在这些数据的基础上进行性能的测试。
    注意,这里所说的数据一定是符合其功能场景的,不是毫无关系的数据。

    目的

    容量测试的目的是通过测试预先分析出反映软件系统应用特征的某项指标的极限值(如最大并发用户数、数据库记录数等),系统在其极限状态下没有出现任何软件故障或还能保持主要功能正常运行。容量测试还将确定测试对象在给定时间内能够持续处理的最大负载或工作量。软件容量的测试能让软件开发商或用户了解该软件系统的承载能力或提供服务的能力,如某个电子商务网站所能承受的、同时进行交易或结算的在线用户数。知道了系统的实际容量,如是不能满足设计要求,就应该寻求新的技术解决方案,以提高系统的容量。有了对软件负载的准确预测,不仅能对软件系统在实际使用中的性能状况充满信心,同时也可以帮助用户经济地规划应用系统,优化系统的部署。

    如何统计容量指标?

    统计维度

    一般来说,可以从如下两个维度来定量系统的容量:

     

    统计方法

    一般来说,常用的采集数据的方法,有以下几种方式:

    ①、埋点采集:即在系统的各个节点,根据需要添加埋点,针对性的进行数据采集;

    ②、日志/数据库:通过日志服务(比如ELK)或者运维监控(现在很流行的Devops),采集分析数据;

    ③、Agent/探针:在需要采集的节点添加Agent/探针,实时采集,数据存入时序数据库(比如influxdb),实时展示;

    注意事项

    ①、采集对比的数据一定要采集线上的真实数据,这样才能反映真实客观的系统压力。

    ②、容量测试环境的配置,一定要和线上保持一致(服务器数量可以不同,但配置尽可能保持一致)。

    测试思路

    ①、根据具体的业务情况和系统架构,通过配置测试的手段,测量得到单个服务节点在对应的业务场景下最大的性能表现;

    ②、根据系统架构(集群、分布式、微服务)特点,通过启用≥2的服务节点,来得到服务节点的增加和系统性能的提升比例;

    ③、通过线上采集的系统数据,分析出过去某段时间(或某个业务)的高峰流量,然后通过计算,得到容量扩容,需要投入的实际服务数量;

    约束/停止条件

    在测试过程中,只要限定的某项指标达到最大可接受阈值或某项资源达到最大使用状态,即刻停止测试。

    选择合适的容量指标

    考虑到业务需求和系统架构的不同,在选取容量指标时一般遵循如下原则:

    ①、数据密集型:即并发请求量较大的类型,一般TPS和RT是比较关注的指标;

    ②、数据存储型:即需要存储读写的数据量较大的类型,一般吞吐量和IO是比较关注的指标;

    容量规划

    为什么需要容量规划?

    对于业务越来越复杂的商业形态,每个业务都由一系列不同的系统来提供服务,每个业务系统都部署在不同的机器上。容量规划的目的在于让每一个业务系统能够清晰地知道:

    ①、什么时候应该增加服务节点,什么时候应该减少服务节点(比如服务端接受到的流量达到什么量级)?(比如双十一,大促,秒杀)

    ②、为了双 11 、促销、秒杀、渠道拓展引流等业务需求,需要扩充到什么数量级的服务,才能即保证系统的可用性、稳定性,又能节约成本?

    容量规划四步走

    ①、业务流量预估阶段:通过分析历史数据以及实时的线上监控,预估未来某个时间点或者某个业务可能会有多少多少的流量冲击;

    ②、系统容量评估阶段:根据具体的业务场景,分析每个业务场景的流量配比,然后计算每个业务大概需要多少服务节点来提供可靠稳定的性能支撑;

    ③、系统容量测试阶段:通过全链路压测或者PAT/UAT环境的压测,来模拟真实的业务场景,确定每个服务节点的具体性能表现,进行针对性的调整;

    ④、流量分配调整阶段:根据压测的结果,设定限流、服务降级等系统保护措施,来预防当实际流量超过系统所能承受的最大流量时,系统无法提供服务;

    扩容手段

    ①、垂直扩容

    升级服务的硬件配置,让单个服务节点的容量更大,来提供更高的系统服务能力。比如:

    加大服务机器的CPU数量和内存,更换性能更好的高速缓存服务器,数据存储用NAS盘替换等。

    ②、水平扩展

    即增加服务节点的数量,让可提供服务的服务变得更多,来提升系统总体的服务能力。常见的方式有:

    服务集群:服务器的数量由1→N(但需要重点关注负载均衡);

    分布式:提供服务的节点由统一集中管理部署,分散到不同的地点;

    容器:提供更灵活的弹性扩容机制,根据具体的访问流量大小来弹性扩容或者缩容;

    容量测试的优点

    以下是任何软件应用程序的容量或洪水测试的优点。

    • 它提供了运行软件应用程序所需的硬件类型的清晰图像,包括CPU、内存等。
    • 可以很早地确定可扩展性计划。
    • 它有助于节省可能用于应急计划的大量资金。
    • 它有助于尽早发现应用程序操作中的瓶颈。
    • 它确保了经过容量测试的应用程序已准备好投入实际使用。
    • 它有助于让应用程序上线或不上线。

    容量测试的缺点

    此类测试增加了项目的额外成本,因为它是由不同的性能测试团队在功能测试的基础上完成的。

    为什么经常推荐容量测试?

    由于以下原因,通常建议进行容量测试。

    • 当到数据库中的数据量增加时,它有助于检查系统性能。
    • 使用大量数据研究软件应用程序行为。
    • 评估应用程序稳定性开始降低的点。
    • 它可以识别正常,低,中,高容量下的应用能力。

    容量测试检查

    在容量或洪水测试期间评估和检查以下参数。

    • 容量测试旨在检查是否有任何数据丢失。
    • 进行容量测试以记录不同容量条件下的响应时间并评估平均响应时间。
    • 它旨在评估数据库中的数据是否正确保存。
    • 它旨在验证数据是否被任何通知覆盖。
    • 它旨在检查警告和错误消息,以及它们在不同容量级别的关联。
    • 它旨在检查高数据量是否会以任何方式影响被测系统中处理请求的速度。

    容量测试最佳实践

    以下是最佳容量测试结果广泛遵循的最佳实践。

    • 在检查所有日志 (即服务器和应用程序的日志) 时, 不要忘记停止所有服务器。
    • 在开始容量测试之前,确保正面(正常)场景正常工作。
    • 为了从容量测试中获得最佳结果,始终建议错开用户数量。
    • 平衡你的容量试时间以克服许可限制。
    • 引入的任何新版本都应该非常谨慎地处理。
    • 建立基线后,应分析用例以提高性能。
    • 在出现性能瓶颈的情况下,应该反复重复进行容量测试,以深入研究性能问题。
    可靠性测试

    定义

    软件可靠性测试是指为了保证和验证软件的可靠性要求而对软件进行的测试。其采用的是按照软件运行剖面(对软件实际使用情况的统计规律的描述)对软件进行随机测试的测试方法。

    软件可靠性是软件系统在规定的时间内以及规定的环境条件下,完成规定功能的能力。一般情况下,只能通过对软件系统进行测试来度量其可靠性。

    对软件可靠性进行定量的评估或验证,为了达到和验证软件的可靠性定量要求而对软件进行的测试。

    软件可靠性测试通常是在系统测试、验收、交付阶段进行,它主要是在实验室内仿真环境下进行,也可以根据需要和可能在用户现场进行。

    在给系统加载一定业务压力的情况下,使系统运行一段时间,以此检测系统是否稳定。例如,可以施加让 CPU 资源保持 70%~90%使用率的压力,连续对系统加压 8 个小时,然后根据结果分析系统是否稳定。这么多类型的性能测试看起来很吓人,实际上它们大多是密切相关的。例如,运行 8 个小时来测试系统是否可靠,而这个测试极有可能包含了可靠性测试、强度测试、并发(用户)测试、负载测试,等等。

    特点

     

    测试的目的

    (1)通过在有使用代表性的环境中执行软件,以证实软件需求是否正确实现。

    (2)为进行软件可靠性估计采集准确的数据,预测软件在实际运行中的可靠性。

    估计软件可靠性一般可分为四个步骤,即数据采集、模型选择、模型拟合以及软件可靠性评估。可以认为,数据采集是整个软件可靠性估计工作的基础,数据的准确与否关系到软件可靠性评估的准确度。

    (3)通过软件可靠性测试找出所有对软件可靠性影响较大的错误。

    (4)通过测试可以提高整个软件系统的防错、容错和纠错的能力。

    通过软件可靠性测试可以达到以下目的:

    (1) 有效地发现程序中影响软件可靠性的缺陷,从而实现可靠性增长:软件可靠性是指“在规定的时间内,规定的条件下,软件不引起系统失效的能力,其概率度量称为软件可靠度。”

    软件的“规定的条件”主要包括相对不变的条件和相对变化的条件,相对不变的条件如计算机及其操作系统;相对变化的条件是指输入的分布,用软件的运行剖面来描述。认为按照软件的运行剖面对软件进行测试一般先暴露在使用中发生概率高的缺陷,然后是发生概率低的缺陷。而高发生概率的缺陷是影响产品可靠性的主要缺陷,通过排除这些缺陷可以有效地实现软件可靠性的增长。

    (2) 验证软件可靠性满足一定的要求:通过对软件可靠性测试中观测到的失效情况进行分析,可以验证软件可靠性的定量要求是否得到满足。

    (3) 估计、预计软件可靠性水平

    通过对软件可靠性测试中观测到的失效数据进行分析,可以评估当前软件可靠性的水平,预测未来可能达到的水平,从而为开发管理提供决策依据。软件可靠性测试中暴露的缺陷既可以是影响功能需求的缺陷也可以是影响性能需求的缺陷。软件可靠性测试方法从概念上讲是一种黑盒测试方法,因为它是面向需求、面向使用的测试,它不需要了解程序的结构以及如何实现等问题。

    分析方法

    目前主要的软件可靠性分析方法有失效模式影响分析法、严酷性分析法、故障树分析法、事件树分析法、潜在线路分析法。

    测试过程

    包括五个步骤:确定可靠性目标,定义软件运行剖面,设计测试用例,实施可靠性测试,分析测试结果。

    失败恢复性测试

      对于有冗余备份和负载均衡的系统,通过这样的测试来检验如果系统局部发生故障用户是否能够继续使用系统,用户收到多大的影响。

     

    强度测试

    强度测试是一种性能测试,它在系统资源特别低的情况下软件系统运行情况,目的是找到系统在哪里失效以及如何失效的地方。 

    强度测试主要是为了检查程序对异常情况的抵抗能力。强度测试总是迫使系统在异常的资源配置下运行。例如:
      当正常的用户点击率为“1000 次/秒”时,运行点击率为“2000 次/秒”的测试用例;
      运行需要最大存储空间(或其他资源)的测试用例;
      运行可能导致操作系统崩溃或磁盘数据剧烈抖动的测试用例,等等。
    强度测试是一种特别重要的测试,对测试系统的稳定性,以及系统未来的扩展空间均具有重要的意义。在这种异常条件下进行的测试,更容易发现系统是否稳定以及性能方面是否
    容易扩展。

    疲劳测试

    疲劳测试是采用系统稳定运行情况下能够支持的最大并发用户数,持续执行一段时间业务,通过综合分析交易执行指标和资源监控指标来确定系统处理最大工作量强度性能的过程。是一类特殊的强度测试,主要测试系统长时间运行后的性能表现,例如 7× 24 小时的压力测试。

    尖峰测试(Spike testing)

    尖峰测试(Spike testing)其实可以算作是压力测试(Stress Testing)的子集。

    尖峰测试是在目标系统经受短时间内反复增加工作负载,以至超出预期生产操作的负载量时,分析系统的行为,验证其性能特征。它还包括检查应用程序是否可以从突然增加的超预期负荷中恢复出来的测试。
    举例:在电商应用程序中经常有“整点秒杀”的活动,所以在整点时间前后的两三分钟时间里,会有巨大数量的用户进入到该活动中秒杀商品。尖峰测试就是为了分析这类场景。

    持久测试(Endurance testing)

    持久测试(Endurance testing),也被称为是浸泡测试(Soak Testing),它也是一种非功能的测试。
    持久测试是指在相当长的时间内使用预期的负载量对系统进行测试,以检查系统的各种行为,如内存泄露、系统错误、随机行为等。
    这里的提到的相当长的时间是相对而言的,举例来说,如果一个系统设计为运行3个小时的时间,那可以使用6个小时的时间来进行持久测试;如果设计为5个小时的时间,不妨用10个小时的时间来进行持久测试。对于现在的许多网络类应用程序,通常情况下会持续运行好多天,那么进行持久测试时可以选择更长的时间段。

    稳定性测试

    狭义的定义:稳定性测试是指被测试系统在特定硬件、软件、网络环境条件下,给系统加载一定业务压力,使系统运行一段较长时间,以此检测系统是否稳定,一般稳定性测试时间为 n*12 小时。

    运用场景:此类型的测试目前也最常见,针对需要长时间稳定运行的性能点,需要执行稳定性测试。往往在一个项目的性能测试过程中,会划分出优先级较高的性能点,做稳定性测试。例如:宝贝详情页面等等。

    如何实施

    识别并确认软件主要业务(是否需要稳定性测试)

    将稳定性测试的重心放在软件最有Value的地方,比如说一个抢票系统,它最有value的地方是当有一定数量的用户同时进行买票操作是系统的响应时间,资源利用率等是否能够正常且稳定,而不是用户如何添加新的联系人,修改个人信息等。

    罗列主要用户场景及响应负载量

    用户场景可以根据软件主要业务进行设定

    对主要场景负载量需要有一个清晰的定义(或者通过负载测试验证了用户场景的负载量,这将作为一个标准的负载在稳定性测试中使用)

    制定稳定性指标模型(Modeling)

    根据用户场景建模,创建合适合理的稳定性指标模型(之后会有一个例子)

    测试环境准备(对软硬件环境的配置:配置的来源可以是客户环境模拟、需求文档规定的配置或者配置测试得出的最佳配置)

    识别稳定性的主要性能指标(KPI)

    用来描述稳定性测试关注的系统指标,比如响应时间、CPU、内存使用率等等,需要根据具体业务进行定义  

    测试的执行和数据收集

    按照相应稳定性指标模型(Modeling)分析测试结果

    将测试结果应用在稳定性测试模型中,观察是否满足稳定性要求

    持续改进(如有必要)

    大数据量测试

    主要针对数据库有特殊要求的系统进行的测试,如电信业务系统的手机短信业务;可以分为实时大数据量,主要目的是测试用户较多或者某些业务产生较大数据量时,系统能否稳定运行;极限状态下的测试,测试系统使用一段时间即系统累计一点量的数据时能否正常的运行业务;前面两种的结合,测试系统已经累计了较大数据量时,一些实时产生较大数据量的模块能否稳定工作;

    如下大数量测试用例:
      功能:数据库中的短信息表可以保存所有不能及时发送的短信息,用户上线后又能及时发送已经保存的信息;

    大数据量测试可以分为两种类型:针对某些系统存储、传输、统计、查询等业务进行大数据量的独立数据量测试;与压力性能测试、负载性能测试、疲劳性能测试相结合的综合数据量测试方案。大数据量测试的关键是测试数据的准备,可以依靠工具准备测试数据。

    速度测试

    速度测试主要是针对关键有速度要求的业务进行手工测速度,可以在多次测试的基础上求平均值,可以和工具测得的响应时间等指标做对比分析。

    不同类型测试之间的区别

    性能测试是为了获得系统在某种特定的条件下(包括特定的负载条件下)的性能指标数据,而负载测试、压力测试是为了发现软件系统中所存在的问题,包括性能瓶颈、内存泄漏等。通过负载测试,也是为了获得系统正常工作时所能承受的最大负载,这时负载测试就成为容量测试。通过压力测试,可以知道在什么极限情况下系统会崩溃、系统是否具有自我恢复性等,但更多的是为了确定系统的稳定性。

    压力测试是测试系统什么情况下失效或者崩溃;负载测试是测试系统什么情况下超出需求指标;强度测试是测试系统在瞬时高负载、长时间负载情况下系统反应;容量测试是测试系统在大数据量交互的反应! 

    性能指标
    性能测试最基本要考虑以下几点

    1、时间特性,主要指的是软件产品的事物响应时间(用户发出请求到收到应答的这段时间)

    2、资源利用率,包括:cpu、内存、网络、硬盘、虚拟内存(如Java虚拟机)

    3、服务器可靠性,指服务器能在相对高负载情况下持续的运行

    4、可配置优化性,指服务器配置优化、业务逻辑优化、代码优化等

    检查系统是否满足需求规格说明书中规定的性能,通常表现在以下几个方面:

    1、对资源利用(包括:cpu、内存、网络、硬盘、虚拟内存(如Java虚拟机)等)进行的精确度量;

    2、对执行间隔;

    3、日志事件(如中断,报错)

    4、响应时间

    5、吞吐量(TPS)

    6、辅助存储区(例如缓冲区、工作区的大小等)

    7、处理精度等进行的监测

    在实际工作中我们经常会对两种类型软件进行测试:bs和cs,这两方面的性能指标一般需要哪些内容呢?

    bs结构程序一般会关注的通用指标如下(简):

    Web服务器指标指标:

    * Avg Rps: 平均每秒钟响应次数=总请求时间 / 秒数;

    * Avg time to last byte per terstion (mstes):平均每秒业务脚本的迭代次数,有人会把这两者混淆;

    * Successful Rounds:成功的请求;

    * Failed Rounds :失败的请求;

    * Successful Hits :成功的点击次数;

    * Failed Hits :失败的点击次数;

    * Hits Per Second :每秒点击次数;

    * Successful Hits Per Second :每秒成功的点击次数;

    * Failed Hits Per Second :每秒失败的点击次数;

    * Attempted Connections :尝试链接数;

    CS结构程序,由于一般软件后台通常为数据库,所以我们更注重数据库的测试指标:

    * User 0 Connections :用户连接数,也就是数据库的连接数量;

    * Number of deadlocks:数据库死锁;

    * Buffer Cache hit :数据库Cache的命中情况

    当然,在实际中我们还会察看多用户测试情况下的内存,CPU,系统资源调用情况。这些指标其实是引申出来性能测试中的一种:竞争测试。什么是竞争测试,软件竞争使用各种资源(数据纪录,内存等),看他与其他相关系统对资源的争夺能力。

    我们知道软件架构在实际测试中制约着测试策略和工具的选择。如何选择性能测试策略是我们在实际工作中需要了解的。一般软件可以按照系统架构分成几种类型:

    c/s

    client/Server 客户端/服务器架构

    基于客户端/服务器的三层架构

    基于客户端/服务器的分布式架构

    b/s

    基于浏览器/Web服务器的三层架构

    基于中间件应用服务器的三层架构l

    基于Web服务器和中间件的多层架构l

    性能指标的两个方面

     

    外部指标|系统指标(与用户场景和需求相关指标)

    从外部看,性能测试主要关注如下四个指标

    • 吞吐量:每秒钟系统能够处理客户的请求数、任务数,其直接体现系统的承载的能力。
    • 并发用户数:同一时刻与服务器进行数据交互的所有用户数量;
    • 响应时间:服务处理一个请求或一个任务的耗时。
    • 错误率:一批请求中结果出错的请求所占比例。

    响应时间

    从单个请求来看就是服务响应一次请求的花费的时间。但是在性能测试中,单个请求的响应时间并没有什么参考价值,通常考虑的是完成所有请求的平均响应时间及中位数时间。

     

    平均响应时间很好理解,就是完成请求花费的总时间/完成的请求总数。但是平均响应时间有一点不靠谱,因为系统的运行并不是平稳平滑的,如果某几个请求的时间超短或者超长就会导致平均数偏离很多。因此有时候我们会用中位数响应时间。

    所谓中位数的意思就是把将一组数据按大小顺序排列,处在最中间位置的一个数叫做这组数据的中位数 ,这意味着至少有50%的数据低于或高于这个中位数。当然,最为正确的统计做法是用百分比分布统计。也就是英文中的TP – Top Percentile ,TP50的意思在,50%的请求都小于某个值,TP90表示90%的请求小于某个时间。

    响应时间的指标取决于具体的服务。如智能提示一类的服务,返回的数据有效周期短(用户多输入一个字母就需要重新请求),对实时性要求比较高,响应时间的上限一般在100ms以内。而导航一类的服务,由于返回结果的使用周期比较长(整个导航过程中),响应时间的上限一般在2-5s。

    决定系统响应时间要素

    我们做项目要排计划,可以多人同时并发做多项任务,也可以一个人或者多个人串行工作,始终会有一条关键路径,这条路径就是项目的工期。

    系统一次调用的响应时间跟项目计划一样,也有一条关键路径,这个关键路径是就是系统响应时间;

    关键路径是由CPU运算、IO、外部系统响应等等组成。

    计算公式

    1、响应时间:对一个请求做出响应所需要的时间

    网络传输时间:N1+N2+N3+N4

    应用服务器处理时间:A1+A3

    数据库服务器处理时间:A2

    响应时间=网络响应时间+应用程序响应时间=(N1+N2+N3+N4)+(A1+A2+A3)

    2、平均响应时间:所有请求花费的平均时间

    系统处理事务的响应时间的平均值。事务的响应时间是从客户端提交访问请求到客户端接收到服务器响应所消耗的时间。对于系统快速响应类页面,一般响应时间为3秒左右。

    如:如果有100个请求,其中 98 个耗时为 1ms,其他两个为 100ms

    平均响应时间: (98 * 1 + 2 * 100) / 100.0 = 2.98ms,但是,2.98ms并不能反映服务器的整体效率,因为98个请求耗时才1ms,引申出百分位数

    百分位数:以响应时间为例,指的是 99% 的请求响应时间,都处在这个值以下,更能体现整体效率。

    注:(一般响应时间在3s内,用户会感觉比较满意。在3s~8s之间用户勉强能接受,大于8s用户就可能无法接受,从而刷新页面或者离开,仅供参考)

    响应时间与负载对应关系

    图中拐点说明:
    (1)响应时间突然增加
    (2)意味着系统的一种或多种资源利用达到的极限
    (3)通常可以利用拐点来进行性能测试分析与定位

    并发用户数

    一、首先涉及到并发用户数可以从以下几个方面去做数据判断。

    1.系统用户数

    2.在线用户数

    3.并发用户数

    二、三者之间的关系

    1.在线用户数的预估可以采取20%的系统用户数。例如某个系统在系统用户数有1000,则同时在线用户数据有可能达到200,或者预估200做参考。

    2.在线用户数和并发用户数又存在着关系。即:平均并发用户数为:c=NL/T L为在线时长,T为考核时长。例如:考核时长为1天,即8小时,但是用户平均在线时长为2小时,则c=n*2/8 n为登录系统的用户数,L为登录的时常。例如:一个系统有400个用户登录,然后每个用户登录大概停留2小时,则以一天8小时考核,算平均并发用户则为:c=400*2/8

    并发主要是针对服务器而言,在同一时刻与服务器进行交互(指向服务器发出请求)的在线用户数。

    (1)并发用户数:某一物理时刻同时向系统提交请求的用户数,提交的请求可能是同一个场景或功能,也可以是不同场景或功能。

    (2)在线用户数:某段时间内访问系统的用户数,这些用户并不一定同时向系统提交请求。如多个用户在浏览网页,但没有对同时对服务器进行数据请求,需要与并发用户数区分开。

    (3)系统用户数:系统注册的总用户数据

       三者之间的关系:系统用户数 >= 在线用户数 >= 并发用户数

    同时在线用户数:在一定的时间范围内,最大的同时在线用户数量。

    同时在线用户数=每秒请求数RPS(吞吐量)+并发连接数+平均用户思考时间

    平均并发用户数的计算:C=nL / T

    其中C是平均的并发用户数,n是平均每天访问用户数(login session),L是一天内用户从登录到退出的平均时间(login session的平均时间),T是考察时间长度(一天内多长时间有用户使用系统)

    并发用户数峰值计算:C^约等于C + 3*根号C  也是峰值C1,即最大并发数,计算公式C1=C+³√C

    其中C^是并发用户峰值,C是平均并发用户数,该公式遵循泊松分布理论。

    注:理解最佳并发用户数和最大并发用户数

     

    看了《LoadRunner没有告诉你的》之理发店模式,对最佳并发用户数和最大的并发用户数的理解小小整理了一下。

    所谓的理发店模式,简单地阐述一下,一个理发店有3个理发师,当同时来理发店的客户有3个的时候,那么理发师的资源能够有效地利用,这时3个用户数即为最佳的并发用户数;当理发店来了9个客户的时候,3个客户理发,而6个用户在等待,3个客户的等待时间为1个小时,另外的3个客户的等待时间为2小时,客户的最大忍受时间为3小时包括理发的1个小时,所以6个客户的等待时间都在客户的可以承受范围内,故9个客户是该理发店的最大并发用户数。

    吞吐量

    我把吞吐量定义为“单位时间内系统处理的客户请求的数量”( 吞吐量表示单位时间内能够完成的事务数量,因此也被称为每秒事务数(Transaction Per Second),计算方式是完成的事务数除以时间。),直接体现软件系统的性能承载能力,对于交互式应用系统来说、吞吐量反映的是服务器承受的压力、在容量规划的测试中、吞吐量是一个重要指标、它不但反映在中间件、数据库上、更加体现在硬件上。

    吞吐量的指标受到响应时间、服务器软硬件配置、网络状态等多方面因素影响。

    • 吞吐量越大,响应时间越长。
    • 服务器硬件配置越高,吞吐量越大。
    • 网络越差,吞吐量越小。

    在低吞吐量下的响应时间的均值、分布比较稳定,不会产生太大的波动。在高吞吐量下,响应时间会随着吞吐量的增长而增长,增长的趋势可能是线性的,也可能接近指数的。当吞吐量接近系统的峰值时,响应时间会出现激增。

    系统吞度量要素

      一个系统的吞度量(承压能力)与request对CPU的消耗、外部接口、IO等等紧密关联。单个reqeust 对CPU消耗越高,外部系统接口、IO影响速度越慢,系统吞吐能力越低,反之越高。

    系统吞吐量几个重要参数:QPS(TPS)、并发数、响应时间

    QPS(每秒请求数)(TPS (Transaction Per Second)每秒事务数):每秒钟系统处理的request/事务 数量,它是衡量系统处理能力的重要指标;

    并发数:系统同时处理的request/事务数

    响应时间:一般取平均响应时间

    理解了上面三个要素的意义之后,就能推算出它们之间的关系:QPS(TPS)= 并发数/平均响应时间

      一个系统吞吐量通常由QPS(TPS)、并发数两个因素决定,每套系统这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。

    系统吞吐量评估

    我们在做系统设计的时候就需要考虑CPU运算、IO、外部系统响应因素造成的影响以及对系统性能的初步预估。而通常境况下,我们面对需求,我们评估出来的QPS、并发数之外,还有另外一个维度:日页面流量PV。

    PV:访问一个URL,产生一个PV(Page View,页面访问量),每日每个网站的总PV量是形容一个 网站规模的重要指标。

    通过观察系统的访问日志发现,在用户量很大的情况下,各个时间周期内的同一时间段的访问流量几乎一样。只要能拿到日流量图和QPS我们就可以推算日流量。

    通常的技术方法:

    1. 找出系统的最高TPS和日PV,这两个要素有相对比较稳定的关系(除了放假、季节性因素影响之外)

    2. 通过压力测试或者经验预估,得出最高TPS,然后跟进1的关系,计算出系统最高的日吞吐量。

    无论有无思考时间(T_think),测试所得的TPS值和并发虚拟用户数(U_concurrent)、Loadrunner读取的交易响应时间(T_response)之间有以下关系(稳定运行情况下):TPS=U_concurrent / (T_response+T_think)。

    并发数、QPS、平均响应时间三者之间关系

     

     

    X轴代表并发用户数,Y轴代表资源利用率、吞吐量、响应时间。

    X轴与Y轴区域从左往右分别是轻压力区、重压力区、拐点区。

    随着并发用户数的增加,在轻压力区的响应时间变化不大,比较平缓,进入重压力区后呈现增长的趋势,最后进入拐点区后倾斜率增大,响应时间急剧增加。接着看吞吐量,随着并发用户数的增加,吞吐量增加,进入重压力区后逐步平稳,到达拐点区后急剧下降,说明系统已经达到了处理极限,有点要扛不住的感觉。

    同理,随着并发用户数的增加,资源利用率逐步上升,最后达到饱和状态。

    最后,把所有指标融合到一起来分析,随着并发用户数的增加,吞吐量与资源利用率增加,说明系统在积极处理,所以响应时间增加得并不明显,处于比较好的状态。但随着并发用户数的持续增加,压力也在持续加大,吞吐量与资源利用率都达到了饱和,随后吞吐量急剧下降,造成响应时间急剧增长。轻压力区与重压力区的交界点是系统的最佳并发用户数,因为各种资源都利用充分,响应也很快;而重压力区与拐点区的交界点就是系统的最大并发 用户数,因为超过这个点,系统性能将会急剧下降甚至崩溃。

    Light Load(较轻压力)-----最佳用户数(资源利用最高)---(较重压力,系统可以持续工作,但用户等待时间较长,满意度会下降)-----Heavy Load-------最大并发用户数--------Buckle Zone(用户无法忍受而放弃请求)

    最佳并发用户数:当系统的负载等于最佳并发用户数时,系统的整体效率最高,没有资源被浪费,用户也不需要等待
        最大并发用户数:系统的负载一直持续,有些用户在处理而有的用户在自己最大的等待时间内等待的时候

    我们需要保证的是:

    (1)最佳并发用户数需大于系统的平均负载

    (2)系统的最大并发用户数要大于系统需要承受的峰值负载

    怎么理解这两句话呢?

    (1)系统的平均负载:在特定的时间内,系统正在处理的用户数和等待处理的用户数的总和

    如果系统的平均负载大于最佳并发用户数,则用户的满意度会下降,所以我们需要保证系统的平均负载小于或者等于最佳并发用户数

    (2)峰值:指的是系统的最大能承受的用户数的极值

    只有最大并发用户数大于系统所能承受的峰值负载,才不会造成等待空间资源的浪费,导致系统的效率低下

    计算公式

    指单位时间内系统处理用户的请求数

    从业务角度看,吞吐量可以用:请求数/秒、页面数/秒、人数/天或处理业务数/小时等单位来衡量

    从网络角度看,吞吐量可以用:字节/秒来衡量

    对于交互式应用来说,吞吐量指标反映的是服务器承受的压力,他能够说明系统的负载能力

    以不同方式表达的吞吐量可以说明不同层次的问题,例如,以字节数/秒方式可以表示数要受网络基础设施、服务器架构、应用服务器制约等方面的瓶颈;已请求数/秒的方式表示主要是受应用服务器和应用代码的制约体现出的瓶颈。

    当没有遇到性能瓶颈的时候,吞吐量与虚拟用户数之间存在一定的联系,可以采用以下公式计算:F=VU * R /T

    其中F为吞吐量,VU表示虚拟用户个数,R表示每个虚拟用户发出的请求数,T表示性能测试所用的时间

     

    吞吐量与负载对应关系

    图中拐点说明:
    (1)吞吐量逐渐达到饱和
    (2)意味着系统的一种或多种资源利用达到的极限
    (3)通常可以利用拐点来进行性能测试分析与定位

    错误率

    超时错误率:主要指事务由于超时或系统内部其它错误导致失败占总事务的比率。

    错误率和服务的具体实现有关。通常情况下,由于网络超时等外部原因造成的错误比例不应超过5%%,由于服务本身导致的错误率不应超过1% 。

    内部指标|资源指标(与硬件资源消耗相关指标)

     资源利用率:资源利用率指的是对不同系统资源的使用程度,一般使用“资源实际使用/总的资源可用量”形成资源利用率。例如服务器的 CPU 利用率、磁盘利用率等。资源利用率是分析系统性能指标进而改善性能的主要依据,因此,它是 Web 性能测试工作的重点。资源利用率主要针对 Web 服务器、操作系统、数据库服务器、网络等,是测试和分析瓶颈的主要参数。在性能测试中,要根据需要采集具体的资源利用率参数来进行分析。

    从服务器的角度看,性能测试主要关注CPU、内存、服务器负载、网络、磁盘IO等

    1.硬件性能指标:CPU,内存Memory,磁盘I/O(Disk I/O),网络I/O(Network I/O)

    CPU:主要解释计算机指令以及处理计算机软件中的数据

    Linux系统中top命令查看CPU的使用率

    CPU的利用率(<=75%)有:user(用户使用),sys(系统调用<=30%),wait(等待<=5%),idle(空闲)

    当user消耗高时,通过top命令查看哪个用户进程占用cpu的使用

    user消耗过高的原因可能有:

    (1)代码问题。如代码中耗时循环中不加sleep,即例如while的死循环中,没有加sleep时间,导致没有空余的时间将cpu的控制权给其他的进程,一直陷入该死循环中,cpu得不到休息,所以usr的消耗过高,则cpu的消耗高

    (2)gc频繁。gc则为垃圾回收,由于垃圾回收也是需要大量的计算,也消耗cpu,所以当gc频繁时也导致usr用户空间的消耗也过高,cpu消耗过高

    当sys消耗高时,通过top命令查看系统调用资源的情况

    sys消耗过高的原因可能有:
    (1)上下文切换频繁。上下文切换发生的情况有:中断处理,多任务处理,用户状态改变。

    中断处理,当cpu停止处理当前的进程转而处理中断请求的进程时发生上下文切换。多任务处理则为有多个进程请求cpu的处理,进程的数量多于cpu的核数,则分配进程时间片,根据时间片处理进程,意味着会强制停止一个进程而去处理另一个进程,形成频繁的上下文切换。用户状态改变则为user状态与sys状态的改变。

    wait较高时,即等待的进程占比高则可以考虑是否磁盘读写,磁盘瓶颈问题, 等待的进程较多时,cpu无论如何切换都是切换到等待的进程,导致cpu一直在频繁切换等待的线程而利用率较低

    内存:与cpu沟通的桥梁,计算机中所有程序的运行都在内存中进行,内存分为物理内存、页面交换(Paging),SWAP内存(虚拟内存)

    页面交换:当物理内存即实际的内存满了的时候,将物理内存中不常用的进程调出存储到虚拟内存中,以缓解物理内存空间的压力,所以当物理内存与虚拟内存的数据交换频繁的时候,这时候就要关注下内存的性能情况。

    SWAP内存:为进程分配虚拟的内存空间,即调用硬盘的空间作为内存使用。

    内存的性能分析是又可用内存与页面交换来分析的,可用内存使用占70%-80%为上限,当超出这个数值,内存性能情况就比较危险,而且即使可用内存使用不超过80%的数值时,页面交换比较频繁时,也是要关注下内存情

    一般物理内存即使是满内存也不能代表内存出现问题,主要是看虚拟内存swap,虚拟内存应该<=70%,大于则可以考虑是否内存问题或者内存泄漏

    磁盘吞吐量,指单位时间内通过磁盘的数据量。主要关注磁盘的繁忙率,如果高于70%,则磁盘瓶颈

    网络吞吐量,指单位时间内通过网络的数据量,当吞吐量大于网路设备或链路最大传输能力,即带宽时,则应该考虑升级网络设备或者增加带宽,Linux命令netstate

    网络IO也有可能出现终止连接失败。例如当服务端出现大量的TIME_WAIT,见以下TCP终止连接的第4个步骤,在主动发起关闭连接方接收到结束符FIN时状态变为TIME_WAIT,这时在服务端发现大量的TIME_WAIT,意味着关闭连接是由服务端发起的。

    常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。

    问?什么情况是由服务端发起关闭连接?答:在用户端的应用程序忘记关闭连接

    另外如果在服务端发现大量状态CLOSE_WAIT,则说明第二次关闭回不去,也就是TCP关闭连接的第三个步骤没有执行,停留在CLOSE_WAIT的状态,浏览器如果这时发起请求则会返回超时连接,因为服务端这边一直无法进行第二次关闭,将结束符返回去给用户端。
    注:普及TCP连接的三次握手,终止连接的四次握手

    TCP三次握手连接:

    (1)用户端发送SYN给服务器,用户端的状态为SYN_SEND

    (2)服务端接收到后发送ACK给用户端,服务端的状态为SYN_RECV

    (3)用户端接收到服务端发送过来的后发送了ACK给服务端,用户端的状态变为Estabilished

    TCP终止连接:

    (1)用户端的应用主动发起关闭连接,即应用调用close发送FIN给服务端

    (2)服务端接收到FIN后发送ACK给用户端,服务端的状态变为CLOSE_WAIT

    (3)服务端发送ACK给用户端的同时也将FIN作为一个文件结束符传递给接收端应用程序

    (4)用户端的应用程序接收到FIN后将调用close关闭它的套接字,确认FIN,这时用户端的状态变为TIME_WAIT

    (5)用户端发送ACK回执给服务端,连接终止

    2.中间件:常用的中间件例如web服务器Tomcat,Weblogic web服务器,JVM(java虚拟机),ThreadPool线程池,JDBC数据驱动

    注:http服务器和web服务器与应用服务器的差别是一个存储静态网页的服务器,一个是存储css,js等动态加载网页的服务器,而tomcat则属于应用服务器

    注:对中间件例如对服务器的性能测试,需要将监控的jmeter-server的文件下载在服务端上,然后开启即可监控被测服务器的性能,或者将监控的软件下载在被测服务器上,远程启动监控软件等

    3.数据库指标

    应关注SQL,吞吐量,缓存命中率,连接数等,则是关注sql语句执行时间,以微妙为单位,吞吐量TPS,缓存命中率应>=95%

    注:对数据库的性能测试通过jemter利用批量的sql语句对数据库进行操作,从而测试数据库的性能,前提是需要将jdbc的驱动加载在测试计划添加的驱动文件中,然后添加jdbc的前置处理器和jdbc的请求sample。

    4.JVM,java虚拟机,为使java的代码可以编译运行在不同的平台上顺畅,仿真模拟各种计算机来实现

    GC:自动内存管理程序,被引用的对象保存在内存中,当对象不被引用时则释放。关注的参数有Full GC完全java虚拟机垃圾部分回收频率

    5.前端指标

    前端应该关注页面展示,即首次显示时间,页面数量,页面大小,网络startRender,firstRender等

    注:关注前端的性能与后端的性能的不同点在于,前端是每个用户的直观的感受,以及前端页面的加载元素耗费时间给予用户的感受,而后端的性能关注点在于多用户使用系统时,服务器是否能够承受或者服务器的处理能力如何,能否以较好的响应时间响应。

    6.Load:系统平均负载,特定时间间隔内运行进程数,Load与cpu核数一致

    CPU

    CPU使用率:指用户进程与系统进程消耗的CPU时间百分比,长时间情况下,一般可接受上限不超过85%。

    后台服务的所有指令和数据处理都是由CPU负责,服务对CPU的利用率对服务的性能起着决定性的作用。

    Linux系统的CPU主要有如下几个维度的统计数据:

    us:用户态使用的cpu时间百分比

    sy:系统态使用的cpu时间百分比

    ni:用做nice加权的进程分配的用户态cpu时间百分比

    id:空闲的cpu时间百分比

    wa:cpu等待IO完成时间百分比

    hi:硬中断消耗时间百分比

    si:软中断消耗时间百分比

    下图是线上开放平台转发服务某台服务器上top命令的输出,下面以这个服务为例对CPU各项指标进行说明

     

    us & sy:大部分后台服务使用的CPU时间片中us和sy的占用比例是最高的。同时这两个指标又是互相影响的,us的比例高了,sy的比例就低,反之亦然。通常sy比例过高意味着被测服务在用户态和系统态之间切换比较频繁,此时系统整体性能会有一定下降。另外,在使用多核CPU的服务器上,CPU 0负责CPU各核间的调度,CPU 0上的使用率过高会导致其他CPU核心之间的调度效率变低。因此测试过程中CPU 0需要重点关注。

    ni:每个Linux进程都有个优先级,优先级高的进程有优先执行的权利,这个叫做pri。进程除了优先级外,还有个优先级的修正值。这个修正值就叫做进程的nice值。一般来说,被测服务和服务器整体的ni值不会很高。如果测试过程中ni的值比较高,需要从服务器Linux系统配置、被测服务运行参数查找原因

    id:线上服务运行过程中,需要保留一定的id冗余来应对突发的流量激增。在性能测试过程中,如果id一直很低,吞吐量上不去,需要检查被测服务线程/进程配置、服务器系统配置等。

    wa:磁盘、网络等IO操作会导致CPU的wa指标提高。通常情况下,网络IO占用的wa资源不会很高,而频繁的磁盘读写会导致wa激增。如果被测服务不是IO密集型的服务,那需要检查被测服务的日志量、数据载入频率等。

    hi & si:硬中断是外设对CPU的中断,即外围硬件发给CPU或者内存的异步信号就是硬中断信号;软中断由软件本身发给操作系统内核的中断信号。通常是由硬中断处理程序或进程调度程序对操作系统内核的中断,也就是我们常说的系统调用(System Call)。在性能测试过程中,hi会有一定的CPU占用率,但不会太高。对于IO密集型的服务,si的CPU占用率会高一些。

    内存

    内存利用率:内存利用率=(1-空闲内存/总内存大小)*100%,一般至少有10%可用内存,内存使用率可接受上限为85%。

    性能测试过程中对内存监控的主要目的是检查被测服务所占用内存的波动情况。

    在Linux系统中有多个命令可以获取指定进程的内存使用情况,最常用的是top命令,如下图所示

     

    其中

    VIRT:进程所使用的虚拟内存的总数。它包括所有的代码,数据和共享库,加上已换出的页面,所有已申请的总内存空间

    RES:进程正在使用的没有交换的物理内存(栈、堆),申请内存后该内存段已被重新赋值

    SHR:进程使用共享内存的总数。该数值只是反映可能与其它进程共享的内存,不代表这段内存当前正被其他进程使用

    SWAP:进程使用的虚拟内存中被换出的大小,交换的是已经申请,但没有使用的空间,包括(栈、堆、共享内存)

    DATA:进程除可执行代码以外的物理内存总量,即进程栈、堆申请的总空间

    从上面的解释可以看出,测试过程中主要监控RES和VIRT,对于使用了共享内存的多进程架构服务,还需要监控SHR。

    LOAD(服务器负载)

    Linux的系统负载指运行队列的平均长度,也就是等待CPU的平均进程数

    从服务器负载的定义可以看出,服务器运行最理想的状态是所有CPU核心的运行队列都为1,即所有活动进程都在运行,没有等待。这种状态下服务器运行在负载阈值下。

    通常情况下,按照经验值,服务器的负载应位于阈值的70%~80%,这样既能利用服务器大部分性能,又留有一定的性能冗余应对流量增长。

    Linux提供了很多查看系统负载的命令,最常用的是top和uptime

    top和uptime针对负载的输出内容相同,都是系统最近1分钟、5分钟、15分钟的负载均值

     

    Uptime命令结果的每一列的含义如下:

    “当前时间 系统运行时长 登录的用户数最 近1分钟、5分钟、15分钟的平均负载”

    查看系统负载阈值的命令如下,下方是查看CPU每个核心的使用情况:

     

    在性能测试过程中,系统负载是评价整个系统运行状况最重要的指标之一。通常情况下,压力测试时系统负载应接近但不能超过阈值,并发测试时的系统负载最高不能超过阈值的80%,稳定性测试时,系统负载应在阈值的50%左右。

    网络

    网络带宽:一般使用计数器Bytes Total/sec来度量,Bytes Total/sec表示为发送和接收字节的速率,包括帧字符在内。判断网络连接速度是否是瓶颈,可以用该计数器的值和目前网络的带宽比较。

    性能测试中网络监控主要包括网络流量、网络连接状态的监控。

    网络流量监控

    可以使用nethogs命令。该命令与top类似,是一个实时交互的命令,运行界面如下

     

    在后台服务性能测试中,对于返回文本结果的服务,并不需要太多关注在流量方面。

    网络连接状态监控

    性能测试中对网络的监控主要是监控网络连接状态的变化和异常。对于使用TCP协议的服务,需要监控服务已建立连接的变化情况(即ESTABLISHED状态的TCP连接)。对于HTTP协议的服务,需要监控被测服务对应进程的网络缓冲区的状态、TIME_WAIT状态的连接数等。Linux自带的很多命令如netstat、ss都支持如上功能。下图是netstat对指定pid进程的监控结果

    磁盘IO

     磁盘主要用于存取数据,因此当说到IO操作的时候,就会存在两种相对应的操作,存数据的时候对应的是写IO操作,取数据的时候对应的是读IO操作,一般使用% Disk Time(磁盘用于读写操作所占用的时间百分比)度量磁盘读写性能。

    性能测试过程中,如果被测服务对磁盘读写过于频繁,会导致大量请求处于IO等待的状态,系统负载升高,响应时间变长,吞吐量下降。

    Linux下可以用iostat命令来监控磁盘状态,如下图

     

    tps:该设备每秒的传输次数。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的

    kB_read/s:每秒从设备(driveexpressed)读取的数据量,单位为Kilobytes

    kB_wrtn/s:每秒向设备(driveexpressed)写入的数据量,单位为Kilobytes

    kB_read:读取的总数据量,单位为Kilobytes

    kB_wrtn:写入的总数量数据量,单位为Kilobytes

    从iostat的输出中,能够获得系统运行最基本的统计数据。但对于性能测试来说,这些数据不能提供更多的信息。需要加上-x参数

      

    rrqm/s:每秒这个设备相关的读取请求有多少被合并了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge)

    wrqm/s:每秒这个设备相关的写入请求有多少被Merge了

    await:每一个IO请求的处理的平均时间(单位是毫秒)

    %util:在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,该参数暗示了设备的繁忙程度。

    资源利用与负载对应关系

    图中拐点说明:
    (1)服务器某一资源使用逐渐达到饱和
    (2)通常可以利用拐点来进行性能测试分析与定位

    性能计数器(counters)

    是描述服务器或操作系统性能的一些数据指标,如使用内存数、进程时间,在性能测试中发挥着“监控和分析”的作用,尤其是在分析系统可扩展性、进行新能瓶颈定位时有着非常关键的作用。

    常见性能瓶颈

    吞吐量到上限时系统负载未到阈值:一般是被测服务分配的系统资源过少导致的。测试过程中如果发现此类情况,可以从ulimit、系统开启的线程数、分配的内存等维度定位问题原因

    CPU的us和sy不高,但wa很高:如果被测服务是磁盘IO密集型型服务,wa高属于正常现象。但如果不是此类服务,最可能导致wa高的原因有两个,一是服务对磁盘读写的业务逻辑有问题,读写频率过高,写入数据量过大,如不合理的数据载入策略、log过多等,都有可能导致这种问题。二是服务器内存不足,服务在swap分区不停的换入换出。

    同一请求的响应时间忽大忽小:在正常吞吐量下发生此问题,可能的原因有两方面,一是服务对资源的加锁逻辑有问题,导致处理某些请求过程中花了大量的时间等待资源解锁;二是Linux本身分配给服务的资源有限,某些请求需要等待其他请求释放资源后才能继续执行。

    内存持续上涨:在吞吐量固定的前提下,如果内存持续上涨,那么很有可能是被测服务存在明显的内存泄漏,需要使用valgrind等内存检查工具进行定位。

    性能瓶颈定位之拐点分析法

      “拐点分析”方法是一种利用性能计数器曲线图上的拐点进行性能分析的方法。它的基本思想就是性能产生瓶颈的主要原因就是因为某个资源的使用达到了极限,此时表现为随着压力的增大,系统性能却出现急剧下降,这样就产生了“拐点”现象。当得到“拐点”附近的资源使用情况时,就能定位出系统的性能瓶颈。

    软件性能的其它术语

    思考时间的计算公式

    Think Time,从业务角度来看,这个时间指用户进行操作时每个请求之间的时间间隔,而在做新能测试时,为了模拟这样的时间间隔,引入了思考时间这个概念,来更加真实的模拟用户的操作。

    在吞吐量这个公式中F=VU * R / T说明吞吐量F是VU数量、每个用户发出的请求数R和时间T的函数,而其中的R又可以用时间T和用户思考时间TS来计算:R = T / TS

    下面给出一个计算思考时间的一般步骤:

    1、首先计算出系统的并发用户数

    C=nL / T   F=R×C

    2、统计出系统平均的吞吐量

    F=VU * R / T   R×C = VU * R / T

    3、统计出平均每个用户发出的请求数量

    R=u*C*T/VU

    4、根据公式计算出思考时间

    TS=T/R

    软件性能的影响因素

    (1)硬件设施(部署结构、机器配置)

    (2)网络环境(客户端带宽、服务器端带宽)

    (3)操作系统(类型、版本、参数配置)

    (4)中间件(类型、版本、参数配置)

    (5)应用程序(性能)

    (6)并发用户数(系统当前访问状态)

    (7)客户端

    (8)数据服务器

    (9)编程语言、程序实现方式、算法

    软件性能的关注点

     

    首先,开发软件的目的是为了让用户使用,我们先站在用户的角度分析一下,用户需要关注哪些性能。

    对于用户来说,当点击一个按钮、链接或发出一条指令开始,到系统把结果已用户感知的形式展现出来为止,这个过程所消耗的时间是用户对这个软件性能的直观印象。也就是我们所说的响应时间,当相应时间较小时,用户体验是很好的,当然用户体验的响应时间包括个人主观因素和客观响应时间,在设计软件时,我们就需要考虑到如何更好地结合这两部分达到用户最佳的体验。如:用户在大数据量查询时,我们可以将先提取出来的数据展示给用户,在用户看的过程中继续进行数据检索,这时用户并不知道我们后台在做什么。

    用户关注的是用户操作的响应时间。

     

    其次,我们站在管理员的角度考虑需要关注的性能点。

    1、  响应时间
    2、 服务器资源使用情况是否合理
    3、 应用服务器和数据库资源使用是否合理
    4、 系统能否实现扩展
    5、 系统最多支持多少用户访问、系统最大业务处理量是多少
    6、 系统性能可能存在的瓶颈在哪里
    7、 更换那些设备可以提高性能
    8、 系统能否支持7×24小时的业务访问

    再次,站在开发(设计)人员角度去考虑。

    1、 架构设计是否合理
    2、 数据库设计是否合理
    3、 代码是否存在性能方面的问题
    4、 系统中是否有不合理的内存使用方式
    5、 系统中是否存在不合理的线程同步方式
    6、 系统中是否存在不合理的资源竞争

    那么站在性能测试工程师的角度,我们要关注什么呢?  一句话,我们要关注以上所有的性能点。

     

    性能测试的核心原理

    性能测试的核心原理,开发测试工具也是基于前两点:

    1、基于协议(前端后端通信机制),基于界面(决定和前端交互),基于代码(后端)。

    基于网络的分布式架构:基于网络协议去模拟用户发送请求;

    2、多线程:模拟多线程操作,多人同时操作,模拟大负载量(功能测试在于用以测试功能);

    3、模拟真实场景:真实的网络环境,用户操作时间不确定性,操作不确定,得出的数据是准确的,场景不对,数据也不一定可用。

    性能问题分析原则

     

    性能测试原则

    1)情况许可时,应使用几种测试工具或手段分别独立进行测试,并将结果相互印证,避免单一工具或测试手段自身缺陷影响结果的准确性;

    2)对于不同的系统,性能关注点是有所区别的,应该具体问题具体分析;

    3)查找瓶颈的过程应由易到难逐步排查:

         服务器硬件瓶颈及网络瓶颈(局域网环境下可以不考虑网络因素)

         应用服务器及中间件操作系统瓶颈(数据库、WEB服务器等参数配置)

         应用业务瓶颈(SQL语句、数据库设计、业务逻辑、算法、数据等)

    4)性能调优过程中不宜对系统的各种参数进行随意的改动,应该以用户配置手册中相关参数设置为基础,逐步根据实际现场环境进行优化,一次只对某个领域进行性能调优(例如对CPU的使用情况进行分析),并且每次只改动一个设置,避免相关因素互相干扰;

    5)调优过程中应仔细进行记录,保留每一步的操作内容及结果,以便比较分析;

    6)性能调优是一个经验性的工作,需要多思考、分析、交流和积累;

    7)了解“有限的资源,无限的需求”;

    8)尽可能在开始前明确调优工作的终止标准。

    性能测试的注意要点

     

    性能调优应该注意的要点

     

    性能测试流程

    采用自动化负载测试工具执行的并发性能测试,基本遵循的测试过程有:测试需求与测试内容,测试案例制定,测试环境准备,测试脚本录制、编写与调试,脚本分配、回放配置与加载策略,测试执行跟踪,结果分析与定位问题所在,测试报告与测试评估。

     

     

     

     

    一、性能测试需求分析

      性能需求分析是整个性能测试工作开展的基础,如果连性能的需求都没弄清楚,后面的性能测试执行其实是没有任何意义的,而且性能需求分析做的好不好直接影响到性能测试的结果。

      一些性能测试人员常犯的错误就是测试一开始就直接用工具对系统进行加压,没有弄清楚性能测试的目的,稀里糊涂做完了以后也不知道结果是否满足性能需求。市面上的书籍也大都是直接讲性能测试工具如LR,jmeter如何使用,导致很多新手一提到性能测试就直接拿工具来进行录制回放,使得很多人认为会使用性能测试工具就等于会性能测试了,殊不知工具其实只是性能测试过程中很小的一部分。

     在需求分析阶段,测试人员需要与项目相关的人员进行沟通,收集各种项目资料,对系统进行分析,建立性能测试数据模型,并将其转化为可衡量的具体性能指标,确认测试的目标。所以性能测试需求分析过程是繁杂的,需要测试人员有深厚的性能理论知识,除此之外还需要懂一些数学建模的知识来帮助我们建立性能测试模型。

    首先,让我们来看看通过性能需求分析我们需要得出哪些结论或目标:

    • 明确倒底要不要做性能测试?性能测试的目的是什么?
    • 明确被测系统是什么?被测试系统的相关技术信息如:架构、平台、协议等
    • 明确被测系统的基本业务、关键业务,用户行为
    • 明确性能测试点是什么?哪些需要测,为什么?哪些不需要测,又是为什么?
    • 明确被测系统未来的业务拓展规划以及性能需求?
    • 明确性能测试策略,即应该怎么测试?
    • 明确性能测试的指标,知道测试出来的结果怎么算通过?

    其次,需求分析阶段我们可以从以下几个方面入手:

    1、系统信息调研:

      指对被测试系统进行分析,需要对其有全面的了解和认识,这是我们做好性能测试的前提,而且在后续进行性能分析和调优时将会大有用处,试想如果连系统的架构、协议都不了解,我们如何进行准确的性能测试?如果进行性能分析与调优?

      需要分析的系统信息如下(包括但不仅限于如下这些):

     

     

     

    2、业务信息调研:

      指对被测试的业务进行分析,通过对业务的分析和了解,方便我们后续进行性能测试场景的确定以及性能测试指标的确定。

      需要分析的业务信息如下(包括但不仅限于如下这些):

     

    3、性能需求评估:

      在实施性能测试之前,我们需要对被测系统做相应的评估,主要目的是明确是否需要做性能测试。如果确定需要做性能测试,需要进一步确立性能测试点和指标,明确该测什么、性能指标是多少,测试通过or不通过的标准?性能指标也会根据情况评估,要求被测系统能满足将来一定时间段的业务压力。

      判断是否进行性能测试主要从下面两个方面进行思考:

    • 业务角度:

       系统是公司内部 or 对外?系统使用的人数的多少?如果一个系统上线后基本没几个人使用,无论系统多大,设计多么复杂,并发性的性能测试都是没必要的,前期可以否决。当然,除非在功能测试阶段发现非常明显的性能问题,使得用户体验较差的,此时可进行性能测试来排查问题。

    • 系统角度:系统又可以从以下3个方面进行分析

      a)系统架构:

         如果一个系统采用的框架是老的系统框架(通常大公司都有自己的统一框架),只是在此框架上增加一些应用,其实是没有必要做性能测试,因为老框架的使用肯定是经过了验证的。如果一个系统采用的是一种新的框架,可以考虑做性能测试。

      b)数据库要求:

         很多情况下,性能测试是大数据量的并发访问、修改数据库,而瓶颈在于连接数据库池的数量,而非数据库本身的负载、吞吐能力。这时,可以结合DBA的建议,来决定是否来做性能测试。

      c)系统特殊要求:

         从实时性角度来分析,某些系统对响应时间要求比较,比如证券系统,系统的快慢直接影响客户的收益,这种情况就有作并发测试的必要,在大并发量的场景下,查看这个功能的响应时间。

         从大数据量上传下载角度分析,某些系统经常需要进行较大数据量的上传和下载操作,虽然此种操作使用的人数不会太多,但是也有必要进行性能测试,确定系统能处理的最大容量,如果超过这个容量时系统需要进行相关控制,避免由于不人工误操作导致系统内存溢出或崩溃。

    4、确定性能测试点: 

      在上面第3点中,我们简单分析了如何确定一个系统是否需要做性能测试。下面简单总结下如果一个系统确定要做性能测试,我们如何确定被测系统的性能测试点?

      我们可以从下面几个方面进行分析:

    • 关键业务:

      确定被测项目是否属于关键业务,有哪些主要的业务逻辑点,特别是跟交易相关的功能点。例如转账,扣款等接口。如果项目(或功能点)不属于关键业务(或关键业务点),则可转入下面。

    • 日请求量:

      确定被测项目各功能点的日请求量(可以统计不同时间粒度下的请求量如:小时,日,周,月)。如果日请求量很高,系统压力很大,而且又是关键业务,该项目需要做性能测试,而且关键业务点,可以被确定为性能点。

    • 逻辑复杂度:

      判定被测项目各功能点的逻辑复杂度。如果一个主要业务的日请求量不高,但是逻辑很复杂,则也需要通过性能测试。原因是,在分布式方式的调用中,当某一个环节响应较慢,就会影响到其它环节,造成雪崩效应。

    • 运营推广活动:

      根据运营的推广计划来判定待测系统未来的压力。未雨绸缪、防患于未然、降低运营风险是性能测试的主要目标。被测系统的性能不仅能满足当前压力,更需要满足未来一定时间段内的压力。因此,事先了解运营推广计划,对性能点的制定有很大的作用。例如,运营计划做活动,要求系统每天能支撑多少 PV、多少 UV,或者一个季度后,需要能支撑多大的访问量等等数据。当新项目(或功能点)属于运营重点推广计划范畴之内,则该项目(或功能点)也需要做性能测试。

    以上 4 点,是相辅相成、环环相扣的。在实际工作中应该具体问题具体分析。例如,当一个功能点不满足以上 4 点,但又属于资源高消耗(内存、CPU),也可列入性能测试点行列。

    注:

    PV:访问一个URL,产生一个PV(Page View,页面访问量),每日每个网站的总PV量是形容一个 网站规模的重要指标。

    UV:作为一个独立的用户,访问站点的所有页面均算作一个UV(Unique Visitor,用户访问)

    5、确定性能指标: 

      性能需求分析一个很重要的目标就是需要确定后期性能分析用的性能指标,性能指标有很多,可以根据具体项目选取和设定,而具体的指标值则需要根据业务特点进行设定,本文不详细进行阐述,后续可考虑就此单独写一篇。

    二、性能测试准备

    1、测试环境准备:(见:四:测试脚本设计与开发)

      a)系统运行环境:这个通常就是我们的测试环境,有些时候需求比较多,做性能测试担心把环境搞跨了影响其它的功能测试,可能需要重新搭建一套专门用来做性能测试的环境。

      b)执行机环境:这个就是用来生成负载的执行机,通常需要在物理机上运行,而物理机又是稀缺资源,所以我们每次做性能测试都需要提前准备好执行机环境。

    2、测试场景设计:(见:四:测试脚本设计与开发)

    根据性能需求分析来设计符合用户使用习惯的场景,场景设计的好不好直接影响到性能测试的效果。

    3、性能工具准备:

      a)负载工具:根据需求分析和系统特点选择合适的负载工具,比如LR、Jmeter或galting等

      b)监控工具:准备性能测试时的服务器资源、JVM、数据库监控工具,以便进行后续的性能测试分析与调优。

    4、测试脚本准备:如果性能测试工具不能满足被测系统的要求或只能满足部分要求时,需要我们自己开发脚本配合工具进行性能测试。

    5、测试数据准备:

      a)负载测试数据:并发测试时需要多少数据?比如登录场景?

      b)DB数据量大小:为了尽量符合生产场景,需要模拟线上大量数据情况,那么要往数据库里提前插入一定的数据量。这可能需要花费一些时间,特点是关联系统较多,逻辑复杂的业务可能同时涉及多张表。

    6、性能测试团队组建:如果需要其它关联系统或专业人士如DBA配合的,也需要提前进行沟通。

    三、性能测试计划

    测试计划阶段最重要的是分析用户场景,确定系统性能目标。

    1、性能测试领域分析

    根据对项目背景,业务的了解,确定本次性能测试要解决的问题点;是测试系统能否满足实际运行时的需要,还是目前的系统在哪些方面制约系统性能的表现,或者,哪些系统因素导致系统无法跟上业务发展?确定测试领域,然后具体问题具体分析。

    2、用户场景剖析和业务建模

    根据对系统业务、用户活跃时间、访问频率、场景交互等各方面的分析,整理一个业务场景表,当然其中最好对用户操作场景、步骤进行详细的描述,为测试脚本开发提供依据。

    3、确定性能目标

    前面已经确定了本次性能测试的应用领域,接下来就是针对具体的领域关注点,确定性能目标(指标);其中需要和其他业务部门进行沟通协商,以及结合当前系统的响应时间等数据,确定最终我们需要达到的响应时间和系统资源使用率等目标;比如:

    ①登录请求到登录成功的页面响应时间不能超过2秒;

    ②报表审核提交的页面响应时间不能超过5秒;

    ③文件的上传、下载页面响应时间不超过8秒;

    ④服务器的CPU平均使用率小于70%,内存使用率小于75%;

    ⑤  各个业务系统的响应时间和服务器资源使用情况在不同测试环境下,各指标随负载变化的情况等;

    web性能测试之响应时间

    4、制定测试计划的实施时间

    预设本次性能测试各子模块的起止时间,产出,参与人员等等。

    (1)明确测试范围

    (2)制订时间(进度)计划

    (3)制订成本计划

    (4)制订环境计划

    (5)测试工具规划

    (6)测试风险分析

    四、测试脚本设计与开发

    性能测试中,测试脚本设计与开发占据了很大的时间比测试重。

    1、测试环境设计

    本次性能测试的目标是需要验证系统在实际运行环境中的性能外,还需要考虑到不同的硬件配置是否会是制约系统性能的重要因素!因此在测试环境中,需要部署多个不同的测试环境,

    在不同的硬件配置上检查应用系统的性能,并对不同配置下系统的测试结果进行分析,得出最优结果(最适合当前系统的配置)。

    这里所说的配置大概是如下几类:

    ①数据库服务器

    ②应用服务器

    ③负载模拟器

    ④软件运行环境,平台测试环境测试数据,可以根据系统的运行预期来确定,比如需要测试的业务场景,数据多久执行一次备份转移,该业务场景涉及哪些表,每次操作数据怎样写入,写入几条,需要多少的测试数据来使得测试环境的数据保持一致性等等。

    可以在首次测试数据生成时,将其导出到本地保存,在每次测试开始前导入数据,保持一致性。

    2、测试场景设计

    通过和业务部门沟通以及以往用户操作习惯,确定用户操作习惯模式,以及不同的场景用户数量,操作次数,确定测试指标,以及性能监控等。

    3、测试用例设计

    确认测试场景后,在系统已有的操作描述上,进一步完善为可映射为脚本的测试用例描述,用例大概内容如下:

    用例编号:查询表单_xxx_x1(命名以业务操作场景为主,简洁易懂即可)

    用例条件:用户已登录、具有对应权限等。。。

    操作步骤:

    ①进入对应页面。。。。。。

    ②查询相关数据。。。。。。

    ③勾选导出数据。。。。。。

    ④修改上传数据。。。。。。

    PS:这里的操作步骤只是个例子,具体以系统业务场景描述;

    4、脚本和辅助工具的开发及使用

    按照用例描述,可利用工具进行录制,然后在录制的脚本中进行修改;比如参数化、关联、检查点等等,最后的结果使得测试脚本可用,能达到测试要求即可;

    PS:个人而言,建议尽量自己写脚本来实现业务操作场景,这样对个人技能提升较大;一句话:能写就绝不录制!!!

    五、性能测试执行

    在这个阶段,只需要按照之前已经设计好的业务场景、环境和测试用例脚本,部署环境,执行测试并记录结果即可。

     1、人工边执行边分析

      通常我们做性能测试都是人工执行并随时观察系统运行的情况、资源的使用率等指标。性能测试的吸引力之一就在于它的不可预知性。当我们在做性能测试的时候,遇到跟预期不符的情况很正常,这个时候需要冷静的分析。但这个过程可能会很漫长,需要不断的调整系统配置或程序代码来定位问题,耗时耗人力。特别是在当前敏捷开发模式比较流行的大环境下,版本发布非常频繁且版本周期短(通常1~2周一个版本),没有那么长的时间来做性能测试。

    2、无人值守执行性能测试

      无人值守是最理想化的目标,目前我们也朝着这个方向努力。无人值守不是说没有人力介入,而是把人为的分析和执行过程分离,执行过程只是机器服从指令的运行而已。通常测试环境在白天比较繁忙,出现性能问题及定位难度较大且会影响功能测试。所以一般性能测试最好在晚上或周末进行,在相对较安静的条件有利于测试结果的稳定性。这种方法也相对比较适合敏捷的模式,不需要人工一直守着。只需要在拿到结果后进行分析就好了。同时,这种方式对测试人员能力的要求比较高,需要我们能进行自动化的收集各种监控数据、生成报表便于后续分析。

    六、结果分析与调优

    1、测试环境的系统性能分析

    根据我们之前记录得到的测试结果(图表、曲线等),经过计算,与预定的性能指标进行对比,确定是否达到了我们需要的结果;如未达到,查看具体的瓶颈点,然后根据瓶颈点的具体数据进行具体情况具体分析(影响性能的因素很多,这一点,可以根据经验和数据表现来判断分析)。

    2、硬件设备对系统性能表现的影响分析

    由于之前设计了几个不同的测试环境,故可以根据不同测试环境的硬件资源使用状况图进行分析,确定瓶颈是再数据库服务器、应用服务器抑或其他方面,然后针对性的进行优化等操作。

    3、其他影响因素分析

    影响系统性能的因素很多,可以从用户能感受到的场景分析,哪里比较慢,哪里速度尚可,这里可以根据258原则对其进行分析;

    至于其他诸如网络带宽、操作动作、存储池、线程实现、服务器处理机制等一系列的影响因素,具体问题具体分析,这里就不一一表述了。

    4、测试中发现的问题

    在性能测试执行过程中,可能会发现某些功能上的不足或存在的缺陷,以及需要优化的地方,这也是执行多次测试的优点。

    1.性能分析方法分类:

    (1)指标达成法:用于验证性能指标

    (2)最优化分析法:用于能力验证型测试

    2.常用性能分析方法:

    (1)快速瓶颈识别:

    ①硬件上的性能瓶颈        ②应用软件上的性能瓶颈     ③应用程序上的性能瓶颈  

    ④操作系统上的性能瓶颈    ⑤网络设备上的性能瓶颈

    (2)性能下降曲线:单用户区域、性能平坦区、压力区域、性能拐点

    (3)内存分析方法   (4)处理器分析方法   (5)磁盘IO分析方法      (6)进程分析方法   (7)网络分析方法

    七、测试报告与总结

       性能测试报告是性能测试的里程碑,通过报告能展示出性能测试的最终成果,展示系统性能是否符合需求,是否有性能隐患。性能测试报告中需要阐明性能测试目标、性能测试环境、性能测试数据构造规则、性能测试策略、性能测试结果、性能测试调优说明、性能测试过程中遇到的问题和解决办法等。

    性能测试工程师完成该次性能测试后,需要将测试结果进行备案,并作为下次性能测试的基线标准,具体包括性能测试结果数据、性能测试瓶颈和调优方案等。同时需要将测试过程中遇到的问题,包括代码瓶颈、配置项问题、数据问题和沟通问题,以及解决办法或解决方案,进行知识沉淀

    性能测试的实施过程

     

    客户端性能测试

    应用在客户端性能测试的目的是考察客户端应用的性能,测试的入口是客户端。它主要包括并发性能测试、疲劳强度测试、大数据量测试和速度测试等,其中并发性能测试是重点。

    并发性能测试的过程是一个负载测试和压力测试的过程,即逐渐增加负载,直到系统的瓶颈或者不能接收的性能点,通过综合分析交易执行指标和资源监控指标来确定系统并发性能的过程。负载测试(Load Testing)是确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统组成部分的相应输出项,例如通过量、响应时间、CPU负载、内存使用等来决定系统的性能。负载测试是一个分析软件应用程序和支撑架构、模拟真实环境的使用,从而来确定能够接收的性能过程。压力测试(Stress Testing)是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。

    并发性能测试的目的主要体现在三个方面:以真实的业务为依据,选择有代表性的、关键的业务操作设计测试案例,以评价系统的当前性能;当扩展应用程序的功能或者新的应用程序将要被部署时,负载测试会帮助确定系统是否还能够处理期望的用户负载,以预测系统的未来性能;通过模拟成百上千个用户,重复执行和运行测试,可以确认性能瓶颈并优化和调整应用,目的在于寻找到瓶颈问题。

    网络端性能测试

    应用在网络上性能的测试重点是利用成熟先进的自动化技术进行网络应用性能监控、网络应用性能分析和网络预测。

    网络应用性能分析的目的是准确展示网络带宽、延迟、负载和TCP端口的变化是如何影响用户的响应时间的。

    网络应用性能监控

    在系统试运行之后,需要及时准确地了解网络上正在发生什么事情;什么应用在运行,如何运行;多少PC正在访问LAN或WAN;哪些应用程序导致系统瓶颈或资源竞争,这时网络应用性能监控以及网络资源管理对系统的正常稳定运行是非常关键的。利用网络应用性能监控工具,可以达到事半功倍的效果,在这方面我们可以提供的工具是Network Vantage。通俗地讲,它主要用来分析关键应用程序的性能,定位问题的根源是在客户端、服务器、应用程序还是网络。在大多数情况下用户较关心的问题还有哪些应用程序占用大量带宽,哪些用户产生了最大的网络流量,这个工具同样能满足要求。

    网络预测

    考虑到系统未来发展的扩展性,预测网络流量的变化、网络结构的变化对用户系统的影响非常重要。根据规划数据进行预测并及时提供网络性能预测数据。我们利用网络预测分析容量规划工具PREDICTOR可以作到:设置服务水平、完成日网络容量规划、离线测试网络、网络失效和容量极限分析、完成日常故障诊断、预测网络设备迁移和网络设备升级对整个网络的影响。

    从网络管理软件获取网络拓扑结构、从现有的流量监控软件获取流量信息(若没有这类软件可人工生成流量数据),这样可以得到现有网络的基本结构。在基本结构的基础上,可根据网络结构的变化、网络流量的变化生成报告和图表,说明这些变化是如何影响网络性能的。PREDICTOR提供如下信息:根据预测的结果帮助用户及时升级网络,避免因关键设备超过利用阀值导致系统性能下降;哪个网络设备需要升级,这样可减少网络延迟、避免网络瓶颈;根据预测的结果避免不必要的网络升级。

    服务器端性能测试

    对于应用在服务器上性能的测试,可以采用工具监控,也可以使用系统本身的监控命令,例如Tuxedo中可以使用Top命令监控资源使用情况。实施测试的目的是实现服务器设备、服务器操作系统、数据库系统、应用在服务器上性能的全面监控,测试原理如下图。

    UNIX资源监控指标和描述

    监控指标 描述

    平均负载 系统正常状态下,最后60秒同步进程的平均个数

    冲突率 在以太网上监测到的每秒冲突数

    进程/线程交换率 进程和线程之间每秒交换次数

    CPU利用率 CPU占用率(%)

    磁盘交换率 磁盘交换速率

    接收包错误率 接收以太网数据包时每秒错误数

    包输入率 每秒输入的以太网数据包数目

    中断速率 CPU每秒处理的中断数

    输出包错误率 发送以太网数据包时每秒错误数

    包输入率 每秒输出的以太网数据包数目

    读入内存页速率 物理内存中每秒读入内存页的数目

    写出内存页速率 每秒从物理内存中写到页文件中的内存页数

    目或者从物理内存中删掉的内存页数目

    内存页交换速率 每秒写入内存页和从物理内存中读出页的个数

    进程入交换率 交换区输入的进程数目

    进程出交换率 交换区输出的进程数目

    系统CPU利用率 系统的CPU占用率(%)

    用户CPU利用率 用户模式下的CPU占用率(%)

    磁盘阻塞 磁盘每秒阻塞的字节数

    分析优化性能思路流程

    性能测试总结

    1、硬件上的性能瓶颈:

    一般指的是CPU、内存、磁盘读写等的瓶颈,为服务器硬件瓶颈。

    2、应用软件上的性能瓶颈:

    一般指的是服务器操作系统瓶颈(参数配置)、数据库瓶颈(参数配置)、web服务器瓶颈(参数配置)、中间件瓶颈(参数配置)等

    3、应用程序上的性能瓶颈:

    一般指的是开发人员,开发出来的应用程序(如sql语句、数据库设计、业务逻辑、算法等)。

    4、操作系统上的性能瓶颈:

    一般指的是Windows、linux等操作系统,如出现物理内存不足时,或虚拟内存设置不合理(虚拟内存设置不合理,会导致虚拟内存的交换率大大降低,从而导致行为的响应时间大大增加,可以认为在操作系统上出现了性能瓶颈)。

    5、网络设备上的性能瓶颈:

    一般指的是防火墙、动态负载均衡器、交换机等设备。

    2.安全测试

    安全测试是一个相对独立的领域,需要更多的专业知识。如:WEB的安全测试、需要熟悉各种网络协议、防火墙、CDN、熟悉各种操作系统的漏洞、熟悉路由器等。

    采用成熟的网络漏洞检查工具检查系统相关漏洞(即用最专业的黑客攻击工具攻击试一下,现在最常用的是 NBSI 系列和 IPhacker IP )

    安全测试主要是根据对应的项目来进行的安全测试用例设计及编写后执行安全测试。比如主要是对用户登录的校验、密码是否加密、权限;设计充值、提现等必须是否绑定手机号的短信验证码校验等;需要实名认证的,甚至人脸识别技术等;做压力测试的时候,比如需要考虑同一个IP地址的请求过多或频繁,需要有对应的判断是否为恶意攻击及判断后的相应解决措施等。

    3.兼容性测试

    兼容性测试主要是指,软件之间能否很好的运作,会不会有影响、软件和硬件之间能否发挥很好的效率工作,会不会影响导致系统的崩溃。

    平台测试

    浏览器测试

    软件本身能否向前或向后兼容

    测试软件能否与其它相关软件兼容

    数据兼容性测试

    最常见的兼容性测试就是浏览器的兼容性测试,不同浏览器在css,js解析上的不同会导致页面显示不同。

    常见的IE8的兼容性。

    4.文档测试

    国家有关计算机软件产品开发文件编制指南中共有14种文件,可分为3大类。

    开发文件:可行性研究报告、软件需求说明书、数据要求说明书、概要设计说明书、详细设计说明书、数据库设计说明书、模块开发卷宗。

    用户文件:用户手册、操作手册,用户文档的作用:改善易安装性;改善软件的易学性与易用性;改善软件可靠性;降低技术支持成本。

    管理文件:项目开发计划、测试计划、测试分析报告、开发进度月报、项目开发总结报告。

    在实际的测试中,最常见的就是用户文件的测试,例如:手册说明书等。

    文档测试关注的点:

    文档的术语

    文档的正确性

    文档的完整性

    文档的一致性

    文档的易用性

    5.易用性测试(用户体验测试)

    易用性(Useability)是交互的适应性、功能性和有效性的集中体现。又叫用户体验测试。

    6.业务测试

    业务测试是指:测试人员将系统的整个模块串接起来运行、模拟真实用户实际的工作流程。满足用户需求定义的功能来进行测试的过程。

    7.界面测试

    界面测试(简称UI测试),测试用户界面的功能模块的布局是否合理、整体风格是否一致、各个控件的放置位置是否符合客户使用习惯,此外还要测试界面操作便捷性、导航简单易懂性,页面元素的可用性,界面中文字是否正确,命名是否统一,页面是否美观,文字、图片组合是否完美等。

    8.安装与卸载测试

    安装测试是指:测试程序的安装、卸载。最典型的就是APP的安装、卸载。

    9.内存泄漏测试

    内存泄漏的检测:

    1、对于不同的程序可以使用不同的方法来进行内存泄露的检查,还可以使用一些专门的工具来进行内存问题的检查,例如MemProof. AQTime、Purify、BundsChecker等。 有些开发工具本身就带有内存问题检查机制.要确保程序员在编写程序和编译程序的时候打开这些功能。

    2、通过代码扫描分析工具来检查

    按测试实施组织的角度划分

    注:alpha测试和beta测试不能由程序员和测试员完成。

    1.α测试(Alpha Testing)

    α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试。

    α测试的目的是评价软件产品的FLURPS(即功能、局域化、可使用性、可靠性、性能和支持)。

    2.β测试(Beta Testing)

    Beta测试是一种验收测试。Beta测试由软件的最终用户们在一个或多个客户场所进行。

    α测试与Beta测试的区别:

    (1)测试的场所不同:Alpha测试是指把用户请到开发方的场所来测试,beta测试是指在一个或多个用户的场所进行的测试。

    (2)Alpha测试的环境是受开发方控制的,用户的数量相对比较少,时间比较集中。beta测试的环境是不受开发方控制的,用户数量相对比较多,时间不集中。

    (3)alpha测试先于beta测试执行。通用的软件产品需要较大规模的beta测试,测试周期比较长。

    3.第三方测试

    介于开发方和用户方之间的组织测试。

    按是否手工执行测试的角度划分

    1.手工测试(Manual testing)

    手工测试是由人一个一个的输入用例,然后观察结果,和机器测试相对应,属于比较原始但是必须的一个步骤。

    由专门的测试人员从用户视角来验证软件是否满足设计要求的行为。 
    更适用针对深度的测试和强调主观判断的测试 
    比如:众包测试和探索式测试

    优点:自动化测试无法代替探索性测试、发散思维类无既定结果的测试。

    缺点:执行效率慢,量大易错。

    2.自动化测试(Automation Testing)

    定义

    所谓自动化测试,就是在预设条件下运行系统或应用程序,评估运行结果。(预先条件包括:正常条件和异常条件)。简单来说,自动化测试就是是把人为驱动的测试行为,转化为机器执行的一种过程。通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的规程一步步执行测试,得到实际结果与期望结果的比较。在此过程中,为了节省人力、时间或硬件资源,提高测试效率,便引入了自动化测试的概念。

    分类

    自动化测试有:功能测试自动化、性能测试自动化、安全测试自动化。(一般情况下,我们说的自动化是指功能测试的自动化)

    自动化测试按照测试对象来分,还可以分为接口测试、UI测试等。接口测试的ROI(产出投入比)要比UI测试高。

    优点

     

     

    缺点

     

    适用范围

    自动化测试可以涉及和试用的范围主要在以下方面:

    基于Web UI的浏览器应用的界面测试

    基于WebService或者WebAPI的服务契约测试

    基于WCF、.net remoting、Spring等框架的服务的集成测试

    基于APP UI的移动应用界面测试

    基于Java、C#等编程文件进行的单元测试

    前提条件

    实施自动化测试之前需要对软件开发过程进行分析,以观察其是否适合使用自动化测试。通常需要同时满足以下条件:

    1) 需求变动不频繁;

    测试脚本的稳定性决定了自动化测试的维护成本。如果软件需求变动过于频繁,测试人员需要根据变动的需求来更新测试用例以及相关的测试脚本,而脚本的维护本身就是一个代码开发的过程,需要修改、调试,必要的时候还要修改自动化测试的框架,如果所花费的成本不低于利用其节省的测试成本,那么自动化测试便是失败的。项目中的某些模块相对稳定,而某些模块需求变动性很大。我们便可对相对稳定的模块进行自动化测试,而变动较大的仍是用手工测试。

    2) 项目周期足够长;

    自动化测试需求的确定、自动化测试框架的设计、测试脚本的编写与调试均需要相当长的时间来完成,这样的过程本身就是一个测试软件的开发过程,需要较长的时间来完成。如果项目的周期比较短,没有足够的时间去支持这样一个过程,那么自动化测试便成为笑谈。

    3) 自动化测试脚本可重复使用

    如果费尽心思开发了一套近乎完美的自动化测试脚本,但是脚本的重复使用率很低,致使其间所耗费的成本大于所创造的经济价值,自动化测试便成为了测试人员的练手之作,而并非是真正可产生效益的测试手段了。

    另外,在手工测试无法完成,需要投入大量时间与人力时也需要考虑引入自动化测试。比如性能测试、配置测试、大数据量输入测试等。

    适合场景

    通常适合于软件测试自动化的场合:

    (1)回归测试,重复单一的数据录入或是击键等测试操作造成了不必要的时间浪费和人力浪费;

    (2)此外测试人员对程序的理解和对设计文档的验证通常也要借助于测试自动化工具;

    (3)采用自动化测试工具有利于测试报告文档的生成和版本的连贯性;

    (4)自动化工具能够确定测试用例的覆盖路径,确定测试用例集对程序逻辑流程和控制流程的覆盖。

     

    注:自动化测试更适合用于回归测试,而不是用来发现新bug。

    自动化测试的流程

    测试计划:划定自动化测试的范围包含哪些需求,涉及到哪些测试过程

    测试策略:确定自动化测试的工具、编程方案、代码管理、测试重点

    测试设计:使用测试设计方法对被测试的需求进行设计,得出测试的测试点、用例思维导图等

    测试实施:根据测试设计进行用例编写,并且将测试用例用编程的方式实现测试脚本

    测试执行:执行测试用例,运行测试脚本,生成测试结果

    自动化实施的步骤

    (1)完成功能测试,版本基本稳定

    (2)根据项目特性,选择适合项目的自动化工具,并搭建环境

    (3)提取手工测试的测试用例转换为自动化测试的用例

    (4)通过工具、代码实现自动化的构造输入、自动检测输出结果是否符合预期

    (5)生成自动测试报告

    (6)持续改进、脚本优化

    自动化测试模型

    可以分为线性测试、模块化与类库、数据驱动测试和关键字驱动测试。

    线性测试通过录制或编写对应程序的操作步骤会产生相应的线性脚本,即单纯地模拟用户完整的操作场景。

    模块化与类库式把重复的操作单独封装成公共模块,在测试用例执行过程中,当需要用到模块封装时对其进行调用,这样就最大限度地消除了重复,从而提高测试用例的可维护性。

    数据驱动测试的定义:数据的改变驱动自动化测试的执行,最终引起测试结果的改变。就是把数据驱动所需要的测试数据参数化,我们可以用多种方式来存储和管理这些参数化的数据。

    关键字驱动测试又被称为表驱动测试或基于动作字测试。这类框架会把自动化操作封装为“关键字”,避免测试人员直接接触代码,多以“填表格”的形式降低脚本的编写难度。

    自动化测试框架

    自动化测试架构思想做一个对比:

    1)数据驱动测试:

       其思想是将我们的自动化测试脚本和测试数据放在共同的测试架构中,提供可重用的测试逻辑。这样做的目的是减少测试维护的工作量以及便于改善测试用例的覆盖率。测试用例需要输入的测试数据和测试完成后的测试结果数据都会被存储在同一个数据库或者数据源中,并且将测试的数据和测试逻辑分开。这样测试数据发生了变化时不会影响到我们的测试逻辑,并且同一套测试逻辑可以针对多种数据来进行测试,尽量提高测试逻辑的使用效率和复用效率。

    2)模块驱动测试:

       其思想是使用独立的脚本或者代码来对应每一个待测试的模块单元和功能。模块驱动测试引入的是编程语言中的面向对象编程中的抽象和模块独立封装的思想,即将测试代码和每一个测试模块进行解耦,减低自动化测试脚本或者自动化测试代码的维护成本,同时增加可扩展性。

    3)关键字驱动测试:

    Robot Framework和RedwoodHQ就是一种典型的关键字驱动测试的框架模式。关键字驱动测试通常也被认为是表格驱动测试,通过在表格中调用关键字来实现自动化测试。这种设计思想一般会将自动化测试拆分为设计和实现两个不同的阶段。

    4)行为驱动开发测试(BDD):

       是一种敏捷开发的思想,使用简单的、特定于领域的脚本语言(DSL)将结构化自然语言语句转换为通俗易懂的可执行测试。行为驱动开发的根基是一种“通用语言”,通俗易懂,同时被客户和开发者用来定义系统的行为。Cucumber就是一种行为驱动开发的自动化测试工具。

     

    自动化测试架构设计

     

    注:ant也可以换成maven,看项目代码是不是用maven

    分层自动化测试

     

    上图更多关注产品的UI层自动化测试,而分层自动化测试倡导产品不同阶段(层次)都需要自动化测试:

     

    unit :单元自动化测试,是对软件中最小的可测试单元进行检查与验证,如:C语言的最小的单元是一个元素,Java中最小的单元是一个类,图形化软件中的最小单元是一个窗口、按钮、菜单等。规范单元测试需要借助于单元测试框架(工具)

    单元测试(Code Review :中译 代码评审、代码审查):查找系统缺陷、保证软件真题质量,提高开发者自身水平。

    Service:接口自动化测试 分为:模块接口测试、web接口测试

    模块接口测试:测试模块间的调用与返回。如:类方法、函数调用并对返回结果进行验证

    Web接口测试:分为服务器接口测试、外部接口测试

    服务器接口测试:浏览器与服务器之间的接口,通过HTTP协议进行调用

    外部接口测试:调用接口,由第三方调用,如:调用微信、QQ、微博登陆接口

    UI层:是用户使用该产品的入口,所有功能都通过这一层提供并展示给用户,所以测试工作大多集中在这一层进行。为了减轻这一层的测试人力和时间成本,早期的自动化测试工具主要针对该层设计。

    除了UI层所展示的功能外,前端代码同样需要进行测试。在前端开发中最主要的是javascript脚本语言,而QUnit就是针对Javascript的一个强大的单元测试框架。

    分层自动化测试投入比例

    UI层自动化测试:投入比例小,原因:很难保证产品的质量,浪费人力、物力,因为越接近用户越容易变化

    什么样的项目适合自动化测试

    -任务测试明确,不会频繁变动。

    -每日构建后的测试验证。

    -比较频繁的回归测试。

    -软件系统界面稳定,变动少。

    -需要在多平台上运行的相同测试案例、组合遍历型的测试,大量的重复任务。

    -软件维护周期长。

    -项目进度压力不太大。

    -被测软件系统开发较为规范,能够保证系统的可测试性。

    -具备大量的自动化测试平台。

    -测试人员具备较强的编程能力。

    正常情况下满足三个:

    1、软件需求变动不频繁: 自动化脚本变化的大小、频率决定自动化维护成本,变化大,测试人员要进行扩展、修改、调试

    2、项目周期较长:需求确定,框架有好的设计,脚本开发调试时间较长

    3、自动化测试脚本可重复使用:测试项目之间是否存在很强的差异性,如:c/s、b/s之间的架构所展示的功能差不多,对脚本可重复使用,选用的技术、工具是否适应这种差异,测试人员是否有能力设计出满足条件的差异

    自动化测试及工具简述

    自动化测试的概念有广义和狭义之分:广义上讲:所有借助工具来辅助进行软件测试的方式都可以称为自动化测试;狭义上讲:主要是指基于UI层的功能自动化测试。

    1)UFT:(QTP:企业级自动化测试工具,提供强大、易用的录制回放功能,同时兼容对象和图像两种识别模式,支持B/S和C/S两种架构的软件测试 )

    2)Robot Framework:基于Python语言编写的自动化测试框架,具备良好的可扩展性,支持关键字驱动,同时可测试多种类型的客户端或接口,可进行移动端测试

    3)Watir:基于WEB测试,使用Roby语言开发

    4)Selenium:用于web应用程序测试工具,支持多平台,多浏览器,多语言去实现自动化测试

    下来我们探讨一下主流的自动化测试方案,无一例外,都有人机沟通的编程语言,加上机器操作的工具来组成。

    功能自动化测试

    VBScript + QTP(HP UFT),商用功能自动化测试方案

    Python/PHP/Java/C#/JavaScprit/Ruby + Selenium/Appium + 单元测试框架,开源功能自动化测试方案

    这里我们多介绍一点,Selenium/Appium 本身不能算是测试工具,而只是机器用来操作浏览器的工具,并且这个工具能听懂多种语言:

    Java,C# 这两个重 (zhòng) 语言

    Python,Ruby 这两个脚本轻语言

    PHP,JavaScript 这两个专门处理 Web 的语言

    工具外加指定的语言,可以让机器来操作浏览器,但是到此时还无法做到测试,于是才需要每个语言自己的单元测试框架,来一起完成这个功能自动化测试方案的构建。

    此外,业界还一种暂时临时的方案,就是 Python 2 + Robot Framework + Selenium Library 插件 + 单元测试框架 构成的一种测试方案,这个方案笔者不是非常推荐,主要基于两点:

    理念:这是一种基于关键字的方案,那么关键字是 QTP(HP UFT)的特长,并不是Selenium的本意

    Python/Java/C#/JavaScprit/Ruby + Gauge,又一款开源的功能自动化测试方案

    Thoughtworks 的基于BDD理念的自动化测试工具

    Gauge 本身就是完整的测试方案

    Gauge 是从需求分析师(BA)到测试工程师(QA)都覆盖的测试方案

    Java/Python + Macaca,阿里巴巴的功能自动化测试方案,缺点是文档少

    JavaScript + TestCafe,DevExpress 的开源功能自动化测试方案

    pure node.js - TestCafe不使用Selenium,并且不需要插件来在实际浏览器中运行测试。 它建立在node.js的顶部,因此它与现代开发工具集成和工作良好

    无需额外的设置或配置- TestCafe是所有设置后立即运行测试npm install

    完整的测试工具 - 使用单个启动命令,TestCafe启动浏览器,运行测试,收集结果并生成报告

    JavaScript + Postman,免费的Web接口功能自动化测试方案

    Groovy + SoapUI,开源的Web接口功能自动化测试方案

    性能自动化测试

    Java/C + HP LoadRunner,商业版性能测试方案

    Java + JMeter,开源版性能测试方案

    Python + locust,开源版性能测试方案

    学习自动化测试技术心得
    一、自动化测试的学习步骤

    1. 做好手工测试(了解各种测试的知识)->  2. 学习编程语言-> 3. 学习Web基础-> 4. 学习自动化测试工具 ->5. 学习自动化测试框架 -> 6. 实现自动化测试用例 -> 7. 开发自动化测试工具 ->8. 开发自动化测试框架

    按照这个步骤来说,基本上到第7步,难度就比较大了,这个时候也可以称呼自己为“测试开发”。

    二、自动化测试需要掌握的技术能力

    一、首先要学会一门语言,java或者Python,这里针对Python去说。如果要能够满足自动化测试的需求,不要求Python的能力上来就达到精通的水平,但是最起码的使用是要有的,然后在后期在逐步根据测试工具进行进阶。

    二、需要掌握前端的一些知识,无论学习语言还是前端知识,都是为了接下来的脚本和框架做铺垫。

    三、数据库的重要性不言而喻,MySQL必须掌握

    四、web端自动化测试工具selenium

    五、接口测试自动化工具jmeter、postman等

    六、移动端自动化测试appium

    在这里主要就是把自动化划分为了web自动化测试、接口自动化和移动端自动化。

    三、自动化测试的认识误区

    1、自动化的软件测试与手工的软件测试过程一样

    自动化测试所需要的技巧与手工测试所需要的技巧是不一样的。

    通常,你的项目经理会被那些测试工具销售们迷惑,认为自动化的软件测试就是简单地按一个录制的按钮,产生测试脚本。而事实上并没有那么简单。

    区分自动化测试所需要的技巧与手工测试所需要的技巧是非常重要的。最重要的是,自动化测试工程师需要掌握软件开发技巧,没有接受任何培训的手工测试人员,或者没有编程背景的手工测试人员,在实施自动化测试时会碰到很多困难。

    2、自动化测试一定会马上大量减少测试人员数量

    自动化测试不会马上大量减少测试人员数量。因为开展自动化测试初期需要投入一定的人力进行自动化测试脚本开发,并逐渐将自动化测试脚本用于日常的测试中,逐步减少手工测试人员从事重复劳动的时间和人数。为了缩短自动化测试脚本的开发时间,可以考虑将自动化测试脚本的开发工作借助外包的力量来早日实现大规模的自动化测试。

    3、测试自动化就是录制和回放

    仅仅录制得到的不是有效的自动化脚本。

    很多项目经理仍然把测试自动化等同于使用录制回放工具。而事实上,录制得到的脚本通常是不可重用的脚本,脚本中充满了硬编码的值,这些值应该被参数化,否则脚本仅仅适用于一个测试情况,脚本还应该加入条件判断、循环等结构,以便增强测试脚本的灵活性。

    4、自动化测试找不到bug

    自动化测试不直接找bug,而是通过解放有经验的测试工程师的生产力,让其从重复的回归测试中解放出来,从事新的测试方法和测试手段的研究。通过自动化测试解放出测试人员的时间和精力来间接地找到更多、更深层次的新bug,将产品质量再提高一个档次。

    5、自动化测试工具是“万能”的

    很多人一听到自动化测试,就认为自动化测试工具可以完成一切测试工作,从测试计划到测试执行再到测试结果分析,都不需要任何人工干预。显然,这是一种理想状态,现实中还没有哪个测试工具有这个能力,并且将来也不会有。在现实中有关的测试设计、测试案例,以及一些关键的测试任务还是需要人工参与的,即自动化测试是对手工测试的辅助和补充,它永远也不可能完全取代手工测试。

    6、自动化测试工具容易使用

    对于这一点,很多测试工程师有同样的错误观点,认为测试工具可以简单地通过捕获(录制)客户端操作生成脚本,且脚本不加编辑就可用于回放使用。事实上,自动化测试不是那么简单的,捕获的操作是否正确,以及脚本编辑是否合理都会影响测试结果。因此,自动化测试需要更多的技能,也需要更多的培训。

    7、自动化能提供百分百的测试覆盖率

    并非所有内容都可以被自动化地测试到。不可能覆盖所有可能的输入,所有可能的组合和路径。

    自动化测试可以增加测试的广度和深度,但是仍然无法达到100%的测试覆盖率,因为没有足够的时间或资源。

    8、忘记了测试的最终目标:找到BUG

    在自动化测试中,同样要注意把边界值分析、等价类分析、基于风险的测试方法、挑选最合适的测试用例等技术应用起来。

    通常在自动化测试过程中,我们都忙着搭建自动化框架和编写测试脚本,但是我们往往忘记了测试的本来目的:找bug。

    项目经理可能雇佣了最好的自动化开发人员来搭建框架,使用了最新最好的自动化开发技术,创建了成千上万的自动化测试脚本。但是如果BUG仍然被遗漏了,那些本该被自动化测试脚本捕捉到的BUG,结果没有被捕捉到,那么你的自动化测试仍然会被认为是失败的。

    9、所有测试用例都可以自动化

    不是所有的测试用例和测试步骤都可以转化为自动化测试。在自动化测试投入较多的行业,领先企业的自动化测试率有的能达到80%左右,但仍有20%左右的测试用例需要手工来进行。在国外,通常从开发第一版测试用例时,就同步进行自动化测试脚本的开发,所以自动化测试率普遍比中国企业高。

    10、只有性能测试才需要自动化

    自动化测试不光进行性能测试,更被大量应用于功能测试验证,在国外超过半数的自动化测试脚本都是用于功能验证测试的。

    11、测试工具可适用于所有的测试

    每种自动化测试工具都有它的应用范围和可用对象,所以不能认为一种自动化测试工具能够满足所有测试的需求。针对不同的测试目的和测试对象,应该选择合适的测试工具来对它进行测试。在很多情况下,需要利用多种测试工具或者开发自动化测试框架才能达到自动化测试的目的。商业和开源的测试工具能够用来进行自动化测试,但是我们需要根据自身产品的特点,开发自动化测试框架,在框架中提供常用的测试用例,加快测试速度,达到测试用例复用,这是今后测试自动化发展的道路。

    12、自动化测试能发现大量新缺陷

    发现更多的新缺陷应该是手工测试的主要目的,不能期望自动化测试去发现更多新缺陷。事实上,自动化测试主要用于发现原来的缺陷。自动化测试用于回归测试,而大量的新业务测试更多地还是依赖手工测试。

    除了以上列举的常见误区外,还有其他不同的认识误区。自动化测试认识误区的产生,归根到底最本质的原因是由于对自动化测试不现实的期望,也就是期望过高造成的。

    3.手工测试和自动化测试的区别

     

    按测试地域的角度划分

    1.国际化测试

    软件的国际化和软件的本地化是开发面向全球不同地区用户使用的软件系统的两个过程。而本地化测试和国际化测试则是针对这类软件产品进行的测试。由于软件的全球化普及,还有软件外包行业的兴起,软件的本地化和国际化测试俨然成为了一个独特的测试专门领域。

    本地化和国际化测试与其他类型的测试存在很多不同之处。下面是本地化和国际化测试 的一些要点。

    1、本地化后的软件在外观上与原来版本是否存在很大的差异,外观是否墼齐、不走样。

    2、是否对所有界面元素都进行了本地化处理,包括对话框、菜单、工具栏、状态栏、提示信息(包括声音的提示)、日志等。

    3、在不同的屏幕分辨率下界面是否正常显示。

    4、是否存在不同的字体大小,字体设置是否恰当。

    5、日期、数字格式、货币等是否能适应不同国家的文化习俗。例如,中文是年月日,而英文是月日年。

    6、排序的方式是否考虑了不同语言的特点。例如,中文按照第一个字的汉语拼音顺序排序,而英文按照首字母排序。

    7、在不同的国家采用不同的度量单位,软件是否能自适应和转换。

    8、软件是否能在不同类型的硬件上正常运行,特别是在当地市场上销售的流行硬件上。

    9、软件是否能在Windows或者其他操作系统的当地版本上正常运行。

    10、联机帮助和文档是否已经翻译,翻译后的链接是否正常。正文翻译是否正确、恰当, 是否有语法错误。

    软件本地化和国际化测试是一个综合了翻译行业和软件测试行业的测试类型。它要求测 试人员具备一定的翻译能力、语言文化,同时具备测试人员的基本技能。

    2.本地化测试

    之前我们一起学习的测试都是本地化测试。

    * 测试过程按4个步骤进行,即单元测试、集成测试、确认测试和系统测试及发布测试。

    * 开始是单元测试,集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。

    *集成测试把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。

    * 确认测试则是要检查已实现的软件是否满足了需求规格说明中确定了的各种需求,以及软件配置是否完全、正确。

    * 系统测试把已经经过确认的软件纳入实际运行环境中,与其它系统成份组合在一起进行测试。

    单元测试 (Unit Testing)

    * 单元测试又称模块测试,是针对软件设计的最小单位 ─ 程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。

    * 单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。

    1. 单元测试的内容

    * 在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/O条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应。

    (1) 模块接口测试

    * 在单元测试的开始,应对通过被测模块的数据流进行测试。测试项目包括:

    – 调用本模块的输入参数是否正确;

    – 本模块调用子模块时输入给子模块的参数是否正确;

    – 全局量的定义在各模块中是否一致

    * 在做内外存交换时要考虑:

    – 文件属性是否正确;

    – OPEN与CLOSE语句是否正确;

    – 缓冲区容量与记录长度是否匹配;

    – 在进行读写操作之前是否打开了文件;

    – 在结束文件处理时是否关闭了文件;

    – 正文书写/输入错误,

    – I/O错误是否检查并做了处理。

    (2) 局部数据结构测试

    * 不正确或不一致的数据类型说明

    * 使用尚未赋值或尚未初始化的变量

    * 错误的初始值或错误的缺省值

    * 变量名拼写错或书写错

    * 不一致的数据类型

    * 全局数据对模块的影响

    (3) 路径测试

    * 选择适当的测试用例,对模块中重要的执行路径进行测试。

    * 应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误。

    * 对基本执行路径和循环进行测试可以发现大量的路径错误。

    (4) 错误处理测试

    * 出错的描述是否难以理解

    * 出错的描述是否能够对错误定位

    * 显示的错误与实际的错误是否相符

    * 对错误条件的处理正确与否

    * 在对错误进行处理之前,错误条件是否已经引起系统的干预等

    (5) 边界测试

    * 注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性。对这些地方要仔细地选择测试用例,认真加以测试。

    * 如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素。

    2. 单元测试的步骤

    * 模块并不是一个独立的程序,在考虑测试模块时,同时要考虑它和外界的联系,用一些辅助模块去模拟与被测模块相联系的其它模块。

    – 驱动模块 (driver)

    – 桩模块 (stub) ── 存根模块

    * 如果一个模块要完成多种功能,可以将这个模块看成由几个小程序组成。必须对其中的每个小程序先进行单元测试要做的工作,对关键模块还要做性能测试。

    * 对支持某些标准规程的程序,更要着手进行互联测试。有人把这种情况特别称为模块测试,以区别单元测试。

    集成测试(Integrated Testing)

    * 集成测试 (组装测试、联合测试)

    * 通常,在单元测试的基础上,需要将所有模块按照设计要求组装成为系统。这时需要考虑的问题是:

    – 在把各个模块连接起来的时候,穿越模块接口的数据是否会丢失;

    – 一个模块的功能是否会对另一个模块的功能产生不利的影响

    – 各个子功能组合起来,能否达到预期要求的父功能;

    – 全局数据结构是否有问题;

    – 单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。

    在单元测试的同时可进行集成测试,发现并排除在模块连接中可能出现的问题,最终构成要求的软件系统。

    * 子系统的集成测试特别称为部件测试,它所做的工作是要找出集成后的子系统与系统需求规格说明之间的不一致。

    * 通常,把模块集成成为系统的方式有两种

    – 一次性集成方式

    – 增殖式集成方式

    1. 一次性集成方式(big bang)

    * 它是一种非增殖式组装方式。也叫做整体拼装。

    * 使用这种方式,首先对每个模块分别进行模块测试,然后再把所有模块组装在一起进行测试,最终得到要求的软件系统。

    2. 增殖式集成方式

    * 这种集成方式又称渐增式集成

    * 首先对一个个模块进行模块测试,然后将这些模块逐步组装成较大的系统

    * 在集成的过程中边连接边测试,以发现连接过程中产生的问题

    * 通过增殖逐步组装成为要求的软件系统。

    (1) 自顶向下的增殖方式

    * 这种集成方式将模块按系统程序结构,沿控制层次自顶向下进行组装。

    * 自顶向下的增殖方式在测试过程中较早地验证了主要的控制和判断点。

    * 选用按深度方向组装的方式,可以首先实现和验证一个完整的软件功能。

    (2) 自底向上的增殖方式

    * 这种集成的方式是从程序模块结构的最底层的模块开始集成和测试。

    * 因为模块是自底向上进行组装,对于一个给定层次的模块,它的子模块(包括子模块的所有下属模块)已经组装并测试完成,所以不再需要桩模块。在模块的测试过程中需要从子模块得到的信息可以直接运行子模块得到。

    * 自顶向下增殖的方式和自底向上增殖的方式各有优缺点。

    * 一般来讲,一种方式的优点是另一种方式的缺点。

    (3) 混合增殖式测试

    * 衍变的自顶向下的增殖测试

    – 首先对输入/输出模块和引入新算法模块进行测试;

    – 再自底向上组装成为功能相当完整且相对独立的子系统;

    – 然后由主模块开始自顶向下进行增殖测试。

    * 自底向上-自顶向下的增殖测试

    – 首先对含读操作的子系统自底向上直至根结点模块进行组装和测试;

    – 然后对含写操作的子系统做自顶向下的组装与测试。

    * 回归测试

    – 这种方式采取自顶向下的方式测试被修改的模块及其子模块;

    – 然后将这一部分视为子系统,再自底向上测试。

    关键模块问题

    * 在组装测试时,应当确定关键模块,对这些关键模块及早进行测试。

    * 关键模块的特征:

    ① 满足某些软件需求

    ② 在程序的模块结构中位于较高的层次(高层控制模块)

    ③ 较复杂、较易发生错误

    ④ 有明确定义的性能要求。

    确认测试(Validation Testing)

    * 确认测试又称有效性测试。任务是验证软件的功能和性能及其它特性是否与用户的要求一致。

    * 对软件的功能和性能要求在软件需求规格说明书中已经明确规定。它包含的信息就是软件确认测试的基础。

    1. 进行有效性测试(黑盒测试)

    * 有效性测试是在模拟的环境 (可能就是开发的环境) 下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。

    * 首先制定测试计划,规定要做测试的种类。还需要制定一组测试步骤,描述具体的测试用例。

    * 通过实施预定的测试计划和测试步骤,确定

    – 软件的特性是否与需求相符;

    – 所有的文档都是正确且便于使用;

    – 同时,对其它软件需求,例如可移植性、兼容性、出错自动恢复、可维护性等,也都要进行测试

    * 在全部软件测试的测试用例运行完后,所有的测试结果可以分为两类:

    – 测试结果与预期的结果相符。这说明软件的这部分功能或性能特征与需求规格说明书相符合,从而这部分程序被接受。

    – 测试结果与预期的结果不符。这说明软件的这部分功能或性能特征与需求规格说明不一致,因此要为它提交一份问题报告。

    2. 软件配置复查

    软件配置复查的目的是保证软件配置的所有成分都齐全;

    各方面的质量都符合要求;

    具有维护阶段所必需的细节;

    而且已经编排好分类的目录。

    应当严格遵守用户手册和操作手册中规定的使用步骤,以便检查这些文档资料的完整性和正确性。

    系统测试(System Testing)

    * 系统测试,是将通过确认测试的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其它系统元素结合在一起,在实际运行环境下,对计算机系统进行一系列的组装测试和确认测试。

    * 系统测试的目的在于通过与系统的需求定义作比较, 发现软件与系统的定义不符合或与之矛盾的地方。

    验收测试(Acceptance Testing)

    * 在通过了系统的有效性测试及软件配置审查之后,就应开始系统的验收测试。

    * 验收测试是以用户为主的测试。软件开发人员和QA(质量保证)人员也应参加。

    * 由用户参加设计测试用例,使用生产中的实际数据进行测试。

    * 在测试过程中,除了考虑软件的功能和性能外,还应对软件的可移植性、兼容性、可维护性、错误的恢复功能等进行确认。

    *确认测试应交付的文档有:

    – 确认测试分析报告

    – 最终的用户手册和操作手册

    – 项目开发总结报告。

    其他汇总

    1.回归测试(Regression Testing)

    回归测试指修改了旧的代码之后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。(自动回归测试将大幅度降低系统测试、维护升级等阶段的成本)。在软件变更之后,对软件重新进行的测试。其目标是检验对软件进行的修改是否正确,保证改动不会带来不可预料的行为或者另外的错误。

    在整个软件测试过程中占有很大的工作比重,软件开发的各个阶段都会进行多次回归测试。随着系统的庞大,回归测试的成本越来越大,通过正确的回归测试策略来改进回归测试的效率和有效性是很有意义的。

    2.冒烟测试(smoke testing)

    该术语来自硬件,指对一个硬件或一组硬件进行更改或修复后,直接给设备加电。如果没有冒烟,则该组件就通过了测试,也可以理解为该种测试耗时短,仅用一袋烟的功夫就足够了。

    在《微软项目求生法则》一书第14章“构建过程”关于冒烟测试,就是开发人员在个人版本的软件上执行目前的冒烟测试项目,确定新的程序代码不出故障。

    冒烟测试的对象是每一个新编译的需要正式测试的软件版本,目的是确认软件基本功能正常,可以进行后续正式的测试工作。

    冒烟测试的执行者是版本编译人。现基本执行对象为测试人员,在正规测试一个新版本之前,投入较少的人力和时间验证基本功能,通过则测试准入。

    冒烟测试一般在开发人员开发完毕后送给测试人员来进行测试时,测试人员会先进行冒烟测试,保证基本功能正常,不阻碍后续测试。

    3.接口测试

     原理:模拟客户端向服务器发送请求报文,服务器接收请求报文后对相应的报文做处理并向客户端返回应答,客户端接收应答的过程;

    重点:检查数据的交换,传递和控制管理过程,还包括处理的次数;

    核心:持续集成是接口测试的核心;

    优点:为高复杂性的平台带来高效的缺陷监测和质量监督能力,平台越复杂,系统越庞大,接口测试的效果越明显(提高测试效率,提升用户体验,降低研发成本);

     

    接口的定义

    接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。

    直白点讲就是:通过测试不同情况下的入参与之相对应的出参信息来判断接口是否和符合或满足相应的功能性、安全性要求。

    接口测试的目的

    接口测试的目的是测试接口的正确性和稳定性,尤其是那些与系统相关联的外部接口,测试的重点是要检查数据的交换,传递和控制管理过程,还包括处理的次数。外部接口测试一般是作为系统测试来看待的。

     

    接口通信过程

     

    接口类型

    接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。
    系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你提供一个他们写好的方法来获取数据,你引用他提供的接口就能使用他写好的方法,从而达到数据共享的目的,比如说咱们用的app、网址这些它在进行数据处理的时候都是通过接口来进行调用的。
    程序内部的接口:方法与方法之间,模块与模块之间的交互,程序内部抛出的接口,比如bbs系统,有登录模块、发帖模块等等,那你要发帖就必须先登录,要发帖就得登录,那么这两个模块就得有交互,它就会抛出一个接口,供内部系统进行调用。

     

     

     

     

     

    接口协议分类及特点

    接口的分类:1.webservice接口 2.http api接口

    webService接口是走soap协议通过http传输,请求报文和返回报文都是xml格式的,我们在测试的时候都用通过工具才能进行调用,测试。

    http api接口是走http协议,通过路径来区分调用的方法,请求报文都是key-value形式的,返回报文一般都是json串,有get和post等方法,这也是最常用的两种请求方式。

    json是一种通用的数据类型,所有的语言都认识它。(json的本质是字符串,他与其他语言无关,只是可以经过稍稍加工可以转换成其他语言的数据类型,比如可以转换成Python中的字典,key-value的形式,可以转换成JavaScript中的原生对象,可以转换成java中的类对象等。)

     

    接口测试工具

    1、webService接口:可以使用的工具有SoapUI、jmeter、loadrunner等;webservice接口开发框架:Axis2、cxf、xfire

    2、http api接口:可以使用的工具有postman、RESTClient、jmeter、loadrunner等;

    Mozilla Firefox下的两款接口测试工具RESTClient和HttpRequester。

    Google chrome下的三款接口测试工具Advanced REST Client和Postman和RESTED。

    接口测试的类型

    主要包含三种测试:

    Web接口测试;

    应用程序接口(API, application programming interface)测试;

    数据库测试。

    实际上意义就是UI界面到数据库之间,数据流经过的所有过程。

    接口测试用例设计

    用例设计重点:通常情况下主要测试最外层的两类接口:数据进入系统接口(调用外部系统的参数为本系统使用)和数据流出系统接口(验证系统处理后的数据是否正常)

     

    接口测试主要是在开发接口联调完毕后进行接口测试;当接口测试通过后,进入系统集成测试阶段,先冒烟测试通过后再进行功能测试,等到回归测试且系统比较稳定后,达到能进行对应的业务功能全链路的UI自动化测试和接口自动化等;

    接口测试质量评估标准

      1. 业务功能覆盖是否完整

      2. 业务规则覆盖是否完整

      3. 参数验证是否达到要求(边界、业务规则)

      4. 接口异常场景覆盖是否完整

      5. 接口覆盖率是否达到要求

      6.  代码覆盖率是否达到要求

      7. 性能指标是否满足要求

      8. 安全指标是否满足要求

    其他关联知识
    get请求,post请求的区别:

    1、GET使用URL或Cookie传参。而POST将数据放在BODY中。
    2、GET的URL会有长度上的限制,则POST的数据则可以非常大。
    3、POST比GET安全,因为数据在地址栏上不可见。而post只有条件数据在url上。
    4、一般get请求用来获取数据,post请求用来发送数据。
    其实上面这几点,只有最后一点说的是比较靠谱的,第一点post请求也可以把数据放到url里面,get请求其实也没长度限制,post请求看起来参数是隐式的,稍微安全那么一些些,但是那只是对于小白用户来说的,就算post请求,你通过抓包也是可以抓到参数的。(唯一区别就是这一点,上面3点区别都是不准确的)

    Get请求方法:可以比喻成发送一次请求给服务器就完事了。

    Post请求方法:

     

    可以比喻成发送两次请求给服务器,第一次先把header信息头发送给服务器,服务器返回同意你发body信息给他了,然后客户端再把body信息发送给服务器。

     

    http状态码:

    1、200 2开头的都表示这个请求发送成功,最常见的就是200,就代表这个请求是ok的,服务器也返回了。
    2、300 3开头的代表重定向,最常见的是302,把这个请求重定向到别的地方了。
    3、400 400代表客户端发送的请求有语法错误,401代表访问的页面没有授权,403表示没有权限访问这个页面,404代表没有这个页面。
    4、500 5开头的代表服务器有异常,500代表服务器内部异常,504代表服务器端超时,没返回结果。

    webservice接口怎么测试:

    它不需要你在拼报文了,会给一个webservice的地址,或者wsdl文件,直接在soapui导入,就可以看到这个webservice里面的所有接口,也有报文,直接填入参数调用,看返回结果就可以了。

    cookie与session的区别:

    1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

    2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。

    3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。

    4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

    5、所以个人建议:将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中

    确认测试

    确认测试:又称有效性测试。其任务就是确认软件的有效性,即确认软件的功能和性能及其它特性是否与用户的要求一致。这一阶段要做的主要工作是进行功能测试和软件配置复审。

    Alpha和Beta测试:Alpha测试是用户在开发环境下进行的测试,也可以是产品供应商内部的用户在模拟实际操作环境下进行的测试。软件在一个自然设置状态下使用,开发者坐在用户旁边,随时记下错误情况和使用中的问题。这是在受控制环境下进行的测试。Beta测试是由多个用户在一个或多个用户的实际使用环境下进行的测试。通常是在不受控制的环境下进行的测试,开发者通常不在现场。用户记录在测试过程中遇到的一切问题(真实的或想象的),并且定期把这些问题报告给开发者。

    随机测试(Ad-hoc Testing)

    随机测试主要是根据测试者的经验对软件进行功能和性能抽查。

    根据测试说明书执行用例测试的重要补充手段,是保证测试覆盖完整性的有效方式和过程。

    随机测试主要是对被测软件的一些重要功能进行复测,也包括测试那些当前的测试用例(TestCase)没有覆盖到的部分。

    安全测试(Security Testing) 

    安全测试是在IT软件产品的生命周期中,特别是产品开发基本完成到发布阶段,对产品进行检验以验证产品符合安全需求定义和产品质量标准的过程 。

    Findyou觉现在对安全知识的普及,大家意识都提上来了。比如现在越来越多的不支持HTTP协议,转用HTTPS等。

     探索性测试(Exploratory testing)

    探索性测试可以说是一种测试思维技术。它没有很多实际的测试方法、技术和工具,但是却是所有测试人员都应该掌握的一种测试思维方式。探索性强调测试人员的主观能动性,抛弃繁杂的测试计划和测试用例设计过程,强调在碰到问题时及时改变测试策略。

    探索性测试自动化暂时无法代替。Findyou也无法被代替。

    测试阶段

    测试流程

    测试用例

    定义

    软件测试用例的重要性

     

     

    测试用例设计及其选取

     

    如何编写软件测试用例

     

     

     

    软件测试应该具备的常识

     

    缺陷基本理论知识

    缺陷:软件表现与需求不符合的问题—bug /defect

    缺陷的属性

    1状态 :new(新的 ) 测试人员刚刚发现新缺陷

         Open(打开)   开发人员看到了这个缺陷

                Fixed(修复的)  开发人员已经修复了

                Reopen(重新打开) 测试验证没修复,重新给开发

               Close(关闭)  测试验证成功

    2严重程度 :致命的: 软件崩溃、死机、蓝屏

                         严重的: 出现多个问题的

                         一般的: 一个问题

                        轻微的: 界面的没对齐,错别字等

                        建议的: 使得软件完善的想法

    3优先级: 缺陷修改的优先次序

    4缺陷编号:标识缺陷

    5缺陷标题:缺陷的简单描述(在哪里发生了什么 )

    6缺陷描述: 步骤描述、预期和实际结果

    7 提交人:  缺陷发现

    8提交日期:发现缺陷的时间

    9附件 :   缺陷的截图

    10 分配人: 分配的开发

    缺陷跟踪流程: 缺陷和角色之间的跟踪顺序

     

     借鉴:https://home.cnblogs.com/u/douyini/

  • 相关阅读:
    201671010112 第十四周 Swing用户界面组件
    201671010112 第十二周
    201671010112 第十二周—— “如何在eclipse中重定向标准输入到文件?”整理方案
    201671010112 第十一周
    201671010112 第十周
    201671010112 第九周
    201671010112 第八周
    201671010112 第六周
    面向对象的程序设计课程进度
    201671010111 2016-2017-2《面向对象的程序设计》 java学习总结
  • 原文地址:https://www.cnblogs.com/laoshuai/p/13130260.html
Copyright © 2011-2022 走看看