热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《软件测试精要》深度解析与实战经验分享

《软件测试精要》深度解析与实战经验分享,系统梳理了软件测试的核心概念与关键原则,结合实际项目中的测试经验和教训,详细探讨了测试分类、测试权衡要素、测试效率、测试覆盖率以及测试框架的引入和用例设计等内容,为读者提供了全面而实用的指导。

《软件测试艺术》按个人思路整理的重点内容,补充了实际项目中的测试经验教训

文章目录

      • 一、概念
        • 测试
        • 测试原则
        • 测试的分类
        • 测试权衡要素---测试效率/测试覆盖率/测试框架引入
        • 用例设计编码原则---代码质量/划分粒度/执行速度/执行独立性/自校验/健壮性
      • 三、测试用例设计 之 白盒/黑盒 手段
        • 黑盒测试
          • (1)等价类划分---典型值
          • (2)边界值分析---边界及异常边界
          • (3)因果图分析---输入条件组合
          • (4)错误猜测---经验与直觉推测异常场景
        • 白盒测试
          • 语句 / 判定 / 条件 / 判断条件 / 多重条件 / 路径 覆盖
      • 四、常见测试用例划分
        • 1、功能测试-单元测试/模块测试/集成测试
        • 2、性能测试-接口耗时/cpu内存等资源占用/编译镜像size
        • 3、异常测试-接口异常参数/模糊测试/异常流程测试(如ctrl+c后资源回收)
        • 4、压力测试-切换流程压测/高频接口压测/并发行为压测/最大负载场景
        • 5、典型场景-重点场景/基础场景/最大功能叠加场景
        • 6、debug手段测试-调试命令/proc打印/报错和info信息
      • 五、项目测试经验总结
        • 1、开发人员测试效率思考---开发人员该如何测试?有哪些优势/劣势
        • 2、测试观念与团队执行思考---关于团队的测试能力提升 和 开发测试氛围培养


一、概念


测试

测试是为了发现错误而执行程序的过程。一个成功的测试用例,通过诱发程序发生错误,可以在咋混个方向上促进程序质量改进。就像医生给病人看病检查,没有异常并不一定是一次成功的测试,准确发现问题才是。

测试原则

1、对预期输出或者结果有明确的定义。
2、避免测试自己编写的程序。
//思维转变,开发人员常对测试理解不够,会陷入思维约束,难以“破坏性”测试
3、编写软件的组织不应当测试自己编写的程序。
//与上一个类似,编写组织难以客观测试,度量时间和功能特性容易,度量可靠性极其困难,常应为进度压缩测试时间
4、应该彻底检查每个测试的执行结果。
5、用例要覆盖无效和未预期的输入。
6、测试不光是测试程序 ‘应该做的’,还要检查 是否 ‘做了不应该做的’。
7、避免测试用例用后即弃(除非一次性软件)
8、测试计划的时候 不应该 假定不会发现错误,要预留问题应对。
9、程序中部分存在更多问题可能性,与 该部分已发现错误成正比。
10、软件测试是一项 创造性、智力挑战的工作。

测试的分类

(1)从是否关注内部实现—黑盒(不关注代码实现)/白盒(根据内部实现流程设计)/灰盒(介于两者之间)
(2)从代码是否需要执行—静态测试(一些静态扫描工具,如圈复杂度检查) / 动态测试
(3)根据执行阶段–单元测试(模块内部-开发)/集成测试(模块交互-开发/测试) /系统测试 (测试)/ 验收测试(用户)
(4)根据目的-- 功能测试/性能测试/兼容性测试/安装测试 等
(5)更具测试执行结果校验方式–手动测试/自动测试

测试权衡要素—测试效率/测试覆盖率/测试框架引入

1、测试效率问题
由于时间和成本的约束,软件测试最关键的问题:在所有可能的测试用例中,哪个子集最有可能发现最多的错误
从测试发现成本上看,开发人员的测试效率是最高的,如果把review也作为测试的一部分,那么发现问题概率就更高了。
2、测试覆盖率
很多公司都对测试覆盖率有标准(如语句测试 80%等),也会对测试问题发现阶段做约束(如 研发自测问题/测试问题/客户问题你 7:2:1等 )。我们应该意识到,单纯也把测试覆盖率作为质量指标没有意义,应该把覆盖率作为一种发现未测试的代码手段。分析未覆盖部分,反推测试设计是否做好,有没有测试重点缺失,特别时未覆盖的代码出现问题时,要反思最初评估是否正确,是否需要补充。覆盖率高的测试 设计不一定好,反过来 覆盖率低 的 测试 很难向他人证明 你的测试设计效率和代码质量, 只能从滞后的问题分布结果来看
3、测试框架引入
不要自己造轮子,业界有很多常用的测试框架,如测试C语言平台cunit、java平台junit等。这些测试框架能能方便的提供一些 测试用例通用的行为控制需求,如:(1)提供测试suit(分类)管理和执行的能力;(2)提供用例手动选择执行和自动选择执行;(3)提供大量方便的测试assert(等于/不能与/返回值校验),用于指定结果;(4)提供测试结果报告输出 ;

用例设计编码原则—代码质量/划分粒度/执行速度/执行独立性/自校验/健壮性

0、用例代码质量和开发代码一致:测试代码如果没有做好质量控制,随着用例添加逐渐增多,用例本身 可读性、用例设计分层选择,性能 逐步出现问题,用例本身也会引入维护工作量,当用例本身 添加复杂、执行效率低、容易引起随机失败等问题出现,用例就会变为代码债务,需要加倍奉还。
1、测试粒度划分要小,用例代码控制在50行内:测试应该分类(分suit),针对每一个场景 规格点 进行单独测试。测试力度尽可能独立到一个规格或者特性。不要大包大揽的测试。测试的代码应该控制在50行以内,通过对测试公共行为进行封装,用例里面应该一眼能够看到 它测试的功能点。
2、测试执行要快:单个测试用例(除非特殊压测的用例以外),尽量低于1min,如果一个用例执行超过5min,大家就不愿意执行。
3、测试用例独立 相互无干扰:测试要可以随机重复执行,每次结果应该时一致的,不能A用例依赖B用例,或者 A执行后 B用例结果发生变化。
4、测试用例尽可能自动化:不要依赖人通过打印判断,或者 查询状态判断用例结果,用例应该尽可能自动化 自确认。即使多花10倍时间设计和编写一个用例,能给你节省数百倍,数千倍的手动执行确认时间。
5、测试用例要足够健壮:常见引入健壮性问题,对外部模块或者环境有太多依赖(其他模块出现问题,是否导致大部分自测用例不过?即使你本身业务正常。必须依赖);对配置有过多依赖,产品形态A只能执行一部分用例,产品版本B不能执行某些用例,都是设计用例阶段兼容性设计不足引入。过多无效/冗余 的断言,一个规格的测试用例应该集中在规格的测试点上,不要随意在一些不相关的动作 如 初始化等行为上添加断言,如果你认为这个动作需要测试,应该在它的单独用例里面添加判断。

三、测试用例设计 之 白盒/黑盒 手段


黑盒测试


(1)等价类划分—典型值

把全部输入的数据合理划分为若干等价类,在每一个等价类种取一个数据作为测试输入条件,以少量有代表性的测试数据取得比较好的测试结果。举个例子:测试产品输入分辨率,选择一个FHD以下,选一个FHD,选一个4K,选一个8K进行测试。
优点:通过测试设计方法,适用各种类型,以较少用例规模覆盖测试规格;缺点:没有组合测试;

(2)边界值分析—边界及异常边界

等价类的补充,**选择 正好等于左右边界,或者 刚好超过左右边界(异常值)**的数据作为测试数据。

(3)因果图分析—输入条件组合

等价类和边界值都没有考虑输入条件之间组合关系,因果图,就是运用图方法 对多个输入之间组合以及输入、输出之间 因果关系分析,生成 判定表,适用与检查各种输入组合情况。
基本流程:分析输入/输出,找出相互关系,明确约束和条件(剔除不可能组合),转化判定表按表项目测试。

(4)错误猜测—经验与直觉推测异常场景

基于经验和直觉推测程序中所有可能存在的各种错误,针对性的进行测试。如 接口异常输入(入参异常,文件异常,无效路径,缓冲溢出);系统状态异常(内存耗尽,cpu调度性能不足 调度超时)

白盒测试


语句 / 判定 / 条件 / 判断条件 / 多重条件 / 路径 覆盖

以下图为例子:
在这里插入图片描述
在这里插入图片描述

四、常见测试用例划分


1、功能测试-单元测试/模块测试/集成测试

主要针对基本的功能特性,如果一个小的特性在模块内部测试可以叫单元测试。你负责的模块进行单独功能测试(外部模块可以自己打桩构造),尽可能屏蔽外部模块影响,叫模块自测集成测试就是把和你相关的模块串联起来到一个正常的工作环境中测试,关注相关模块交互行为和结果是否符合预期。

2、性能测试-接口耗时/cpu内存等资源占用/编译镜像size


3、异常测试-接口异常参数/模糊测试/异常流程测试(如ctrl+c后资源回收)


4、压力测试-切换流程压测/高频接口压测/并发行为压测/最大负载场景


5、典型场景-重点场景/基础场景/最大功能叠加场景


6、debug手段测试-调试命令/proc打印/报错和info信息


五、项目测试经验总结


1、开发人员测试效率思考—开发人员该如何测试?有哪些优势/劣势

一、开发人员员进行测试优势:
(1)对规格的理解更深刻,能明确每个测试场景效果/边界/约束
(2)对方案实现细节更熟悉,能有针对性的做覆盖测试,知道哪些规格及实现是 继承/新增/变化,有重点的测试,知道哪些规格之间有耦合的需要组合测试,哪些需要压力测试,设计效率更高;
(3)开发过程本身测试和开发是相辅相成的,开发人员必须写用例,用测试驱动开发,有一套好的开发测试能快速回归,帮助 开发过程 迅速 识别问题,帮助定位,澄清规格交付完整性。
(4)最核心的一点,开发人员在 设计模块 的 时候,本身 测试设计(模块如何更高效的测试) 和 维护设计(如何更快速定位维问题)就是 模块设计的一部分。开发人员的测试和维护设计做好,可以非常顺畅和快速的搞自动化测试,支持迭代开发和重构。
(5)源于上一点,开发人员在做模块设计时候非常灵活,可以通过设计做很好的测试规划和测试方案
常见 如: 模块隔离设计 开发的时候经常会遇到 依赖模块没有准备好的情况,可以通过 测试桩 替代外部模块 进行独立的测试。测试平台迁移 如果外部依赖 封装与隔离做得足够好(包括 外部模块 和 系统接口),可以把 自己 的 模块代码 迁移到其他平台测试,举个例子 把 本来在arm linux环境的代码,直接编程好放在服务器上运行,可以极大提升测试效率 和 剥离对硬件环境的依赖。测试手段输出 可以把软件内部状态 输出到proc做自动化校验,合理的报错做自动化分析,以及研发人员的角度 有许多内部调试手段,如 嵌入式开发硬件的状态 上报测试。
二、研发测试的劣势:
开发人员测试 最容易忽视的点,(1)和外部模块交互部分往往是薄弱点,大家都关注自己的一亩三分地。(2)一些概率性问题测试往往不够,比如一些并发问题,往往 系统高负载状态下 压测 更容易暴露,但是模块自测常见 都是针对某个特性规格进行,缺少外部干扰和负载压力。(3)低优先级或者低价值的规格常常被 放低测试优先级。(4)依赖整机环境 或者 较为复杂的外部环境搭建时,开发者不愿投入太多工作量,容易选择性放弃。

2、测试观念与团队执行思考—关于团队的测试能力提升 和 开发测试氛围培养

一个开发团队,涉及的测试工作也是非常多并且极其重要的。很多团队很容易出现 重开发 轻测试 问题。如果测试用例投入不够,反过来 开发的问题 不能及时发现,后续解决成本直线上升,反过来影响开发计划。
常见测试工作如:
需求阶段 测试策略指定,
设计阶段 功能代码的可测试设计 / 功能代码的可维护设计 / 测试框架选型 / 测试依赖组件设计 / 测试自动化手段设计 / 测试用例表单设计
开发阶段 测试框架搭建 / 用例组件开发 / 测试用例编写/ 用例自动化整改
开发测试阶段-内部版本测试 测试构建以及执行效率提升 / 测试用例的周期执行工作 / 用例维护问题解决 / 问题用例补充和集成 / 测试覆盖率和测试问题分析


推荐阅读
  • 全面解析Java虚拟机:内存模型深度剖析 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • 作为140字符的开创者,Twitter看似简单却异常复杂。其简洁之处在于仅用140个字符就能实现信息的高效传播,甚至在多次全球性事件中超越传统媒体的速度。然而,为了支持2亿用户的高效使用,其背后的技术架构和系统设计则极为复杂,涉及高并发处理、数据存储和实时传输等多个技术挑战。 ... [详细]
  • Spring框架入门指南:专为新手打造的详细学习笔记
    Spring框架是Java Web开发中广泛应用的轻量级应用框架,以其卓越的功能和出色的性能赢得了广大开发者的青睐。本文为初学者提供了详尽的学习指南,涵盖基础概念、核心组件及实际应用案例,帮助新手快速掌握Spring框架的核心技术与实践技巧。 ... [详细]
  • Java中高级工程师面试必备:JVM核心知识点全面解析
    对于软件开发人员而言,随着技术框架的不断演进和成熟,许多高级功能已经被高度封装,使得初级开发者只需掌握基本用法即可迅速完成项目。然而,对于中高级工程师而言,深入了解Java虚拟机(JVM)的核心知识点是必不可少的。这不仅有助于优化性能和解决复杂问题,还能在面试中脱颖而出。本文将全面解析JVM的关键概念和技术细节,帮助读者全面提升技术水平。 ... [详细]
  • Go语言实现Redis客户端与服务器的交互机制深入解析
    在前文对Godis v1.0版本的基础功能进行了详细介绍后,本文将重点探讨如何实现客户端与服务器之间的交互机制。通过具体代码实现,使客户端与服务器能够顺利通信,赋予项目实际运行的能力。本文将详细解析Go语言在实现这一过程中的关键技术和实现细节,帮助读者深入了解Redis客户端与服务器的交互原理。 ... [详细]
  • 深入解析 C 语言与 C++ 之间的差异及关联
    深入解析 C 语言与 C++ 之间的差异及关联 ... [详细]
  • HTTP协议作为互联网通信的基础,其重要性不言而喻。相比JDK自带的URLConnection,HttpClient不仅提升了易用性和灵活性,还在性能、稳定性和安全性方面进行了显著优化。本文将深入解析HttpClient的使用方法与技巧,帮助开发者更好地掌握这一强大的工具。 ... [详细]
  • 西北工业大学作为陕西省三所985和211高校之一,虽然在农业和林业领域不如某些顶尖院校,但在航空航天领域的实力尤为突出。该校的计算机科学专业在科研和教学方面也具有显著优势,是考研的理想选择。 ... [详细]
  • Java虚拟机内存管理与优化技术深入解析
    Java虚拟机内存管理与优化技术深入解析 ... [详细]
  • C语言中按位取反与按位与运算符的使用方法及应用场景解析
    位运算是一种基于二进制的计算方式,在系统软件开发中经常用于处理二进制位的相关问题。C语言提供了六种位操作运算符,专门用于对整型数据(包括带符号和无符号的char、short等)进行操作。本文详细解析了按位取反和按位与运算符的使用方法及其典型应用场景,帮助开发者更好地理解和应用这些运算符。 ... [详细]
  • 本题库精选了Java核心知识点的练习题,旨在帮助学习者巩固和检验对Java理论基础的掌握。其中,选择题部分涵盖了访问控制权限等关键概念,例如,Java语言中仅允许子类或同一包内的类访问的访问权限为protected。此外,题库还包括其他重要知识点,如异常处理、多线程、集合框架等,全面覆盖Java编程的核心内容。 ... [详细]
  • C++ 进阶:类的内存布局与虚函数类的实现细节
    C++ 进阶:类的内存布局与虚函数类的实现细节 ... [详细]
  • Ceph API微服务实现RBD块设备的高效创建与安全删除
    本文旨在实现Ceph块存储中RBD块设备的高效创建与安全删除功能。开发环境为CentOS 7,使用 IntelliJ IDEA 进行开发。首先介绍了 librbd 的基本概念及其在 Ceph 中的作用,随后详细描述了项目 Gradle 配置的优化过程,确保了开发环境的稳定性和兼容性。通过这一系列步骤,我们成功实现了 RBD 块设备的快速创建与安全删除,提升了系统的整体性能和可靠性。 ... [详细]
author-avatar
xiaol
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有