软件测试的理解

IEEE定义:使用人工或自动的手段来运行或测量软件系统的过程,以检验软件系统是否满足规定的要求,并找出与预期结果之间的差异。 测试对象:软件需求

   IEEE定义:使用人工或自动的手段来运行或测量软件系统的过程,以检验软件系统是否满足规定的要求,并找出与预期结果之间的差异。

    测试对象:软件需求、软件概要设计、软件详细设计、软件源代码、可运行程序、软件运行环境。覆盖到软件研发过程中的方方面面

    五大要素:质量、人员、资源(硬件设备、网络环境、时间)、流程(规范要求)、技术​

    目标:保证软件质量:(1)提高测试覆盖率 (2)提升测试效率​

    遵循原则​:1.测试显示缺陷的存在,但不能保证系统不存在缺陷

                     2.穷尽测试时不可能的,应及时设定测试终止条件

                     3.软件测试应该尽早进行​

缺陷在软件研发的前期引出,越往后修复成本越高​

                     4.缺陷具备群集特性

                     5.测试的杀虫剂悖论

 采用同样的测试用例方法多次测试同一个模块不会再发现新的缺陷, 测试用例和测试方法应该不断的修改评审,引入新方法

                     6.测试的二八原则

  测试的时间和资源是有限的,测试总存在风险。 把百分之八十的时间用在百分之二十的重要模块上

                     7.测试活动依赖于测试背景

 

软件测试分类

按照测试阶段:

1.单元测试:对最小可视单元进行测试,针对代码

遵循原则:(1)尽可能保证每个测试用例是互相独立的​

               (2)一般由代码的开发人员来实施

优点:能尽早的发现缺陷/有利于重构/简化集成(保证了最小单元的稳定性,正确性,为集成测试提供保障/文档(减少文档存在)/用于设计(设计的本身能够验证设计)

限制:不可能覆盖到所有路径,不能捕捉到所有的路径错误

        单元测试的投入非常大(投入产出的平衡点)

 各种单元测试框架​

Junit 针对Java的框架​

2.集成测试(单元模块之间的借口):在单元测试的基础上,测试在将所有的软件单元按照概要设计说明的要求组装成(模块,子系统或系统)的过程中各部分工作是否达到或实现相应技术指标及要求的活动

实施方案:Big Bang:  所有的东西组装好一起测试

               (瀑布) 自顶向下:​递增组装,从主程序开始沿控制层逐层向下

               (瀑布)自底向上(最常用):从程序模块的最底层逐层向上组装测试

               (敏捷) 核心系统集成:​把核心的部分挑出来进行测试

               (敏捷)高频集成:每隔一段时间对现有的代码进行集成测试

集成测试与单元测试的测试对象不同,集成测试测试模块与模块的之间的关系,集成测试的主要依据是软件概要设计,单元测试依据软件详细设计​

3.系统测试(功能和性能):将经过集成测试的软件作为计算机系统的一部分,与系统中其他部分结合起来,子实际运行环境下对计算机系统进行一系列严格有效的测试,以发现软件潜在的问题,保证系统的正常运行.(专职的测试岗位最重要)

  ​关注点:

      系统本身的使用,

      关注被测系统与其他相关系统之间的连通,

      关注系统在不同压力下使用的表现,

      关注系统在真实的使用环境下的表现

测试对象:除了软件​之外,还包括计算机的硬件以及相关的外围设备,数据采集和传输机构,支持软件,系统操作人员等整个系统.

倾向于​业务.

      ​

4.验收测试:也称交付测试,针对用户需求,业务流程的正式的测试,确定系统是否满足验收标准.由用户,客户或其他授权机构决定是否接受系统.

分类:

用户验收测试

运行验收测试

合同和规范验收测试

alpha(α)测试:开发者提供环境,用户进行测试(开发完了,开发者环境)

Beta测试:完全脱离开发者环境,由用户在用户的环境上测试

release:完全交付(正式交付版本)

验收测试驱动开发​(敏捷):TDD BDD 针对用户故事条件开发

测试手段:

黑盒测试、白盒测试

静态测试、动态测试

手工测试、自动化测试

黑盒测试:在 完全不考虑程序内部结构和内部特性的情况下,通过相关暴露出的接口来对程序进行测试,只检查程序的功能是否按照需求说明的规定能正常使用。能适当的接收输 入数据并产生正确输出信息。着眼于外部结构不考虑内部的逻辑,针对软件界面及可见功能进行测试。从用户的视角通过不同的数据事件驱动系统,根据结果进行判 断

优点:容易实施,不需要考虑内部

          更贴近用户的视角

缺点:视同不可见,测试覆盖率低,只能覆盖到代码的 百分之四十

           针对黑盒的自动化测试,测试用例的重用率较低​,脚本维护代价大

主要关注点:

是否有不正确或者遗漏的功能,其次接口上给定的输入系统能否接受并输出正确的结果

是否有数据结构错误或外部信息访问错误,性能上能否满足用户需求

在系统测试阶段用黑盒测试多

黑盒测试主要设计方法:

等价类划分法:把所有的输入当中等价的划分为一类形成若干典型的有代表性的输入,通过这些典型的输入进行测试用例设计。

边界值分析法:关注各种各样的边界条件,编写程序时,边界值容易出现失误、

错误推测法:基于经验或直觉来判断可能出现错误的情况、

因果图法:拿到程序规格需求说明说明书,将程序输入输出看成原因和结果,根据规格语义说明生成判定表

正交试验分析法:筛选输入数据然后设计测试用例的输入输出、

状态迁移图法:通过状态迁移关系设计测试用例,如:提交审批到待审批状态,退回等等各种状态,通过状态画出变迁的关系图、

流程分析法:梳理逻辑来进行测试用例设计

白盒测试:测试人员对内部结构十分了解,逻辑结构是透明的。根据逻辑结构设计来设计测试用例。衡量标准:逻辑覆盖率

语句:保证程序的每条语句至少执行一次

判定:每个分支至少执行一次,

条件:所有的条件表达式至少计算一次

条件组合:覆盖所有不同条件的组合情况

路径覆盖:每一条可能的路径至少执行一次

优点:需要对系统有深入了解

          可以检测代码中每条分支和路径,覆盖率高

          可以检测出代码中的隐藏错误

          对代码的测试比较彻底

缺点:昂贵,较高的覆盖率需要巨大的工作量,成本高

          无法检测代码中的遗漏路径以及难发现数据敏感性错误​

          不能够直接验证需求规格的正确性

主要测试方法:

代码检测法:多面检查,代码走查

静态结构分析法:通过使用测试工具分析源代码的内部结构

静态质量度量法:根据标准的质量

逻辑覆盖法:6中逻辑覆盖方法​

基本路径测试法:程序控制流图

灰盒测试:介于黑盒与白盒,系统主键判断系统符合用户需求

静态测试:无需执行被测程序,而是通过评审软件文档或代码,度量程序静态复杂度,检查软件是否符合变成标准,借以发现编写的程序的不足之处,减少错误出现的概率​

特点:程序不被运行,之间看文档代码,可人工也可自动化工具

方式:互审,走查(小组走查程序或文档​),会议

动态测试:通过运行被测程序,来检查运行结果与预期结果的差异来分析运行效率,正确性和健壮性等。​

手工测试:由专门的测试人员从用户的视角来验证软件是否满足设计要求的行为。更适用于针对深度的测试和强调主观判断的测试。

充分利用人的主观判断和创造性来进行测试

自动化测试:使用单独的测试工具软件控制测试的自动化执行以及对预期和结果进行自动检查

单元测试,接口测试,性能测试多用于自动化测试

手工测试优点:容易发现缺陷、更容易实施、创造性、灵活性

缺点:覆盖量化难、重复测试效率低、不一致性、可靠性低、人力资源依赖

自动化测试优点:高效率、速度快、高覆盖下、覆盖容易度量、准确可靠、不知疲劳

缺点:机械,发现缺陷率低、一次性投入大

 

  负载测试(Load testing)、压力测试(Stress Test,应称为强度测试)和性能测试,这三个概念常常引起混淆,难以区分,从而造成不正确的理解和错误的使用。

  目前对性能测试没有明确的定义,一般地,它主要是针对系统的性能指标制定性能测试方案,执行测试用例,得出测试结果来验证系统的性能指标是否满足既定值。性能指标里可能包括系统各个方面的能力,如系统并发处理能力,批量业务处理能力等。 

       负载测试、压力测试和性能测试的测试目的不同,但其手段和方法在一定程度上比较相似,通常会使用相同的测试环境和测试工具,而且都会监控系统所占用资源的情况以及其它相应的性能指标,这也是造成人们容易产生概念混淆的主要原因。
       我们知道,软件总是运行在一定的环境下,这种环境包括支撑软件运行的软硬件环境和影响软件运行的外部条件。为了让客户使用软件系统感到满意,必须确保系统 运行良好,达到高安全、高可靠和高性能。其中,系统是否具有高性能的运行特征,不仅取决于系统本身的设计和程序算法,而且取决于系统的运行环境。系统的运 行环境会依赖于一些关键因素,例如:

·                                 系统架构,如分布式服务器集群还是集中式主机系统等。

·                                 硬件配置,如服务器的配置,CPU、内存等配置越高,系统的性能会越好。

·                                 网络带宽,随着带宽的提高,客户端访问服务器的速度会有较大的改善。

·                                 支撑软件的选定,如选定不同的数据库管理系统(Oracle、MySQL等)和web应用服务器(Tomcat、GlassFish、Jboss、WebLogic等),对应用系统的性能都有影响。

·                                 外部负载,同时有多少个用户连接、用户上载文件大小、数据库中的记录数等都会对系统的性能有影响。一般来说,系统负载越大,系统的性能会降低。

       从 上面可以看出,使系统的性能达到一个最好的状态,不仅通过对处在特定环境下的系统进行测试以完成相关的验证,而且往往要根据测试的结果,对系统的设计、代 码和配置等进行调整,提高系统的性能。许多时候,系统性能的改善是测试、调整、再测试、再调整、……一个持续改进的过程,这就是我们经常说的性能调优 (perormance tuning)。
       在了解了这样一个背景之后,就比较容易理解为什么在性能测试中常常要谈负载测试。从测试的目的出发、从用户的需求出发,就比较容易区分性能测试、负载测试和压力测试。性能测试是为了获得系统在某种特定的条件下(包括特定的负载条件下)的性能指标数据,而负载测试、压力测试是为了发现软件系统中所存在的问题,包括性能瓶颈、内存泄漏等。通过负载测试,也是为了获得系统正常工作时所能承受的最大负载,这时负载测试就成为容量测试。通过压力测试,可以知道在什么极限情况下系统会崩溃、系统是否具有自我恢复性等,但更多的是为了确定系统的稳定性。
      那么,如何给负载测试、压力测试下个定义呢?根据上述讨论,我们可以给出如下的定义:

·                                 负载测试是 模拟实际软件系统所承受的负载条件的系统负荷,通过不断加载(如逐渐增加模拟用户的数量)或其它加载方式来观察不同负载下系统的响应时间和数据吞吐量、系 统占用的资源(如CPU、内存)等,以检验系统的行为和特性,以发现系统可能存在的性能瓶颈、内存泄漏、不能实时同步等问题。负载测试更多地体现了一种方 法或一种技术。

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

        压力测试可以被看作是负载测试的一种, 即高负载下的负载测试,或者说压力测试采用负载测试技术。通过压力测试,可以更快地发现内存泄漏问题,还可以更快地发现影响系统稳定性的问题。例如,在正 常负载情况下,某些功能不能正常使用或系统出错的概率比较低,可能一个月只出现一次,但在高负载(压力测试)下,可能一天就出现,从而发现有缺陷的功能或 其它系统问题。通过负载测试,可以证明这一点,某个电子商务网站的订单提交功能,在10个并发用户时错误率是零,在 50个并发用户时错误率是1%,而在200个并发用户时错误率是20%。
    负载测试是为了发现系统的性能问题,负载测试需要通过系统性能特性或行为来发现问题,从而为性能改进提供帮助,从这个意义看,负载测试可以看作性能测试的 一部分。但它们两者的目的是不一样的,负载测试是为了发现缺陷,而性能测试是为了获取性能指标。因为性能测试过程中,也可以不调整负载,而是在同样负载情 况下改变系统的结构、改变算法、改变硬件配置等等来得到性能指标数据,从这个意义看,负载测试可以看作是性能测试所c的一种技术,即性能测试使用负载测试 的技术、使用负载测试的工具。性能测试要获得在不同的负载情况下的性能指标数据。
    通过负载测试和压力测试都可以获得系统正常工作时的极限负载或最大容量。容量测试,自然也是采用负载测试技术来实现,而在破坏性的压力测试中,容量的确定可以看作是一种副产品——间接结果。
    综合所述,负载测试、压力测试和性能测试的概念可以概括如下:

·                                 负载测试是通过改变系统负载方式、增加负载等来发现系统中所存在的性能问题。负载测试是一种测试方法,可以为性能测试、压力测试所采用。负载测试的加载方式也有很多种,可以根据测试需要来选择。

·                                 性能测试是为获取或验证系统性能指标而进行测试。多数情况下,性能测试会在不同负载情况下进行。

·                                 压力测试通常是在高负载情况下来对系统的稳定性进行测试,更有效地发现系统稳定性的隐患和系统在负载峰值的条件下功能隐患等。

负载测试及压力测试特点:

性能测试方法通过模拟生产运行的业务压力量和使用场景组合测试性能是否能够满足需要。具备三个特点:

   (1)这种方法的目的是验证系统是否具有系统宣称具有的能力。
      (2)这种方法需要事先了解被测试系统典型场景、并确定性能目标。
      (3)这种方法要求在已确定的环境下运行

●  负载测试用来测定系统饱和状态、确定阀值。其特点有:
      (1)这种方法的目的是找到系统处理能力的极限;通过“检测、加压、阀值”手段找到如“响应时间不超过10秒”,“服务器平均CPU利用率低于65%”等指标。
      (2)这种性能测试方法需要在给定的测试环境下进行,通常也需要考虑被测系统的业务压力量和典型场景、另外HP Mercury LoadRuner在使用该方法进行“加压”的时候必须选择典型场景。
      (3)这种性能测试方法一般用来了解系统的性能容量,或者是配合性能调优的时候来使用。

● 压力测试方法测试目标系统在一定饱和状态下,例如CPU、内存等在饱和状态下、系统能够处理的session的能力,以及系统是否会出现错误。该方法需要在系统cache调优与pool优化方面着手。该方法具备以下特点:
      (1)该方法的目的是检查系统处于压力情况下的,应用的表现。如增加VU数量、节点数量、并发用户数量等使应用系统的资源使用保持一定的水平,这种方法的主要目的是检验此时的应用表现,重点在于有无错误信息产生,系统对应用的响应时间等。
      (2)该方法通过模拟负载在实现压力。这种模拟需要考虑的层面很多、首先、模拟必须是有效的,我的经验是需要结合业务系统和软件架构来定制模拟指标、我 测试过一些国内生产的压力测试工具、他们使用通用的指标来考量、造成很多信息反馈有很大的水分。需要考虑的层面如:Oracle I/O、JVM GC、Conn Pool等。
      (3)该方法还可以测试系统的稳定性。这里的技巧在于“什么样的平台定义一个多长的压力测试时间让其稳定运行才是科学的?”