文章目录
为什么要进行软件测试?
什么是软件测试?
软件测试是由 验证(Verification) 和 有效性确认(Validation) 活动构成的整体
Bill Hetzel博士(正向思维的代表):
- 软件测试就是为程序能够按预期设想那样运行而建立足够的信心
- “软件测试是一系列活动以评价一个程序或系统的特性或能力并确定是否达到预期的结果”
- 测试是为了验证软件是否符合用户需求,即验证软件产品是否能正常工作
Glenford J. Myers (反向思维的代表):
- 测试是为了证明程序有错,而不是证明程序无错误
- 一个好的测试用例是在于它能发现至今未发现的错误
- 一个成功的测试是发现了至今未发现的错误的测试
![]()
软件测试和软件开发的关系
在V模型中,软件测试活动和项目同时启动,软件测试的工作很早就开始了,避免了瀑布模型所带来的误区—软件测试是在代码完成之后进行。V模型相对准确地反映测试与开发之间的关系:
左边是软件定义和实现的过程(包括分析、设计和编程),右边是对左边所构造的东西进行验证的过程,测试与开发有一对一的关系。测试的工作(右边)是对开发工作(左边) 成果的检验,以确认是否满足事先的定义和要求。
![]()
软件测试与SQA(软件质量保证)的关系
联系
区别
四种导向
五大学派
任何程序、系统中的问题,和产品设计书的不一致性,不能满足用户的需求。

在设计阶段就是它的3~6倍,在编程阶段是它的10倍,在内部测试阶段是它的20~40倍,在外部测试阶段是它的30~70倍,而到了产品发布出去时,这个数字就是40~100倍,修正错误的代价不是随时间线性增长,而几乎是呈指数增长的。
静态测试包括对软件产品的需求和设计规格说明书的评审、 对程序代码的审査以及静态分析等。并不需要对代码进行编译和仿真运行。
动态测试是通过真正运行程序发现错误,通过观察代码运行过程,来获取系统行为、变量实时结果、内存、堆栈、线程以及测试覆盖度等各方面的信息,来判断系统是否存在问题,或者通过有效的测试用例,对应的输人输出关系来分析被测程序的运行情况,来发现缺陷。
也称负载测试,用来检查系统在不同负载(如数据量、并发用户、连接数等)条件下的系统运行情况,特别是高负载、极限负载下的系统运行情况,以发现系统不稳定、系统性能瓶颈、内存泄漏、CPU使用率过高等问题。
| 基于脚本的测试执行(ST) | 探索式测试(ET) |
|---|---|
| 系统性强 | 自由灵活 |
| 容易管理、控制 | 适应性强,和ST是互补的 |
| 设计在先,执行在后 | 执行和设计(思考)并行 |
| 主要是验证自己的思路 | 不断和系统交互,带着问题测试 |
| 可预见性 | 学习的过程,强调个人能力 |
软件测试工作的组织与管理:制定测试策略、测试计划,确认所采用的测试方法与规范,控制测试进度,管理测试资源。
测试工作的实施:编制符合标准的测试文档,搭建测试环境,开发测试脚本、与开发组织协作实现各阶段的测试活动。
按照程序内部的结构测试程序,通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行,检验程序中的每条通路是否都能按预定要求正确工作。
黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。黑盒测试着眼于程序外部结构,不考虑内部逻辑结构,主要针对软件界面和软件功能进行测试。
为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求,被称为有效地发现软件缺陷的最小测试执行单元。
测试用例测试用例是软件测试的核心,构成了设计和制定测试过程的基础。
TMMi呈现的是一个过程改进的阶段型架构。它包括阶段或级别,组织可以通过它们使测试过程从临时的和未管理的状态进化为已管理、已定义、已测量和优化的状态。在TMMi中有5个级别,规定了
成熟度级别和测试过程改进的路径。每个级别都有一组过程域,组织需要实施这些过程域来达到对应的成熟度级别。
- TMMi1级—初始
- TMMi2级—已管理
- TMMi3级—已定义
- TMMi4级—已测量
- TMMi5级—优化
过程能力描述了遵循一个软件测试过程可能达到的预期结果的范围。TMM的建立,得益于以下3点:
TPI是基于连续性表示法的测试过程改进的参考模型,是在软件控制、测试知识以及过往经验的基础上开发出来的。
关键测试过程(Critical Test Process,CTP)评估模型主要是一个内容参考模型,一个上下文相关的方法,并能对模型进行裁剪。
使用 CTP 的过程改进,始于对现有测试过程的评估, 通过评估以识别过程的强弱,并结合组织的需要提供改进的意见。
STEP(Systematic Test and Evaluation Process,系统化测试和评估过程)是一个内容参考模型,认定测试是一个生命周期活动,在明确需求后开始直到系统退役。
单元测试:单元测试是对软件基本组成单元(如函数、类的方法等)进行的测试
单元测试的测试人员:程序人员和开发人员
时机:一般在代码完成后由开发人员完成,QA(质量保证)人员辅助。
模块和组件都是系统的组成部分,只是从不同的角度拆分系统而已。
从逻辑的角度来拆分系统后,得到的单元就是
模块划分模块的主要目的是职责分离
从物理的角度来拆分系统后,得到的单元就是
组件划分组件的主要目的是单元复用。
软件需求规格说明书
软件详细设计说明书
主要目标:检验各单元模块是否被正确地编码
需要验证以下内容:
流入和流出单元。集成测试:集成测试是将软件集成起来,对模块之间的接口进行测试。
顾名思义,集成测试是将软件集成起来后进行测试。集成测试又叫子系统测试、组装测试、部件测试等。
模块内的集成,主要是测试模块内各个接口间的交互集成关系
子系统内的集成,测试子系统内各个模块间的交互关系
系统内的集成,测试系统内各个子系统和模块间的集成关系
集成测试的测试人员:有经验的测试人员和开发者共同
非渐增式测试模式:先分别测试每个模块,再把所有模块按设计要求放在一起结合成所要的程序,如大棒模式。
渐增式测试模式:把下一个要测试的模块同已经测试好的模块结合进来进行测试,测试完后再把下一个应该测试的模块结合起来测试。渐增式测试又可以根据每次添加模块的路线分为自顶向下测试、自底向上测试和混合测试等方式。
自顶向下:从主控模块开始,沿着软件的控制层次向下移动,从而逐渐把各个模块结合起来。在集成过程中,可以使用深度优先的策略或宽度优先的策略。
自底向上:从“原子”模块( 即在软件结构最底层的模块) 开始集成以进行测试。
混合策略:在具体测试中,可采用混合策略,即结合上述的两种方法逐步实施集成测试。
驱动程序
用于模拟被测模块的上级模块,能够调用被测模块,驱动模块接受测试数据,调用被测模块并把相关数据传送给被测模块。桩程序
用于模拟被测模块工作过程中所调用的下层模块,一般很少进行数据处理,一般只检测被测模块传输数据的正确性。
软件概要设计说明书软件详细设计说明书
集成测试,也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。实践表明,一些模块虽然能够单独地工作,但并不能保证连接起来也能正常的工作。程序在某些局部反映不出来的问题,在全局上很可能暴露出来,影响功能的实现。
目标在于检验与软件设计相关的程序结构问题。如数据穿过接口时可能丢失;一个模块与另一个模块可能有由于疏忽的问题而造成有害影响; 把子功能组合起来可能不产生预期的主功能;个别看起来是可以接受的误差可能积累到不能接受的程度;全程数据结构可能有错误等。
检验系统所有元素之间协作是否合适,整个系统的性能和功能是否达到要求。其测试内容包括:功能测试,非功能测试与回归测试等。
功能测试:根据产品规格说明书,来检验被测试的系统是否满足各方面功能的使用要求
非功能性测试包含:性能测试、压力测试、容量测试、安全性测试、可靠性测试、容错性测试
回归测试:在程序有修改的情况下保证原有功能正常
系统测试的测试人员:软件测试工程师
软件需求规格说明书软件概要设计说明书 软件详细设计说明书
确认测试又称有效性测试。有效性测试是在模拟的环境下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。
任务是验证软件的功能和性能及其他特性是否与用户的要求一致。对软件的功能和性能要求在软件需求规格说明书中已经明确规定,它包含的信息就是软件确认测试的基础。
验收测试:检查软件是否符合合同要求,包括需求规格说明、设计规格说明和用户手册等。
测试内容:
易用性测试(用户界面和可用性测试)
兼容性测试(软件兼容性测试、数据共享兼容性测试、硬件兼容性测试)
安装测试和可恢复性测试(安装与卸载测试、可恢复性测试)
文档测试(正确性、完备性、易理解性、一致性)
测试人员:用户和测试部门共同完成
测试依据: 国家规范、行业标准、合同条款、用户确认的需求规格说明书
α测试是指软件开发公司组织内部人员模拟各类用户行对即将面市软件产品(称为α版本)进行测试,试图发现错误并修正。
经过α测试调整的软件产品称为β版本。紧随其后的β测试是指软件开发公司组织各方面的典型用户在日常工作中实际使用β版本,并要求用户报告异常情况、提出批评意见。然后软件开发公司再对β版本进行改错和完善。
I18N是借助功能设计和代码实现中软件系统有能力处理多种语言和不同文化,使创建不同语言版本时,不需要重新编写代码的软件工程方法。
L10N是将一个软件产品按特定国家/地区或语言市场的需要进行加工,使之满足特定市场上的用户对语言和文化的特殊要求的软件生产活动。
G11N = I18N + L10N
自动化测试是相对手工测试而存在的一个概念,由手工逐个地运行测试用例的操作过程被测试工具自动执行的过程所代替。
| 手工测试 | 自动化测试 |
|---|---|
| 发现缺陷率高 | 难以发现缺陷 |
| 重复测试效率低 | 高效率、高复用性 |
| 不一致性、可靠性低 | 准确、可靠 |
| 依赖人力资源 | 不知疲劳,激励团队士气 |
| 覆盖率量化困难 | 覆盖率容易度量 |
| 创造性、灵活性 | 机械 |
| 容易实施 | 一次性投入大 |
类似于高级编译系统,在工具中定义类/对象/函数/变量等定义规则、语法规则等,在分析时对代码进行语法扫描,找出不符合编码规范的地方。
测试工具能够实现对用户界面的操作,要么就按照屏幕的实际像素坐标来定位,要么通过寻找UI上的对象(如窗口、按钮 、滚动条等)来确定操作的目标.
脚本的技术围绕着脚本的结构设计, 实现测试用例。
自动执行测试脚本时,预期输出是事先定义的或插人脚本中,然后在测试过程中运行脚本,将捕获的结果和预先准备的输出进行比较,从而确定测试用例是否通过。
在大规模的自动化测试过程中,需要调度、控制多台测试机器进行协助工作,还需要特定的服务器用于存储和管理测试任务、测试脚本和测试结果。
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
我有:When/^(?:|I)follow"([^"]*)"(?:within"([^"]*)")?$/do|link,selector|with_scope(selector)doclick_link(link)endend我打电话的地方:Background:GivenIamanexistingadminuserWhenIfollow"CLIENTS"我的HTML是这样的:CLIENTS我一直收到这个错误:.F-.F--U-----U(::)failedsteps(::)nolinkwithtitle,idortext'CLIENTS'found(Capybara::Element