本文主要记录的是《软件测试的艺术》一书的读书笔记以及相关的知识,欢迎大家提出自己的观点,进行讨论与分享。持续更新...
1,前言
1.软件测试为什么变得更加困难?涌现出大量的编程语言/操作系统以及硬件平台等。
2.所谓软件测试,就是一个过程或一系列过程,用来确认计算机代码完成了其该完成的功能,不执行其不该有的操作。软件应当是可预测且稳定的,不会给用户带来意外惊奇。
2,软件测试的心理学和经济学
2.1.软件测试的心理学
人类行为总是倾向于具有高度目标性,确立一个正确的目标有着重要的影响。
1.我们每当要测试一个程序时,应当想到要为程序增加一些价值。而通过测试来增加程序的价值是指提高程序的可靠性或质量,提高可靠性是指找出并最终修改程序的错误。
2.定义:测试是为发现错误而执行程序的过程。并且软件测试是一个破坏性的过程,甚至是一个施虐的过程。
3.不成功的测试用例,会看到程序输出正确的结果而没发现任何错误。???测试用例没发现错误就认为该测试用例是不成功的测试用例吗?
4.软件测试更适宜被视为试图发现程序中错误(假设其存在)的破坏性的过程。软件做了其应该做的,未做其不应该做的。
2.2 软件测试的经济学
穷举测试是不切实际的。
1. 黑盒测试又被称为数据驱动的测试或输入/输出驱动的测试。穷举测试用例不可能实现。
2.测试投入的目标在于通过有限的测试用例,最大限度地提高发现问题的数量,以取得好的测试效果。
2.白盒测试又称为逻辑驱动的测试。
3.穷举路径测试也并非是完全的测试。第一,即使穷举,也不能保证程序符合其设计规范,比如编写升序排序却写成降序。第二,程序可能会因为缺少某些路径而存在问题。第三,穷举路径测试可能不会暴露数据敏感错误。
2.3 软件测试的原则
1.测试用例中一个必须部分是对预期输出或结果的定义。
测试用例包含两个部分:1,对程序输入数据的描述;2,对程序在上述输入数据下的正确输出结果的精确描述。
2.程序员应当避免测试自己编写的程序。
3.编写软件的组织部应当测试自己的编写的软件。
4.应当彻底检查每个测试的结果。
5.测试用例的编写不仅应当根据有效和预期的输入情况,而且也应当根据无效和未预料到的输入情况。
6.检查程序是否“未做其应该做的”仅是测试的一般,测试的另一半是检查程序是否“做了不应该做的”。
7.应避免测试用例用后即弃,除非软件本身就是一个一次性的软件。
对程序的更改容易导致程序先前可以执行的部分发生故障,而这种故障是不容易被发现的,保留测试用例用作回归测试。
8.计划测试工作时不应默许假定不会发现错误。
9.程序某部分存在更多错误的可能性与该部分已发现错误的数量成正比。
10.软件测试是一项极富创造性,极具智力挑战的工作。
3.代码检查、走查与评审
人工测试:非基于计算机测试的过程,在程序开始编码之后,基于计算机的测试开始之前进行。有代码检查,代码走查,桌面检查,同行评审以及可用性测试。
3.1 代码检查与走查
1.代码检查和走查都需要人们组成一个小组来阅读或者直观检查特定的程序,进行头脑风暴,目标是找出错误,但不是改正错误。换句话说是测试而不是调试。
2.代码走查的另一个优点是一旦发现错误通常就能在代码中对其进行精确定位,这就降低了调试的成本。
3.代码检查和走查通常会有效的查出30%-70%的逻辑设计和编码错误,和基于计算机的测试是互补的。
3.2 代码检查
1.通常四个人:协调人员(非编码人员),编码人员,测试专家等。
2.代码检查要将注意力集中在发现错误上,而不是纠正错误。
3.对事不对人
4.代码检查可以提升编程人员的编码技术
5.代码检查错误列表:数据引用错误、数据声明错误、运算错误、比较错误、控制流错误、接口错误、输入/输出错误、其他检查
3.3 代码走查
跟代码检查相似,但规程稍微不同,错误检查技术也不一样。
走查小组建议包括:一个经验丰富的程序员,一个程序设计语言专家,一个程序员新手(可以给出新颖不带偏见的观点),最终维护程序的人员,一位来自其他不同项目的人员,一位来自该软件编程小组的程序员。
3.4 桌面检查
一个人阅读程序,对照错误检查表检查程序,对程序推演测试数据。
3.5 同行评审
让程序员对自身的编程技术进行自我评价。
4.测试用例的设计
由于成本和时间的约束,软件测试最关心的问题是:在所有可能的测试用例中,哪个子集最有可能发现最多的错误?
4.1 白盒测试
白盒测试关注的是测试用例执行的程度或覆盖程序逻辑结构(源代码)的程度。
逻辑覆盖测试:
1.语句覆盖:程序中的每条语句至少被执行一次。
2.判定(分支)覆盖:使得每一个判断都至少有一个为真和为假的输出结果。
3.条件覆盖:确保将一个判断中的每个条件的所有可能的结果至少执行一次。
4.判定/条件覆盖:将一个判断中的每个条件的所有可能的结果至少执行一次,将每个判断的所有可能的结果至少执行一次,将每个入口点都至少调用一次。
5.多重条件覆盖:将每个判定中的所有可能的条件结果的组合,以及所有的入口点都至少执行一次。
4.2 黑盒测试
1.等价类划分:确定等价类->生成测试用例。等价类划分是一个启发式的过程,需要根据实际情况进行划分,但一般情况下要划分为两个不同的组:有效等价类和无效等价类。(可以参考一些等价类划分的指导原则)
2.边界值分析:考虑边界值分析会获得更高的测试回报率。边界值分析不仅要考虑输入空间的边界值,还要考虑输出空间的的边界值。(参考一些通用指南和规则)
3.因果图分析:因果图有助于用一个系统的方法选择出高效的测试用例集,还可以指出规格说明的不完整和不明确之处。是根据条件的组合生成测试用例的系统性的方法,将规格说明转换为一个布尔逻辑网络。
确定规格说明中的因果关系,因指一个明确的输入条件或输入条件的等价类,果指一个输出条件或系统转换(输入对程序或系统状态的延续影响)
4.错误猜测:利用直觉和经验猜测出错的可能类型,然后编写测试用例还暴露这些错误。
4.3 测试策略
1.如果规格说明里面包含条件组合的情况,应首先使用因果分析方法
2.在任何情况下都应该使用边界值分析方法,对输入和输出边界都要进行测试
3.应该为输入和输出确定有效和无效等价类,必要的情况下对上面的测试用例进行补充
4.使用错误猜测技术增加更多的测试用例
5.针对上述的测试用例集检查程序的逻辑结构,应考虑使用逻辑覆盖准则
5.模块(单元)测试
模块测试中测试用例的设计过程:使用一种或多种白盒测试方法分析模块的逻辑,然后使用黑盒测试方法对照模块的规格说明以补充测试用例。它是大规模的白盒测试。
5.1 增量测试
1. 驱动模块:用来将测试用例驱动或传输到被测模块中。
2.桩模块:测试上层模块时用来模拟下层模块的的模块。
3.自顶向下测试:缺点:必须开发桩模块,创建测试环境可能很难,甚至无法执行...
4.自底向上测试:缺点:必须开发驱动模块,知道最后一个模块添加进去,程序才形成一个整体。
5.2 工具
单元测试有很多测试用具,最出名的就是xUnit,这本书没讲。
6.更高级别的测试
当程序无法实现其最终用户要求的合理功能时,就发生了一个错误。
根据软件开发的过程,对应的测试是模块测试、集成测试、功能测试、系统测试、验收测试和安装测试。
6.1 功能测试
1.功能测试是一个试图发现程序与其外部规格说明之间存在不一致的过程。外部规格说明是一份从最终用户角度对程序行为的精确描述。
2.功能测试通常是一项黑盒操作,等价类划分,边界值分析,因果图分析和错误猜测很适合功能测试。
6.2 系统测试
系统测试目的:将系统或程序与其初始目标进行比较,也就是说比较程序、程序目标和用户文档之间的不一致性。
1. 能力测试:逐条语句地检查目标文档,判断程序是否满足。(利用好问题清单)
2.容量测试:使程序经受大容量数据的检验。目的是为了证明程序不能处理目标文档中规定的数据容量。(考虑到该测试需要耗费大量的资源,所以不可进行过多的容量测试,但每个程序至少应该进行几次容量测试)
3.强度测试:使程序承受高负载或强度的检验,所谓高强度是指在很短的时间间隔内达到的数据或操作的数量峰值。(有些也叫做压力测试)
4.可用性测试:又叫用户体验测试,通过发动最终用户在真是环境下对应用程序进行测试。
5.安全性测试:设计测试用例来突破程序安全检查的过程。
6.性能测试:测试软件在特定负载和配置环境下程序的响应时间和吞吐率不满足要求。
7.存储测试:设计测试用例来证明软件的存储目标(内存或辅助存储)没有达到。
8.配置测试:测试软件在不同配置环境下(操作系统,浏览器等)程序不同的反应。
9.兼容性/转换测试:测试软件在不同版本或者环境下的反应。
10.安装测试:发现软件在安装过程中出现的各种问题。
11.可靠性测试:可靠性测试是为了提高软件的可靠性,如果软件的目标中包含了对可靠性的特别描述,就必须设计专门的可靠性测试。
12.可恢复性测试:证明系统的恢复机制不能够正确发挥作用。恢复机制是当系统发生故障时,如何从程序错误、硬件失效和数据错误中恢复过来。
13.服务/可维护性测试:测试软件的服务和可维护性目标。
14.文档测试:检车用户文档的正确性,主要方法是根据文档来确定系统测试用例的形式,用户文档作为审查的对象。
15.过程测试:对已规定的人工过程(如系统操作员、数据库管理员或最终用户的操作过程进行测试)
16.系统测试的执行:不能由程序员来进行测试;不能由该程序开发的机构来执行测试。执行系统测试的人思考问题的方式必须与最终用户相同,必须充分了解最终用户的态度和应用环境以及程序的使用方式。
6.3验收测试
将程序与其最初的需求及最终用户当前的需要进行比较的过程。通常由程序的客户或最终用户来进行,但明智的开发者会引导客户在开发过程和产品发布之前进行用户测试。
6.4测试的计划与控制
一个良好的测试计划应该包括:目标、结束准则、进度、责任、测试用例库及标准、工具、计算机时间、硬件配置、集成、跟踪步骤、调试步骤、回归测试。
6.5测试结束准则
1.(不是最佳)测试用例来源于(1)满足多重条件覆盖准则,(2)对模块接口规格说明进行边界值分析,产生的多有测试用例最终都是不成功的。
2.(也许是最有价值的准则)以确切的数量来描述结束测试的条件。
3.(涉及到许多判断和直觉)在测试过程中记录每个单位时间内发现的错误的数量,通过检查统计曲线的形状,常常可以决定究竟是继续该阶段的测试还是结束它并来时下一测试阶段。
最佳的可能是三种的组合。
7.可用性(用户体验)测试
可用性就像软件的脸蛋。
7.1可用性测试的基本要素
1.是否考虑到最终用户的理解力、教育背景以及环境压力。
2.程序的输出是否有意义、没有侮辱性的词语以及是否含糊不清?
3.错误诊断的提示信息是否清晰易懂还是需要计算机博士才可读懂?
4.用户界面上是否保持与概念一致、内部的连贯性、语法的一致性?是否符合约定的使用习惯/语义和句法规律、格式、样式以及缩写习惯?
5.需要高精确性和准确度的软件系统是否提供足够有效的输入验证?
6.系统是不是包含了太多选项或者包含的一些选项不会被使用,是不是符合人的思维和逻辑?
7.对于来自用户的输入,系统是否能够及时做出反应?比如鼠标点击会不会表现出被按压/弹起的状态。
8.程序的操作是否很容易上手?
9.软件的设计是否有助于用户准确输入?
10.用户的操作可以轻松重复吗吗?
11.用户是否确定能够在众多的功能和菜单中来回切换而不发生意外?用户会不会推荐给其他用户?
12.软件的功能实现是否达到了设计的规格要求?
可用性测试基本上属于黑盒测试的范畴。
7.2可用性测试流程
1.测试用户的选择:需要同一组用户完成多个测试以及不同组用户完成多个测试。有经验的测试专家以及外行人,合理性选择。与时候局外人或许可以给出不一样的见解。
2.需要多少用户进行测试:并不是越多越好,是情况而定,主要原则就是用最少的成本达到最高的测试回报。
3.数据采集方法:录制测试过程并使用“发声思考”可以很好的记录可用性测试数据以及用户对软件的使用感受。“眼球追踪”技术很复杂但却很有用,可以使用在武器导航,机器人控制,车辆控制以及其他队速读和响应有特别要求的系统。
4.可用性调查问卷:可以学学问卷调查设计技巧,一个原则:尽量不要让用户做过主观的回答,减少用户输入。主要采取三个形式:是否问题/真假问题/某种程度的同意反对
5.何时收工:没有一定的原则,根据经验来看。
8.调试
调试是执行一次成功的测试之后所有进行的工作。
8.1 调试方法
1.蛮力法调试:利用内存信息输出来调试、根据一般的“在程序中插入打印语句”建议来调试、使用自动化的调试工具。蛮力法调试忽略了思考的过程,效率比较低下。
2.归纳法调试:从细节转到全局,从线索出发,寻找线索之间的联系。步骤如下:确定相关数据->组织数据->做出假设->证明假设->证明假设->解决问题/
3.演绎法调试:从一些普遍的理论或前提出发,使用排除和精炼的过程,达到一个结论。步骤如下:列举出所有可能的原因或假设->利用数据排除可能的原因->提炼剩下的假设->证明剩下的假设->修复问题。其中有一个循环的过程。
4.回溯法调试:沿着程序的逻辑结构回溯不正确的结果,直到找出程序逻辑出错的位置。
5.测试法调试:当发现了某个被怀疑的错误的症状之后,我们需要编写与原先有所变化的测试用例,尽量确定错误的位置。
8.2 调试的原则
1.定位错误的原则:动脑筋/遇到僵局留到稍后解决/遇到问题把问题描述给其他人听/仅将调试工具作为第二种手段/避免能使用实验法-仅将其作为最后的手段
2.修改错误的技术:存在一个缺陷的地方有可能还存在其他缺陷;/应纠正错误本身而非其症状;/正确纠正错误的可能性并非100%;/随着程序规模的增加正确修改错误的可能性反而降低;/应该意识到纠正错误会引入新错误的可能性;/修改错误的过程也是临时回到设计阶段的过程;/应修改源代码而不是目标代码。
敏捷开发模式下的测试、互联网应用测试和移动应用测试目前不打算精读,到时候分主题进行阅读。