-
【摘自zxy_yocky的日志】软件测试新手应看的一些东西!
2008-10-10 15:16:49
1、Q:给测试新手的建议和指导
A:
http://bbs.51testing.com/viewthread.php?tid=34811http://bbs.51testing.com/thread-10675-1-1.html
2、Q:测试工程师流程、入门、经验介绍
A:
http://bbs.51testing.com/viewthread.php?tid=96652&highlight=%B2%E2%CA%D4%B9%A4%B3%CC%CA%A6%B9%A4%D7%F7%C1%F7%B3%CC%B8%C5%C2%DB3、Q:软件测试基本概念和分类
A:http://bbs.51testing.com/viewthread.php?tid=6384、Q:软件测试书籍列表:
A:http://bbs.51testing.com/viewthread.php?tid=12727&highlight=%C8%ED%BC%FE%B2%E2%CA%D4%CA%E9%BC%AE%C1%D0%B1%ED5、Q:单元测试概念
A:http://bbs.51testing.com/viewthread.php?tid=17555&highlight=%C9%EE%C8%EB%C7%B3%B3%F6%B5%A5%D4%AA%B2%E2%CA%D4
6、Q:软件测试常识
A: http://bbs.51testing.com/search.php?searchid=207&orderby=dateline&ascdesc=desc&searchsubmit=yes
http://bbs.51testing.com/viewthread.php?tid=34810&highlight=%C8%ED%BC%FE%B2%E2%CA%D4%BB%F9%B1%BE%C4%DA%C8%DD
7、Q:安装与卸载测试
A:http://bbs.51testing.com/search.php?searchid=219&orderby=dateline&ascdesc=desc&searchsubmit=yes
8、黑盒测试的测试用例设计方法之等价类划分
A:http://bbs.51testing.com/viewthread.php?tid=4434&highlight=%BA%DA%BA%D0%B2%E2%CA%D410、Q:如何设计编制软件测试用例
A:http://bbs.51testing.com/viewthread.php?tid=2269&highlight=%C8%E7%BA%CE%C9%E8%BC%C6%B1%E0%D6%C6%C8%ED%BC%FE%B2%E2%CA%D4%D3%C3%C0%FD
11、Q:测试设计中需要考虑的测试类型
A:
http://bbs.51testing.com/viewthread.php?tid=3407&highlight=%B2%E2%CA%D4%C9%E8%BC%C6%D6%D0%D0%E8%D2%AA%BF%BC%C2%C7%B5%C422%D6%D6%B2%E2%CA%D4%C0%E0%D0%CD12、Q:测试工具大全[转帖]仅供参考
A:
http://bbs.51testing.com/viewthread.php?tid=525&highlight=%D7%D4%B6%AF%BB%AF%B2%E2%CA%D4%CA%C7%D2%A3%B2%BB%BF%C9%BC%B0%B5%C4%A3%BF -
QTP的一些小知识【转载】
2008-10-13 11:28:39
1.GetCellData函数
作用:获取单元格的值
例: rowCount = Browser("xxx ").Page("xxx ").Frame("xxx").WebTable("xxx").RowCount
'y?6P6o&u4O Q218905For counter = 1 To rowCount51Testing软件测试网u%W9\afj @'^W
text = Browser("xxx").Page("xxx").Frame("xxx").WebTable("xxx").GetCellData(counter,1)
D"fM^3S^k-DO218905 If (text = "xxx") Then
Vl H$uwhF]218905 counter = counter - 151Testing软件测试网2W&e4M)? A
selectNO = "#" & counter51Testing软件测试网WwHoL(@ C
Browser("xxx").Page("xxx").Frame("xxx").WebRadioGroup("xxx").Select selectNO51Testing软件测试网Q;PIL&{+AM3{
Exit For
mhd9];O s2V*Zw218905 End If51Testing软件测试网*Ee3S|&P.KMC
Next2.把值插入datatable里
例: datatable.setcurrentrow(i) 51Testing软件测试网 K$UG7t/vs'`X!l/w
datatable.value("name","Global")="name"
I9v*O%hUo218905 datatable.value("passwd","Global")="passwd"3.用代码来启动浏览器
Browser1 = "IE"
V5]f6w+N6X"W;c6g218905 StartURL = "www.51testing.com"51Testing软件测试网.tW.`3NF,Ch
IF Browser1 = "IE" THEN
_Na2QO&L*{!X218905 set IE = CreateObject("InternetExplorer.Application")51Testing软件测试网k9DLs"}x+hl
IE.Visible = true51Testing软件测试网*~[+O a%B1cC
IE.Navigate StartURL
._9z&ibG6J4b:t218905 END IF
g"n-n:R X"VeR Z2189054.ExecuteFile函数
作用:ExecuteFile 可以直接执行vbs文件,而不需要将其导入resource中
%?z/a$M;A3M n218905 ExecuteFile FileName
3TM-d%H P ^.^v218905 说明:where FileName is the absolute or relative path of your VBscrīpt file.例:ExecuteFile("F:\test.vbs")
5.Strcomp函数
作用:比较文本
例:dim strtext1,strtext2,str ,str1,comp151Testing软件测试网4l6BU XLvnG
strtext1 = "xxx"
%pCG6M]k218905 strtext2 = "xxx"51Testing软件测试网qZ0X9{\
str = VbWindow("xxx").VbWindow("xxx").VbLabe1("xxx").GetTOProperty("text")
:Y3G6o$hx4U218905 str1= VbWindow("xxx").VbWindow("xxx").VbLabel("xxx").GetTOProperty("text")51Testing软件测试网4{0b(J l&Lng|aG
comp1=strcomp(strtext1,str,0)51Testing软件测试网W:lu&g U:^ tcU
If comp=0 Then
"D@Y)?/DL/bm218905 msgbox “这两个串相等”
1PY!z1\-DpB218905 else
~0L2p"GEM218905 msgbox str51Testing软件测试网OCt |'Oko5B(JA0^#G$^
End If6.CaptureBitmap
作用:捕获屏幕
7. GetROProperty
作用:取对象属性值
例:VbWindow("xxx").VbWindow("xxx").VbWindow("xxx").ActiveX("xxx").GetROProperty("TextMatrix(1,0)")
8.ExitAction - 退出当前操作,无论其循环属性如何。51Testing软件测试网!{0Wu8niP3U
ExitActionIteration - 退出操作的当前循环。
J g Q"T2HV+x4U218905 ExitRun - 退出测试,无论其循环属性如何。51Testing软件测试网q{|p#jx
ExitGlobalIteration - 退出当前全局循环。51Testing软件测试网[9l;L+X(E)r Dh
9.如何使用Excel对象处理数据? 51Testing软件测试网g.II b5?*?.[TY^
Dim xl51Testing软件测试网 @6[oe O-]'Lb
打开excel文件
Zm3M-kymIs218905 Function OpenExcelFile(strFilePath)51Testing软件测试网W7d6z{(r pOs T
Set xl = CreateObject("Excel.Application")51Testing软件测试网d:rY)iN^8V9A
xl.Workbooks.Open strFilePath51Testing软件测试网 Ot de1yV&H#J g6L
End Function51Testing软件测试网2a B}C;n'M
获得指定单元格数据
%IXg,a;[s4eY U218905 Function GetCellData(strSheet,rwIndex,colIndex)51Testing软件测试网z/dv#]`%UP0S7x
GetCellData = xl.WorkSheets(strSheet).Cells(rwIndex,colIndex)51Testing软件测试网ZA&x"k q0]*~
End Function
J ^JOu)V218905 填充单元格数据
dz C1RZf7?%B`218905 Function PutCellData(strSheet,rwIndex,colIndex,varData)
R0n)^&\0Q218905 xl.WorkSheets(strSheet).Cells(rwIndex,colIndex) = varData
4i yd*K]218905 End Function51Testing软件测试网5R5A~FRCg[.@dm
保存并推出51Testing软件测试网!Q&NR9`-o7n ^~
Function SaveAndQuit()
l a ^ U2E4V@-U&h218905 xl.Activeworkbook.save51Testing软件测试网K0_OdFDX*PZ
xl.Quit
4S1X qWE218905 Set xl = nothing51Testing软件测试网7C;Jj-Q1Pr]
End Function51Testing软件测试网 j&N.GJ7@C;Y _10.连接sql数据库
例:Dim res,cmd,sql51Testing软件测试网kgQPlL7Ox+v
Set Res=createobject("adodb.recordset")51Testing软件测试网9e*x(I gel8m
Set Cmd=createobject("adodb.command")51Testing软件测试网 Uw3QI ue
Cmd.activeconnection="Provider=SQLOLEDB.1;Password=111111;Persist Security Info=True;User ID=sa;Initial Catalog=xhq;Data Source=192.168.191.142" '这句话是连接数据库的数据源,要做修改
S9])Pj)O9pdF218905 Cmd.CommandType = 1
~]$T_{7xF!}218905 sql="selec t * from 表 where name=username"
R|0K7} O ~218905 Cmd.CommandText = sql51Testing软件测试网1TP'PQw&H4X
Set res = Cmd.Execute()
bTv,c;`218905 Set res = nothing51Testing软件测试网IDJ8@5P&in6ap;a
Set cmd.ActiveConnection = nothing
;_q DGU K7x\218905 Set Cmd= nothing -
【转载】学习QTP三部曲
2008-10-13 11:27:44
循序渐进学习QTP--初级篇
6}8K_ ai'F65054 我们使用QTP的目的是想用它来执行重复的手动测试,主要是用于回归测试和测试同一软件的新版本。因此你在测试前要考虑好如何对应用程序进行测试,例如要测试那些功能、操作步骤、输入数据和期望的输出数据等。
O+BN(i2e9U65054 强烈建议你按照版主oldsidney 写的 Tutorial_oldsidney_cn.pdf 文件来认认真真、从头到尾地执行一遍,包括录制脚本、分析脚本、增加check point、Split Action等。我想这会减少你在学习QTP过程中的不少困惑和疑虑。51Testing软件测试网~c$?"T;qS#LG
这篇文档对如何使用QTP写的非常详细,是QTP初学者的经典教材。我就是看了这篇文档后才对QTP的整个测试流程有了一个初步的认识。在此,我对oldsidney表示感谢。51Testing软件测试网4x NU x$z[%y
注意:51Testing软件测试网 f4rS T$GpKe
1,确保你的IE运行正常,依次点击菜单 查看 --> 工具栏,一定要上网助手等插件卸载掉,特别3721这个垃圾网站和其它拦截广告的插件(它也把测试过程中弹出的窗口当成广告,一样会拦截的!)!
9rhFU u;~!~;J_/V65054 2,如果是按照Tutorial_oldsidney_cn.pdf 文件 中的订购飞机票的例子来练习 QTP的使用,那么只需选择Web 插件就可以了。如果是测试其它的应用程序或系统,就要根据需要来选择相应的插件了。循序渐进学习QTP---中级篇
在这个阶段你就要自己针对某个系统去录制脚本、维护脚本了。在录制后的回放过程中,你可能会遇到各种问题,这个时候就需要发挥你的主观能动性来解决遇到的问题。我想你可以按照下面的方法去解决:51Testing软件测试网3~-g@1Bc.zFb%g;R
~6|U,xuV9k y L65054 1,查看QTP的有关文档,包括Help 、QTP User’s Guide等文档。这些都是比较系统全面的学习材料。你该好好利用呀。
O.G4f9N3d j&{65054 2,在本论坛上查看以前别人是如何解决此类问题的(如果有的话)或者是发新贴寻求帮助,也可以搜索Google 等网站寻找问题的解决方法;51Testing软件测试网)u0h.MR4IZ
3,与自己部门的同事交流,例如与测试人员交流他们是如何解决的,与开发人员交流某个QTP无法识别的控件具体是用什么属性来识别的等。毕竟他们对测试的环境和测试的软件比论坛上的人熟悉呀。51Testing软件测试网3c1}G6UU _6K&iI
4,自己通过学习VBscrīpt 等方式来提高自己的管理QTP scrīpt的能力。
f N9U"p-V:o6505451Testing软件测试网%^R,T]cg~bT
或许你会发现许多问题都是由提出问题的人来解决的,因为他们希望问题得到解决的迫切心比谁都强烈。循序渐进学习QTP---高阶篇
如果你对VB scrīpt 、QTP和需要测试的程序或系统非常熟悉,你可能就想直接写QTP scrīpt来表现一下了。如果你能达到这个水平,那么恭喜你---你就是真正的高手了。这个时候你已经可以从宏观上把握QTP了,也能灵活自如地使用QTP了。51Testing软件测试网*V2|zb7w_)pI -
如何用QTP解决图片验证码(解析QuickTest文本识别机制)?【转】
2008-10-13 11:27:14
大家在使用QTP进行自动化测试的过程中经常会遇到图片验证码的问题——大家所关心的就是如何解决此类问题。51Testing软件测试网4Xi0[3b;g` h
这里我们首先要去了解为什么会有图片验证码。其实验证码的本质作用就是防止有人利用工具(灌水机、注册机,当然也不小心包括了我们的自动化测试工具)恶意猜解登陆或者不停的注册和灌水的。因此如果我们完全寄希望于通过GUI识别来获取内容是不切实际的——先打好预防针,免得读者希望太大,失望更大,呵呵!
ls6M%w;q65054 下面说说验证码的解决思路:
h8A*Rod65054 其实解决图片验证码的思路有很多,我这里主要结合QTP9.5的新特性给大家介绍其中一种解决方案,就是利用它的OCR机制抓取文本内容。
|/H^3S.b.M-AT65054 在QTP9.5中,对象识别能力有了进一步改善,其中针对文本识别方面进行了优化,引入了ABBYY公司的OCR解决方案——这个相关的功能体现在QTP菜单的“Tools-->Options-->General--Use text recognition mechanisms in this order”里,详细内容后面会有具体介绍。51Testing软件测试网,W\3Y0a^l
先来看看ABBYY是何许公司,登录他们的官方网站可以看到一段相关介绍:“ABBYY是世界OCR(光学字符识别)、ICR(手写体识别)和语言软件的领航者。ABBYY 致力于人工智能(AI)和语言软件开发。提供全套文档识别,转换和数据捕获技术的产品解决方案。”如果你使用过图像文档转换的软件,一定会听说过FineReader OCR Professional ,其实它就是ABBYY公司的产品,用官方的说法就是“将通过扫描仪、MFP 或数码相机生成的图像快速转换为可编辑和可搜索的电子格式,而且识别率很高”,说白了就是可以借助它先进的OCR机制“读”出图片里的文本内容,并转换为PDF之类的文档。51Testing软件测试网3LI FU2iR
有了ABBYY这么强大的背后支持,QTP自然底气十足,那么QTP到底如何以OCR机制识别文本呢?我们首先先了解一下什么是OCR。
-T4w_H3T65054 打开“百度百科_OCR”,它的说明:“OCR(Optical Character Recognition,光学字符识别),是属于图型识别(Pattern Recognition,PR)的一门学问。其目的就是要让计算机知道它到底看到了什么,尤其是文字资料。 由于OCR是一门与识别率拔河的技术,因此如何除错或利用辅助信息提高识别正确率,是OCR最重要的课题,ICR(Intelligent Character Recognition)的名词也因此而产生。而根据文字资料存在的媒体介质不同,及取得这些资料的方式不同,就衍生出各式各样、各种不同的应用。”这里有个关键词:“正确率”,也就是“识别率”——既然不能够总是100%,我们自然不可能完全寄希望于通过QTP能够每次100%正确的去识别图片里的文本。尤其是“道高一尺魔高一丈”的今天,验证码加入了大量的干扰素,如扭曲、变形、错位、随机背景花纹,给OCR识别增加了很多难度——本来就不希望被软件识别到嘛。51Testing软件测试网8M LB~[
'FT7G7@XtNCL-~%q65054 了解了OCR之后,我们再来看看QTP对应的这个设置。如前面所说,通过QTP菜单的“Tools-->Options”选中到“General--Use text recognition mechanisms in this order”,这里的四个选项就是对应的不同设置。我们看看帮助的描述(我做了翻译):
1E5FYFU[J"Z65054 =================================
k/t0wAWy6lK65054 使用文本识别机制
Y(WZ e[3l5b ? `I65054 51Testing软件测试网`3~tTN}
指定QTP在采用 “文本”或者“文本区域” 的 检查点或输出值 的步骤时,捕获文本内容所使用的文本识别机制。
bty O:mi }65054 以下有三种识别方式:51Testing软件测试网]%Yx(t'Z#[F%\*nUB
1、先使用Windows API,再使用OCR(默认)。
[ j[$sH(j65054 指示QTP首先尝试以基于Windows API的机制从对象上直接获取文本内容。如果未获取到文本(比如,文本属于图片的一部分),QTP就会使用OCR的机制尝试获取这段文本。
7H(X2EDQ$YF*Et65054 强烈建议在使用中日韩(象形文字)、英的语言环境下采用这个设置。
L!U V^:e7R3Xp;l,cOu65054
CR,E~G'Q[65054 2、先使用OCR,再使用Windows API。
;r-b5C4`#Q&U9]2b8A%x65054 指示QTP首先尝试使用OCR机制从对象上去获取文本。如果未获取到文本,QTP就会以Windows API的机制去获取文本内容。51Testing软件测试网%R[Pv_
-E T6C8yze65054 3、仅使用Windows API方式。51Testing软件测试网p2G8[:sg(R]4l
指示QTP仅采用基于Windows API的机制从对象上获取文本内容。51Testing软件测试网![4K2r9v9Rj Le6u'K@
h@[)N)h\[65054 4、仅使用OCR的方式。
P G)WX~a5r:^ H65054 指示QTP仅采用基于OCR的机制从对象上获取文本内容。51Testing软件测试网jPQLs\
在使用Windows Vista要使用这种方式。
S'N {c2uU)L65054
4TnQh6}w65054 =================================
6U9s7b6J*U)|[l K65054 上面的内容已经解释的很明确了,接下来我们通过TextArea Output Value看看效果。51Testing软件测试网 xf;\/DQ
51Testing软件测试网+s,V8igtRb
如下图所示,QTP针对几张图片的识别效果:51Testing软件测试网8w-[ X&h,S g
(一)、内容是51Testing的,QTP获取正确;内容是51Testing的G风格彩字,QTP获取错误(显示为IC_CHECK_PATTERN)51Testing软件测试网`%vG9}Zs[ `O.w
51Testing软件测试网zz k+K;N'[
51Testing软件测试网0dv }_f$FKE
51Testing软件测试网vw+n"d%~L;w kj ]
(二)、内容是songfun的普通文本,QTP获取正确;内容是songfun的G风格彩字,QTP获取错误(也显示为IC_CHECK_PATTERN)
ek ??sO6F$aSK65054 51Testing软件测试网!dN?srX Q F
)b2E]va F.q65054
D5AY3Pa*Ni7cJ`65054 51Testing软件测试网R\BHi2wJM
有兴趣大家可以自己做一些图片,甚至可以用QQ的验证码图片来试验一下,看看OCR效果。 -
集成测试[转]
2008-10-13 09:30:42
集成测试(也叫组装测试,联合测试)是单元测试的逻辑扩展。它的最简单的形式是:两个已经测试过的单元组合成一个组件,并且测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合成程序的更大部分。方法是测试片段的组合,并最终扩展进程,将您的模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。此外,如果程序由多个进程组成,应该成对测试它们,而不是同时测试所有进程。集成测试识别组合单元时出现的问题。通过使用要求在组合单元前测试每个单元并确保每个单元的生存能力的测试计划,可以知道在组合单元时所发现的任何错误很可能与单元之间的接口有关。这种方法将可能发生的情况数量减少到更简单的分析级别。
集成测试是在单元测试的基础上,测试在将所有的软件单元按照概要设计规格说明的要求组装成模块、子系统或系统的过程中各部分工作是否达到或实现相应技术指标及要求的活动。也就是说,在集成测试之前,单元测试应该已经完成,集成测试中所使用的对象应该是已经经过单元测试的软件单元。这一点很重要,因为如果不经过单元测试,那么集成测试的效果将会受到很大影响,并且会大幅增加软件单元代码纠错的代价。
集成测试是单元测试的逻辑扩展。在现实方案中,集成是指多个单元的聚合,许多单元组合成模块,而这些模块又聚合成程序的更大部分,如分系统或系统。集成测试采用的方法是测试软件单元的组合能否正常工作,以及与其他组的模块能否集成起来工作。最后,还要测试构成系统的所有模块组合能否正常工作。集成测试所持的主要标准是《软件概要设计规格说明》,任何不符合该说明的程序模块行为都应该加以记载并上报。
所有的软件项目都不能摆脱系统集成这个阶段。不管采用什么开发模式,具体的开发工作总得从一个一个的软件单元做起,软件单元只有经过集成才能形成一个有机的整体。具体的集成过程可能是显性的也可能是隐性的。只要有集成,总是会出现一些常见问题,工程实践中,几乎不存在软件单元组装过程中不出任何问题的情况。从图1可以看出,集成测试需要花费的时间远远超过单元测试,直接从单元测试过渡到系统测试是极不妥当的做法。
集成测试的必要性还在于一些模块虽然能够单独地工作,但并不能保证连接起来也能正常工作。程序在某些局部反映不出来的问题,有可能在全局上会暴露出来,影响功能的实现。此外,在某些开发模式中,如迭代式开发,设计和实现是迭代进行的。在这种情况下,集成测试的意义还在于它能间接地验证概要设计是否具有可行性。
集成测试的目的是确保各单元组合在一起后能够按既定意图协作运行,并确保增量的行为正确。它所测试的内容包括单元间的接口以及集成后的功能。使用黑盒测试方法测试集成的功能。并且对以前的集成进行回归测试。
一、集成测试过程
二、单元测试工作内容及其流程
三、集成测试需求获取
集成测试需求所确定的是对某一集成工作版本的测试的内容,即测试的具体对象。集成测试需求主要来源于设计模型(Design Model)和集成构件计划(Integration Build Plan)。集成测试着重于集成版本的外部接口的行为。因此,测试需求须具有可观测、可测评性。
1. 集成工作版本应分析其类协作与消息序列,从而找出该工作版本的外部接口。
2. 由集成工作版本的外部接口确定集成测试用例。
3. 测试用例应覆盖工作版本每一外部接口的所有消息流序列。
注意:一个外部接口和测试用例的关系是多对多,部分集成工作版本的测试需求可映射到系统测试需求,因此对这些集成测试用例可采用重用系统测试用例技术。
四、集成测试工作机制
软件集成测试工作由产品评测部担任。需要项目组相关角色配合完成。如图示:
软件评测部:
软件项目组:
集成测试工作内容及其流程工作流程:
五、集成测试产生的工件清单
1、 软件集成测试计划
2、 集成测试用例
3、 测试过程
4、 测试脚本
5、 测试日志
6、 测试评估摘要六、集成测试常用方案选型
集成测试的实施方案有很多种,如自底向上集成测试、自顶向下集成测试、Big-Bang集成测试、三明治集成测试、核心集成测试、分层集成测试、基于使用的集成测试等。在此,笔者将重点讨论其中一些经实践检验和一些证实有效的集成测试方案。
·自底向上集成测试
自底向上的集成(Bottom-Up Integration)方式是最常使用的方法。其他集成方法都或多或少地继承、吸收了这种集成方式的思想。自底向上集成方式从程序模块结构中最底层的模块开始组装和测试。因为模块是自底向上进行组装的,对于一个给定层次的模块,它的子模块(包括子模块的所有下属模块)事前已经完成组装并经过测试,所以不再需要编制桩模块(一种能模拟真实模块,给待测模块提供调用接口或数据的测试用软件模块)。自底向上集成测试的步骤大致如下:
步骤一: 按照概要设计规格说明,明确有哪些被测模块。在熟悉被测模块性质的基础上对被测模块进行分层,在同一层次上的测试可以并行进行,然后排出测试活动的先后关系,制定测试进度计划。图2给出了自底向上的集成测试过程中各测试活动的拓扑关系。利用图论的相关知识,可以排出各活动之间的时间序列关系,处于同一层次的测试活动可以同时进行,而不会相互影响。
步骤二: 在步骤一的基础上,按时间线序关系,将软件单元集成为模块,并测试在集成过程中出现的问题。这里,可能需要测试人员开发一些驱动模块来驱动集成活动中形成的被测模块。对于比较大的模块,可以先将其中的某几个软件单元集成为子模块,然后再集成为一个较大的模块。
步骤三: 将各软件模块集成为子系统(或分系统)。检测各自子系统是否能正常工作。同样,可能需要测试人员开发少量的驱动模块来驱动被测子系统。
步骤四: 将各子系统集成为最终用户系统,测试是否存在各分系统能否在最终用户系统中正常工作。
方案点评: 自底向上的集成测试方案是工程实践中最常用的测试方法。相关技术也较为成熟。它的优点很明显: 管理方便、测试人员能较好地锁定软件故障所在位置。但它对于某些开发模式不适用,如使用XP开发方法,它会要求测试人员在全部软件单元实现之前完成核心软件部件的集成测试。尽管如此,自底向上的集成测试方法仍不失为一个可供参考的集成测试方案。
·核心系统先行集成测试
核心系统先行集成测试法的思想是先对核心软件部件进行集成测试,在测试通过的基础上再按各外围软件部件的重要程度逐个集成到核心系统中。每次加入一个外围软件部件都产生一个产品基线,直至最后形成稳定的软件产品。核心系统先行集成测试法对应的集成过程是一个逐渐趋于闭合的螺旋形曲线,代表产品逐步定型的过程。其步骤如下:
步骤一: 对核心系统中的每个模块进行单独的、充分的测试,必要时使用驱动模块和桩模块;
步骤二: 对于核心系统中的所有模块一次性集合到被测系统中,解决集成中出现的各类问题。在核心系统规模相对较大的情况下,也可以按照自底向上的步骤,集成核心系统的各组成模块。
步骤三: 按照各外围软件部件的重要程度以及模块间的相互制约关系,拟定外围软件部件集成到核心系统中的顺序方案。方案经评审以后,即可进行外围软件部件的集成。
步骤四: 在外围软件部件添加到核心系统以前,外围软件部件应先完成内部的模块级集成测试。
步骤五: 按顺序不断加入外围软件部件,排除外围软件部件集成中出现的问题,形成最终的用户系统。
方案点评: 该集成测试方法对于快速软件开发很有效果,适合较复杂系统的集成测试,能保证一些重要的功能和服务的实现。缺点是采用此法的系统一般应能明确区分核心软件部件和外围软件部件,核心软件部件应具有较高的耦合度,外围软件部件内部也应具有较高的耦合度,但各外围软件部件之间应具有较低的耦合度。
·高频集成测试
高频集成测试是指同步于软件开发过程,每隔一段时间对开发团队的现有代码进行一次集成测试。如某些自动化集成测试工具能实现每日深夜对开发团队的现有代码进行一次集成测试,然后将测试结果发到各开发人员的电子邮箱中。该集成测试方法频繁地将新代码加入到一个已经稳定的基线中,以免集成故障难以发现,同时控制可能出现的基线偏差。使用高频集成测试需要具备一定的条件: 可以持续获得一个稳定的增量,并且该增量内部已被验证没有问题; 大部分有意义的功能增加可以在一个相对稳定的时间间隔(如每个工作日)内获得; 测试包和代码的开发工作必须是并行进行的,并且需要版本控制工具来保证始终维护的是测试脚本和代码的最新版本; 必须借助于使用自动化工具来完成。高频集成一个显著的特点就是集成次数频繁,显然,人工的方法是不胜任的。
高频集成测试一般采用如下步骤来完成:
步骤一: 选择集成测试自动化工具。如很多Java项目采用Junit+Ant方案来实现集成测试的自动化,也有一些商业集成测试工具可供选择。
步骤二: 设置版本控制工具,以确保集成测试自动化工具所获得的版本是最新版本。如使用CVS进行版本控制。
步骤三: 测试人员和开发人员负责编写对应程序代码的测试脚本。
步骤四: 设置自动化集成测试工具,每隔一段时间对配置管理库的新添加的代码进行自动化的集成测试,并将测试报告汇报给开发人员和测试人员。
步骤五: 测试人员监督代码开发人员及时关闭不合格项。
按照步骤三至步骤五不断循环,直至形成最终软件产品。
方案点评: 该测试方案能在开发过程中及时发现代码错误,能直观地看到开发团队的有效工程进度。在此方案中,开发维护源代码与开发维护软件测试包被赋予了同等的重要性,这对有效防止错误、及时纠正错误都很有帮助。该方案的缺点在于测试包有时候可能不能暴露深层次的编码错误和图形界面错误。
以上我们介绍了几种常见的集成测试方案,一般来讲,在现代复杂软件项目集成测试过程中,通常采用核心系统先行集成测试和高频集成测试相结合的方式进行,自底向上的集成测试方案在采用传统瀑布式开发模式的软件项目集成过程中较为常见。读者应该结合项目的实际工程环境及各测试方案适用的范围进行合理的选型。
附:集成测试计划书 模版原创作者:jerry
转载请注明:来自Sawin系统分析之窗
最后修改时间:2005-4-271引言
1.1编写目的
本文是描述****集成测试的大纲文章,主要描述如何进行集成测试活动?如何控制集成测试活动?集成测试活动的流程以及集成测试活动的工作安排。本文主要的读者对象是项目负责人,集成部门经理,集成测试设计师。
1.2背景
项目名称:***集成测试
项目相关对象:******************
1.3定义
**********:********************
1.4参考资料
《*********》
2测试项目
本测试主要为***系统的集成测试,目前***的版本为2.0,测试是***的最终集成测试,是建立在开发组程序员开发完毕自己的测试以及开发组测试的基础之上
3 被测特性
3.1操作性测试
主要测试操作是否正确,有无误差?分为两部分:
3.1.1返回测试
由主界面逐级进入最终界面,按EXIT键逐级返回,检查返回时候屏幕聚焦是否正确
比如:
1. 进入“系统设置”
2. 进入“频道搜索”
3. 进入“自动频道搜索”
4. 按EXIT键返回,检查当前聚焦是否为“频道搜索”
5. 按EXIT键返回,检查当前聚焦是否为“系统设置”
3.1.2进入测试
由主界面逐级进入最终界面,按MENU键返回主界面,再次进入,检查是否聚焦正确
比如:
1. 进入“系统设置”
2. 进入“频道搜索”
3. 进入“自动频道搜索”
4. 按MENU键返回主界面
5. 当前聚焦是否为“系统设置”
6. 进入“系统设置”,当前聚焦是否为“频道搜索”
3.2功能测试
测试机顶盒中每个应用的功能是否正确
3.3性能测试
3.3.1疲劳性测试
测试连续开机1个月不关机器,每3天去运行一次应用。看系统的稳定性
3.3.2大容量数据测试
前段***数据库表中含有大量数据,测试***功能
4 不被测特性
5 测试方法
1. 书写测试计划
2. 审核测试计划,未通过返回第一步
3. 书写测试用例;
4. 审核测试用例,未通过返回第三步
5. 测试人员按照测试用例逐项进行测试活动,并且将测试结果填写在测试报告上;(测试报告必须覆盖所有测试用例)
6. 测试过程中发现bug,将bug填写在bugzilla上发给集成部经理;(bug状态NEW)
7. 集成部经理接到bugzilla发过来的bug
7.1 对于明显的并且可以立刻解决的bug,将bug发给开发人员;(bug状态ASSIGNED);
7.2 对于不是bug的提交,集成部经理通知测试设计人员和测试人员,对相应文档进行修改; (bug状态RESOLVED,决定设置为INVALID);
7.3 对于目前无法修改的,将这个bug放到下一轮次进行修改;(bug状态RESOLVED,决定设置为REMIND)
8. 开发人员接到发过来的bug立刻修改;(bug状态RESOLVED,决定设置为FIXED)
9. 测试人员接到bugzilla发过来的错误更改信息,应该逐项复测,填写新的测试报告(测试报告必须覆盖上一次中所有REOPENED的测试用例);
10. 如果复测有问题返回第六步(bug状态REOPENED)
11. 否则关闭这项BUG(bug状态CLOSED)
12. 本轮测试中测试用例中有95%一次性通过测试,结束测试任务;
13. 本轮测试中发现的错误有98%经过修改并且通过再次测试(即bug状态CLOSED),返回第五步进行新的一轮测试;
14. 测试任务结束后书写测试总结报告;
15. 正规测试结束进入非正规测试,首先是ALPHA测试,请公司里其他非技术人员以用户角色使用系统。发现bug通知测试人员,测试人员以正规流程处理bug事件;
16. 然后是BETA测试,请用户代表进行测试。发现bug通知测试人员,测试人员以正规流程处理bug事件。
几点说明:
O 测试回归计划为三次;
O 测试用例应该写得比较详尽,步骤一定要标明清楚(应该包括:编号,测试描述,前置条件,测试步骤以及测试希望结果);
O 对于测试人员觉得应该进行的测试项目,测试人员应该报告测试设计人员,完善和健全测试用例;
O 测试报告与测试用例分开,测试报告标明测试用例序号以及是否通过Y/N;
O 对于集成部经理无法决定的上交项目负责人决定;
O 性能测试中的疲劳性测试可以结合在功能测试部分,即测试期间不关闭机器;
O 性能测试中的大容量数据测试放在测试后部分轮次(第二步,只需要进行一次)
6 测试通过标准
测试结果与测试用例中期望的结果一致,测试通过,否则标明测试未通过。
6.1测试结果审批过程
6.1.1测试回归申请结束
测试人员提出申请这轮测试结束,提交集成部经理;
集成部经理召集本组人员开会讨论;
讨论通过,进行下一轮测试,并且部署下一轮测试的注意事项,流程等内容;
如果发现这轮测试目前还存在问题没有解决,延期下一轮测试时间,讨论下一步工作应该如何进行。
6.1.2测试结果申请结束
测试人员提出申请测试结束,提交集成部经理;
集成部经理召集本组人员开会讨论;
1. 讨论通过,结束测试任务;
2. 如果发现目前测试还存在问题没有解决,延期测试结束时间,并且讨论下一步工作应该如何进行。
7 测试挂起和恢复条件
7.1挂起条件
O 进入第一轮测试,测试人员大体了解一下产品情况,如果在一小时之内发现5个以上(含5个)操作性错误,或者3个以上(含3个)功能性错误,退回测试组测试;
O 遇到有项目优先级更高的集成测试任务;
O 遇到有项目优先级更高的集成任务;
O 在测试复测过程中发现产品无法运行下去;
O 人员,设备不足。
7.2恢复条件
O 符合进入集成测试条件(一小时之内发现5个以下(不含5个)操作性错误,或者3个以下(不含3个)功能性错误);
O 项目优先级更高的集成测试任务暂告完成;
O 项目优先级更高的集成任务暂告完成;
O 复测过程中产品可以运行下去;
O 人员,设备到位。
8应提供的测试文件
O 测试计划书
O 测试用例
O 测试报告
O 测试总结
9测试任务
O 制定审核测试计划
O 制定和审核测试用例
O 进行测试活动
O 书写测试报告
10测试环境需求
10.1硬件需求
***********
10.2软件需求
************
10.3测试工具
*************
10.4测试需要的条件
**************
10.4.1 需要的文档
O 用户手册
O 应用手册
O 安装说明
10.4.2需要完成的任务
O 程序员本人测试
O 测试组完成测试
11角色和职责
O 集成(测试)经理:控制并完成测试任务和测试过程,决定测试人员提交上来的bug是否需要修改;
O 测试设计人员:书写集成测试用例;
O 测试人员:按照测试用例进行测试活动;
O 开发人员:MHP程序bug修改;
O 用户代表:进行BETA测试。
12 人员和培训
O 集成测试经理有责任对测试相关人员进行测试流程,规章制度培训;
O 测试设计人员有责任对测试人员进行测试操作培训
13 测试进度
测试工作 进度(人*工作日)
测试计划 8
测试设计 60
测试执行总共进度 30
每次回归进度 10
测试报告 214风险及应急计划
设备不到位:加紧设备购买;
人员不到位
人员请假:请假人员回来加班或赶紧测试进度/申请调配新的人员;
人员离职:调配新的人员;
人员调配到其他部门或项目:调配新的人员;
开发人员开发频频出错:通知开发部门,商量策略;
其他原因的测试工作频频被挂起或者挂起后迟迟恢复不了:加班或延期
15审批
集成部经理 技术部经理
姓名: 姓名:
日期: 日期: -
如何有效的对测试人员进行业绩考核?(转载)
2008-10-10 16:16:20
测试人员主要是三个方面。
第一,整体工作效率。第二,工作结果。第三,过程控制。(针对测试主管或组长)
1.整体工作效率
1.1有效工作时间
主要check指标是每日实际工作时间,按照Ms的标准,一个测试工程师的每天的有效工作时间应该在70%以上。如果只有50%或以下的有效工作时间,那么不能成为好的测试工程师,因为他有能力做得更好。
1.2是否在制定时间内完成工作任务
主要check指标是进度偏离度。主要是和测试计划相比,有多少的延期。这个指标计算是:计划时间/实际需用时间。
当然,本指标未考虑其他因素,如开发人员窝工导致的delay。
2.工作结果
2.1测试用例的数量和质量
a,测试用例的数量
主要考核指标是用例编写速度,考核办法是测试用例的个数/写用例所用时间。
b,测试用例的质量
主要考核指标是用例编写质量,用于考察文档是由有效的指导了测试工作。考核办法是来自用例的bug数目/总bug数目,应该是70%以上才算是质量比较好的用例。
2.2bug的数量和质量
a,bug提交的数量
主要考核指标是提交bug的数量,这个指标根据项目不同而定,不好给出固定经验值。
b,bug的质量
主要考核指标是提交bug的质量,即提交的bug,严重程度和,发现路径的复杂程度
c,发现bug的阶段
主要考核指标是提交bug的时间段,具体执行是统计在测试的每个阶段,发现bug的比例,特别是严重的bug发现的早晚
2.3是否及时验证关闭bug
主要考核指标是验证关闭bug的及时度
2.4测试自动化程度及收效
主要考核指标是,测试中自动化运用的含量,也就是测试技术含量,成果如何?
2.5所负责模块的产品总体质量以及用户反馈
这个总体质量是产品发布之后一段时间才能得出结论,主要是市场,用户对产品的质量、稳定性、性能的反馈。
考核的主要指标是两个。
a,根据市场反馈(由经理定性考核)
b,根据测试人员提交的bug和用户反馈的bug之间的比例,比例越大,说明测试质量相对越高。当然前提是必须划清楚客户的新需求,或者对spec设计方面的抱怨。
3.过程改进
考核点,是纵向对比,相比上一个项目,在质量控制上和测试进度进程上有否进步。包括测试方法,提升质量的手段,测试数据记录,用例更新等等有没有改进。
该项具体考核方法也是经理来根据测试组在过程中具体表现,来定性打分。
还包括测试人员在测试过程中的学习能力。这个也是定性。
4.考核注意事项
4.1统计bug的注意事项
5.其它注意事项
作为考核者要注意以下比例,也许有些没有列入考核内容,但是如下这些点可以指导测试。
a,测试团队发现的bug和所有bug之间的比例
b,spec设计造成的bug
c,重复或者误提交的bug所占的比例
d,每周发现的bug的趋势图
e,Bug严重等级的构成比例
f,Bug从提交到解决的平均需要时间
g,Bug从解决到关闭的平均需要时间 -
google test【转】
2008-10-10 16:02:15
Introduction:为什么需要Google C++ 测试框架?
Google C++ 测试框架帮助你更好地编写C++测试。
无论你是在Linux,Windows,还是Mac环境下工作,只要你编写C++代码,Google 测试框架都可以帮上忙。
那么,哪些因素才能构成一个好的测试?以及,Google C++ 测试框架怎样满足这些因素?我们相信:
- 测试应该是独立、可重复的。因为其他测试成功或失败而导致我们要对自己的测试进行debug是非常痛苦的。Google C++ 测试框架通过将每个测试在不同的对象中运行,使得测试分离开来。当一个测试失败时,Google C++ 测试框架允许你独立运行它以进行快速除错。
- 测试应该能够被很好地组织,并反映被测代码的结构。Google C++ 测试框架将测试组织成测试案例,案例中的测试可以共享数据和程序分支。这样一种通用模式能够很容易辨识,使得我们的测试容易维护。当开发人员在项目之间转换,开始在一个新的代码基上开始工作时,这种一致性格外有用。
- 测试应该是可移植、可重用的。开源社区有很多平台独立的代码,它们的测试也应该是平台独立的。除开一些特殊情况,Google C++ 测试框架运行在不同的操作系统上、与不同的编译器(gcc、icc、MSVC)搭配,Google C++ 测试框架的测试很容易与不同的配置一起工作。
- 当测试失败时,应该提供尽可能多的、关于问题的信息。Google C++ 测试框架在第一个测试失败时不会停下来。相反,它只是将当前测试停止,然后继续接下来的测试。你也可以设置对一些非致命的错误进行报告,并接着进行当前的测试。这样,你就可以在一次“运行-编辑-编译”循环中检查到并修复多个bug。
- 测试框架应该能将测试编写人员从一些环境维护的工作中解放出来,使他们能够集中精力于测试的内容。Google C++ 测试框架自动记录下所有定义好的测试,不需要用户通过列举来指明哪些测试需要运行。
- 测试应该快速。使用Google C++ 测试框架,你可以重用多个测试的共享资源,一次性完成设置/解除设置,而不用使一个测试去依赖另一测试。
因为Google C++ 测试框架基于著名的xUnit架构,如果你之前使用过JUnit或PyUnit的话,你将会感觉非常熟悉。如果你没有接触过这些测试框架,它也只会占用你大约10分钟的时间来学习基本概念和上手。所以,让我们开始吧!
Note:本文偶尔会用“Google Test”来代指“Google C++ 测试框架”。
基本概念
使用Google Test时,你是从编写断言开始的,而断言是一些检查条件是否为真的语句。一个断言的结果可能是成功、非致命失败,或者致命失败。如果一个致命失败出现,他会结束当前的函数;否则,程序继续正常运行。
测试使用断言来验证被测代码的行为。如果一个测试崩溃或是出现一个失败的断言,那么,该测试失败;否则该测试成功。
一个测试案例(test case)包含了一个或多个测试。你应该将自己的测试分别归类到测试案例中,以反映被测代码的结构。当测试案例中的多个测试需要共享通用对象和子程序时,你可以把他们放到一个测试固件(test fixture)类中。
一个测试程序可以包含多个测试案例。
从编写单个的断言开始,到创建测试和测试案例,我们将会介绍怎样编写一个测试程序。
断言
Google Test中的断言是一些与函数调用相似的宏。要测试一个类或函数,我们需要对其行为做出断言。当一个断言失败时,Google Test会在屏幕上输出该代码所在的源文件及其所在的位置行号,以及错误信息。也可以在编写断言时,提供一个自定义的错误信息,这个信息在失败时会被附加在Google Test的错误信息之后。
断言常常成对出现,它们都测试同一个类或者函数,但对当前功能有着不同的效果。ASSERT_*版本的断言失败时会产生致命失败,并结束当前函数。EXPECT_*版本的断言产生非致命失败,而不会中止当前函数。通常更推荐使用EXPECT_*断言,因为它们运行一个测试中可以有不止一个的错误被报告出来。但如果在编写断言如果失败,就没有必要继续往下执行的测试时,你应该使用ASSERT_*断言。
因为失败的ASSERT_*断言会立刻从当前的函数返回,可能会跳过其后的一些的清洁代码,这样也许会导致空间泄漏。根据泄漏本身的特质,这种情况也许值得修复,也可能不值得我们关心——所以,如果你得到断言错误的同时,还得到了一个堆检查的错误,记住上面我们所说的这一点。
要提供一个自定义的错误消息,只需要使用<<操作符,或一个<<操作符的序列,将其输入到框架定义的宏中。下面是一个例子:
- ASSERT_EQ(x.size(), y.size()) << "Ve<SPAN class=hilite2>c</SPAN>tors x and y are of unequal length";
- for (int i = 0; i < x.size(); ++i) {
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(x[i], y[i]) << "Ve<SPAN class=hilite2>c</SPAN>tors x and y differ at index " << i;
- }
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length"; for (int i = 0; i < x.size(); ++i) { EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i; }
任何能够被输出到ostream中的信息都可以被输出到一个断言宏中——特别是C字符串和string对象。如果一个宽字符串(wchar_t*,windows上UNICODE模式TCHAR*或std::wstring)被输出到一个断言中,在打印时它会被转换成UTF-8编码。
基本断言
下面这些断言实现了基本的true/false条件测试。
致命断言 非致命断言 验证条件 ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition为真 ASSERT_FALSE(condition); EXPECT_FALSE(condition); condition 为假 记住,当它们失败时,ASSERT_*产生一个致命失败并从当前函数返回,而EXCEPT_*产生一个非致命失败,允许函数继续运行。在两种情况下,一个断言失败都意味着它所包含的测试失败。
有效平台:Linux、Windows、Mac。
二进制比较
本节描述了比较两个值的一些断言。
致命断言 非致命断言 验证条件 ASSERT_EQ(expected, actual); EXPECT_EQ(expected, actual); expected == actual ASSERT_NE(val1, val2); EXPECT_NE(val1, val2); val1 != val2 ASSERT_LT(val1, val2); EXPECT_LT(val1, val2); val1 < val2 ASSERT_LE(val1, val2); EXPECT_LE(val1, val2); val1 <= val2 ASSERT_GT(val1, val2); EXPECT_GT(val1, val2); val1 > val2 ASSERT_GE(val1, val2); EXPECT_GE(val1, val2); val1 >= val2 在出现失败事件时,Google Test会将两个值(Val1和Val2)都打印出来。在ASSERT_EQ*和EXCEPT_EQ*断言(以及我们随后介绍类似的断言)中,你应该把你希望测试的表达式放在actual(实际值)的位置上,将其期望值放在expected(期望值)的位置上,因为Google Test的测试消息为这种惯例做了一些优化。
参数值必须是可通过断言的比较操作符进行比较的,否则你会得到一个编译错误。参数值还必须支持<<操作符来将值输入到ostream中。所有的C++内置类型都支持这一点。
这些断言可以用于用户自定义的型别,但你必须重载相应的比较操作符(如==、<等)。如果定义有相应的操作符,推荐使用ASSERT_*()宏,因为它们不仅会输出比较的结果,还会输出两个比较对象。
参数表达式总是只被解析一次。因此,参数表达式有一定的副作用(side effect,这里应该是指编译器不同,操作符解析顺序的不确定性)也是可以接受的。但是,同其他普通C/C++函数一样,参数表达式的解析顺序是不确定的(如,一种编译器可以自由选择一种顺序来进行解析),而你的代码不应该依赖于某种特定的参数解析顺序。
ASSERT_EQ()对指针进行的是指针比较。即,如果被用在两个C字符串上,它会比较它们是否指向同样的内存地址,而不是它们所指向的字符串是否有相同值。所以,如果你想对两个C字符串(例如,const char*)进行值比较,请使用ASSERT_STREQ()宏,该宏会在后面介绍到。特别需要一提的是,要验证一个C字符串是否为空(NULL),使用ASSERT_STREQ(NULL, c_string)。但是要比较两个string对象时,你应该使用ASSERT_EQ。
本节中介绍的宏都可以处理窄字符串对象和宽字符串对象(string和wstring)。
有效平台:Linux、Windows、Mac。
字符串比较
该组断言用于比较两个C字符串。如果你想要比较两个string对象,相应地使用EXPECT_EQ、EXPECT_NE等断言。
致命断言 非致命断言 验证条件 ASSERT_STREQ(expected_str, actual_str); EXPECT_STREQ(expected_str, actual_str); 两个C字符串有相同的内容 ASSERT_STRNE(str1, str2); EXPECT_STRNE(str1, str2); 两个C字符串有不同的内容 ASSERT_STRCASEEQ(expected_str, actual_str); EXPECT_STRCASEEQ(expected_str, actual_str); 两个C字符串有相同的内容,忽略大小写 ASSERT_STRCASENE(str1, str2); EXPECT_STRCASENE(str1, str2); 两个C字符串有不同的内容,忽略大小写 注意断言名称中出现的“CASE”意味着大小写被忽略了。
*STREQ*和*STRNE*也接受宽字符串(wchar_t*)。如果两个宽字符串比较失败,它们的值会做为UTF-8窄字符串被输出。
一个NULL空指针和一个空字符串会被认为是不一样的。
有效平台:Linux、Windows、Mac。
参见:更多的字符串比较的技巧(如子字符串、前缀和正则表达式匹配),请参见[Advanced Guide Advanced Google Test Guide]。
简单的测试
要创建一个测试:
- 使用TEST()宏来定义和命名一个测试函数,它们是一些没有返回值的普通C++函数。
- 在这个函数中,与你想要包含的其它任何有效C++代码一起,使用Google Test提供的各种断言来进行检查。
- 测试的结果由其中的断言决定;如果测试中的任意断言失败(无论是致命还是非致命),或者测试崩溃,那么整个测试就失败了。否则,测试通过。
- <SPAN class=hilite3>TEST</SPAN>(<SPAN class=hilite3>test</SPAN>_<SPAN class=hilite2>c</SPAN>ase_name, <SPAN class=hilite3>test</SPAN>_name) {
- ... <SPAN class=hilite3>test</SPAN> body ...
- }
TEST(test_case_name, test_name) { ... test body ... }
TEST()的参数是从概括到特殊的。第一个参数是测试案例的名称,第二个参数是测试案例中的测试的名称。记住,一个测试案例可以包含任意数量的独立测试。一个测试的全称包括了包含它的测试案例名称,及其独立的名称。不同测试案例中的独立测试可以有相同的名称。
举例来说,让我们看一个简单的整数函数:
int Factorial(int n); // 返回n的阶乘
这个函数的测试案例应该看起来像是:
- // 测试0的阶乘
- <SPAN class=hilite3>TEST</SPAN>(Fa<SPAN class=hilite2>c</SPAN>torial<SPAN class=hilite3>Test</SPAN>, HandlesZeroInput) {
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(1, Fa<SPAN class=hilite2>c</SPAN>torial(0));
- }
- // 测试正数的阶乘
- <SPAN class=hilite3>TEST</SPAN>(Fa<SPAN class=hilite2>c</SPAN>torial<SPAN class=hilite3>Test</SPAN>, HandlesPositiveInput) {
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(1, Fa<SPAN class=hilite2>c</SPAN>torial(1));
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(2, Fa<SPAN class=hilite2>c</SPAN>torial(2));
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(6, Fa<SPAN class=hilite2>c</SPAN>torial(3));
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(40320, Fa<SPAN class=hilite2>c</SPAN>torial(8));
- }
// 测试0的阶乘 TEST(FactorialTest, HandlesZeroInput) { EXPECT_EQ(1, Factorial(0)); } // 测试正数的阶乘 TEST(FactorialTest, HandlesPositiveInput) { EXPECT_EQ(1, Factorial(1)); EXPECT_EQ(2, Factorial(2)); EXPECT_EQ(6, Factorial(3)); EXPECT_EQ(40320, Factorial(8)); }
Google Test根据测试案例来分组收集测试结果,因此,逻辑相关的测试应该在同一测试案例中;换句话说,它们的TEST()的第一个参数应该是一样的。在上面的例子中,我们有两个测试,HandlesZeroInput和HandlesPostiveInput,它们都属于同一个测试案例FactorialTest。
有效平台:Linux、Windows、Mac。
测试固件(Test Fixtures,又做测试夹具、测试套件):在多个测试中使用同样的数据配置
当你发现自己编写了两个或多个测试来操作同样的数据,你可以采用一个测试固件。它让你可以在多个不同的测试中重用同样的对象配置。
要创建测试固件,只需:
- 创建一个类继承自testing::Test。将其中的成员声明为protected:或是public:,因为我们想要从子类中存取固件成员。
- 在该类中声明你计划使用的任何对象。
- 如果需要,编写一个默认构造函数或者SetUp()函数来为每个测试准备对象。常见错误包括将SetUp()拼写为Setup()(小写了u)——不要让它发生在你身上。
- 如果需要,编写一个析构函数或者TearDown()函数来释放你在SetUp()函数中申请的资源。要知道什么时候应该使用构造函数/析构函数,什么时候又应该使用SetUp()/TearDown()函数,阅读我们的FAQ。
- 如果需要,定义你的测试所需要共享的子程序。
当我们要使用固件时,使用TEST_F()替换掉TEST(),它允许我们存取测试固件中的对象和子程序:
- <SPAN class=hilite3>TEST</SPAN>_F(<SPAN class=hilite3>test</SPAN>_<SPAN class=hilite2>c</SPAN>ase_name, <SPAN class=hilite3>test</SPAN>_name) {
- ... <SPAN class=hilite3>test</SPAN> body ...
- }
TEST_F(test_case_name, test_name) { ... test body ... }
与TEST()一样,第一个参数是测试案例的名称,但对TEST_F()来说,这个名称必须与测试固件类的名称一些。你可能已经猜到了:_F正是指固件。
不幸地是,C++宏系统并不允许我们创建一个单独的宏来处理两种类型的测试。使用错误的宏会导致编译期的错误。
而且,你必须在TEST_F()中使用它之前,定义好这个测试固件类。否则,你会得到编译器的报错:“virtual outside class declaration”。
对于TEST_F()中定义的每个测试,Google Test将会:
- 在运行时创建一个全新的测试固件
- 马上通过SetUp()初始化它,
- 运行测试
- 调用TearDown()来进行清理工作
- 删除测试固件。注意,同一测试案例中,不同的测试拥有不同的测试固件。Google Test在创建下一个测试固件前总是会对现有固件进行删除。Google Test不会对多个测试重用一个测试固件。测试对测试固件的改动并不会影响到其他测试。
例如,让我们为一个名为Queue的FIFO队列类编写测试,该类的接口如下:
- template <typename E> // E为元素类型
- <SPAN class=hilite2>c</SPAN>lass Queue {
- publi<SPAN class=hilite2>c</SPAN>:
- Queue();
- void Enqueue(<SPAN class=hilite2>c</SPAN>onst E& element);
- E* Dequeue(); // 返回 NULL 如果队列为空.
- size_t size() <SPAN class=hilite2>c</SPAN>onst;
- ...
- };
template <typename E> // E为元素类型 class Queue { public: Queue(); void Enqueue(const E& element); E* Dequeue(); // 返回 NULL 如果队列为空. size_t size() const; ... };
首先,定义一个固件类。习惯上,你应该把它的名字定义为FooTest,这里的Foo是被测试的类。
- <SPAN class=hilite2>c</SPAN>lass Queue<SPAN class=hilite3>Test</SPAN> : publi<SPAN class=hilite2>c</SPAN> <SPAN class=hilite3>test</SPAN>ing::<SPAN class=hilite3>Test</SPAN> {
- prote<SPAN class=hilite2>c</SPAN>ted:
- virtual void SetUp() {
- q1_.Enqueue(1);
- q2_.Enqueue(2);
- q2_.Enqueue(3);
- }
- // virtual void TearDown() {}
- Queue<int> q0_;
- Queue<int> q1_;
- Queue<int> q2_;
- };
class QueueTest : public testing::Test { protected: virtual void SetUp() { q1_.Enqueue(1); q2_.Enqueue(2); q2_.Enqueue(3); } // virtual void TearDown() {} Queue<int> q0_; Queue<int> q1_; Queue<int> q2_; };
在这个案例中,我们不需要TearDown(),因为每个测试后除了析构函数外不需要进行其它的清理工作了。
接下来我们使用TEST_F()和这个固件来编写测试。
- <SPAN class=hilite3>TEST</SPAN>_F(Queue<SPAN class=hilite3>Test</SPAN>, IsEmptyInitially) {
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(0, q0_.size());
- }
- <SPAN class=hilite3>TEST</SPAN>_F(Queue<SPAN class=hilite3>Test</SPAN>, DequeueWorks) {
- int* n = q0_.Dequeue();
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(NULL, n);
- n = q1_.Dequeue();
- ASSERT_TRUE(n != NULL);
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(1, *n);
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(0, q1_.size());
- delete n;
- n = q2_.Dequeue();
- ASSERT_TRUE(n != NULL);
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(2, *n);
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(1, q2_.size());
- delete n;
- }
TEST_F(QueueTest, IsEmptyInitially) { EXPECT_EQ(0, q0_.size()); } TEST_F(QueueTest, DequeueWorks) { int* n = q0_.Dequeue(); EXPECT_EQ(NULL, n); n = q1_.Dequeue(); ASSERT_TRUE(n != NULL); EXPECT_EQ(1, *n); EXPECT_EQ(0, q1_.size()); delete n; n = q2_.Dequeue(); ASSERT_TRUE(n != NULL); EXPECT_EQ(2, *n); EXPECT_EQ(1, q2_.size()); delete n; }
上面这段代码既使用了ASSERT_*断言,又使用了EXPECT_*断言。经验上讲,如果你想要断言失败后,测试能够继续进行以显示更多的错误时,你应该使用EXPECT_*断言;使用ASSERT_*如果该断言失败后继续往下执行毫无意义。例如,Dequeue测试中的第二个断言是ASSERT_TURE(n!= NULL),因为我们随后会n指针解引用,如果n指针为空的话,会导致一个段错误。
当这些测试开始时,会发生如下情况:
- Google Test创建一个QueueTest对象(我们把它叫做t1)。
- t1.SetUp()初始化t1。
- 第一个测试(IsEmptyInitiallly)在t1上运行。
- 测试完成后,t1.TearDown()进行一些清理工作。
- t1被析构。
- 以上步骤在另一个QueueTest对象上重复进行,这回会运行DequeueWorks测试。
有效平台:Linux、Windows、Mac。
注意:当一个测试对象被构造时,Google Test会自动地保存所有的Google Test变量标识,对象析构后进行恢复。
调用测试
TEST()和TEST_F()向Google Test隐式注册它们的测试。因此,与很多其他的C++测试框架不同,你不需要为了运行你定义的测试而将它们全部再列出来一次。
在定义好测试后,你可以通过RUN_ALL_TESTS()来运行它们,如果所有测试成功,该函数返回0,否则会返回1.注意RUN_ALL_TESTS()会运行你链接到的所有测试——它们可以来自不同的测试案例,甚至是来自不同的文件。
当被调用时,RUN_ALL_TESTS()宏会:
- 保存所有的Google Test标志。
- 为一个侧测试创建测试固件对象。
- 调用SetUp()初始化它。
- 在固件对象上运行测试。
- 调用TearDown()清理固件。
- 删除固件。
- 恢复所有Google Test标志的状态。
- 重复上诉步骤,直到所有测试完成。
此外,如果第二步时,测试固件的构造函数产生一个致命错误,继续执行3至5部显然没有必要,所以它们会被跳过。与之相似,如果第3部产生致命错误,第4部也会被跳过。
重要:你不能忽略掉RUN_ALL_TESTS()的返回值,否则gcc会报一个编译错误。这样设计的理由是自动化测试服务会根据测试退出返回码来决定一个测试是否通过,而不是根据其stdout/stderr输出;因此你的main()函数必须返回RUN_ALL_TESTS()的值。
而且,你应该只调用RUN_ALL_TESTS()一次。多次调用该函数会与Google Test的一些高阶特性(如线程安全死亡测试thread-safe death tests)冲突,因而是不被支持的。
有效平台:Linux、Windows、Mac。
编写main()函数
你可以从下面这个样板开始:
- #in<SPAN class=hilite2>c</SPAN>lude "this/pa<SPAN class=hilite2>c</SPAN>kage/foo.h"
- #in<SPAN class=hilite2>c</SPAN>lude <g<SPAN class=hilite3>test</SPAN>/g<SPAN class=hilite3>test</SPAN>.h>
- namespa<SPAN class=hilite2>c</SPAN>e {
- // 测试Foo类的测试固件
- <SPAN class=hilite2>c</SPAN>lass Foo<SPAN class=hilite3>Test</SPAN> : publi<SPAN class=hilite2>c</SPAN> <SPAN class=hilite3>test</SPAN>ing::<SPAN class=hilite3>Test</SPAN> {
- prote<SPAN class=hilite2>c</SPAN>ted:
- // You <SPAN class=hilite2>c</SPAN>an remove any or all of the following fun<SPAN class=hilite2>c</SPAN>tions if its body
- // is empty.
- Foo<SPAN class=hilite3>Test</SPAN>() {
- // You <SPAN class=hilite2>c</SPAN>an do set-up work for ea<SPAN class=hilite2>c</SPAN>h <SPAN class=hilite3>test</SPAN> here.
- }
- virtual ~Foo<SPAN class=hilite3>Test</SPAN>() {
- // You <SPAN class=hilite2>c</SPAN>an do <SPAN class=hilite2>c</SPAN>lean-up work that doesn't throw ex<SPAN class=hilite2>c</SPAN>eptions here.
- }
- // If the <SPAN class=hilite2>c</SPAN>onstru<SPAN class=hilite2>c</SPAN>tor and destru<SPAN class=hilite2>c</SPAN>tor are not enough for setting up
- // and <SPAN class=hilite2>c</SPAN>leaning up ea<SPAN class=hilite2>c</SPAN>h <SPAN class=hilite3>test</SPAN>, you <SPAN class=hilite2>c</SPAN>an define the following methods:
- virtual void SetUp() {
- // <SPAN class=hilite2>C</SPAN>ode here will be <SPAN class=hilite2>c</SPAN>alled immediately after the <SPAN class=hilite2>c</SPAN>onstru<SPAN class=hilite2>c</SPAN>tor (right
- // before ea<SPAN class=hilite2>c</SPAN>h <SPAN class=hilite3>test</SPAN>).
- }
- virtual void TearDown() {
- // <SPAN class=hilite2>C</SPAN>ode here will be <SPAN class=hilite2>c</SPAN>alled immediately after ea<SPAN class=hilite2>c</SPAN>h <SPAN class=hilite3>test</SPAN> (right
- // before the destru<SPAN class=hilite2>c</SPAN>tor).
- }
- // Obje<SPAN class=hilite2>c</SPAN>ts de<SPAN class=hilite2>c</SPAN>lared here <SPAN class=hilite2>c</SPAN>an be used by all <SPAN class=hilite3>test</SPAN>s in the <SPAN class=hilite3>test</SPAN> <SPAN class=hilite2>c</SPAN>ase for Foo.
- };
- // <SPAN class=hilite3>Test</SPAN>s that the Foo::Bar() method does Ab<SPAN class=hilite2>c</SPAN>.
- <SPAN class=hilite3>TEST</SPAN>_F(Foo<SPAN class=hilite3>Test</SPAN>, MethodBarDoesAb<SPAN class=hilite2>c</SPAN>) {
- <SPAN class=hilite2>c</SPAN>onst string input_filepath = "this/pa<SPAN class=hilite2>c</SPAN>kage/<SPAN class=hilite3>test</SPAN>data/myinputfile.dat";
- <SPAN class=hilite2>c</SPAN>onst string output_filepath = "this/pa<SPAN class=hilite2>c</SPAN>kage/<SPAN class=hilite3>test</SPAN>data/myoutputfile.dat";
- Foo f;
- EXPE<SPAN class=hilite2>C</SPAN>T_EQ(0, f.Bar(input_filepath, output_filepath));
- }
- // <SPAN class=hilite3>Test</SPAN>s that Foo does Xyz.
- <SPAN class=hilite3>TEST</SPAN>_F(Foo<SPAN class=hilite3>Test</SPAN>, DoesXyz) {
- // Exer<SPAN class=hilite2>c</SPAN>ises the Xyz feature of Foo.
- }
- } // namespa<SPAN class=hilite2>c</SPAN>e
- int main(int arg<SPAN class=hilite2>c</SPAN>, <SPAN class=hilite2>c</SPAN>har **argv) {
- <SPAN class=hilite3>test</SPAN>ing::Init<SPAN class=hilite1>Google</SPAN><SPAN class=hilite3>Test</SPAN>(&arg<SPAN class=hilite2>c</SPAN>, argv);
- return RUN_ALL_<SPAN class=hilite3>TEST</SPAN>S();
- }
#include "this/package/foo.h" #include <gtest/gtest.h> namespace { // 测试Foo类的测试固件 class FooTest : public testing::Test { protected: // You can remove any or all of the following functions if its body // is empty. FooTest() { // You can do set-up work for each test here. } virtual ~Foo
【转自TESTAGE】实施单元测试技术
2008-10-10 15:52:31
本文作者通过实例介绍了单元测试自动化实现的原理和方法,更难得的是,作者结合自身工作经验提出了单元测试工程实施的要领和注意事项。
单元测试(Unit Testing)是针对于软件基本组成单元所进行的一种测试。按照《详细设计规格说明》中对软件单元的划分,单元测试人员应逐一检查软件单元的程序编码是否和设计要求完全一致。这里用到了“软件单元”这个词汇。一般地,“软件单元”是指在《详细设计规格说明》中所划分出的基本软件单元,即根据概要设计规格说明中的模块,细化出来的类、数据结构、过程或函数等。但在实际的单元测试过程中,有时为了进一步查找问题产生的根源,还会对软件单元继续细化,具体到某一个函数或方法体,或者函数、方法体内的某几段关键代码。
实现单元测试的自动化
目前,单元测试一般采用基于XUnit测试框架的自动化测试工具实现。如Java编程中使用的JUnit,.Net程序编程中使用的NUnit。也有一些其他的用于单元测试的工具,如Cantata或AdaTest,前者是针对于C/C++的测试工具,后者是针对于Ada语言的测试工具。单元测试工具的基本工作原理如图所示。
从图中可以看出,自动化单元测试工具的工作原理是借助于驱动模块与桩模块,运行被测软件单元以检查输入的测试用例是否按软件详细设计规格说明的规定执行相关操作。
这里必须先对桩模块(Stub Module)、驱动模块(Drive Module)等概念做一个简单的介绍。我们知道,软件单元在完成编码以后,代码本身并不是一个可以独立运行的程序。所以,必须为每个软件单元开发用于测试目的驱动模块和桩模块。在绝大多数应用中,驱动模块只是一个接收测试数据,并把数据传送给要测试的软件单元,然后打印或告知测试者相关测试结果的“主程序”;而桩模块的功能则是代替那些隶属于被测软件单元或与被测单元有接口关系的软件模块。这样,测试用例从驱动模块读入到被测软件单元中,被测软件单元针对给定的测试用例运行,当需要通过接口与其他模块进行通信时,就调用桩模块。被测软件单元执行完测试用例以后,将执行结果汇报给驱动模块,驱动模块再将执行结果打印出来或以其他方式(如E-mail)报告给单元测试者。
可以通过如下一个简单的Java程序来说明单元测试的原理。这个程序由三个代码文件组成。它们分别是CaseCheck.java、Account.java以及MoneyTran.java。其中CaseCheck.java充当驱动模块,Accout.java是被测软件单元,MoneyTran.java充当桩模块。以下列出它们各自的源代码:
/* Module name: CaseCheck.java this module servers as driven module; */
public class CaseCheck{
public static void main(String[] args){
Account TomAccount=new Account(8000);
if(8000!=TomAccount.checkBalance()){
System.out.println("TomAccount Construction error!");}
System.out.println("Total balance of TomAccount is "+TomAccount.checkBalance() +"\nWithdraw 1000 from TomAccount\n"+TomAccount.withdraw(1000));
System.out.println("Now,total balance of TomAccount is "+TomAccount.checkBalance() +"\nWithdraw 8000 from TomAccount\n"+TomAccount.withdraw(8000));
System.out.println("Desopit 2000 to Tom's Account.");
TomAccount.deposit(2000);
if(9000!=TomAccount.checkBalance()){
System.out.println("Account class deposit method error!");}
System.out.println("Now Tom's Account has Rmb "+TomAccount.checkBalance()+" .It can change into USDollar "+TomAccount.toDollar());
}
}
/* Module name: Account.java this module servers as software unit for test; */
public class Account{
private int sum;
public Account(int num){
sum=num;
}
public String withdraw(int num){
if(num>sum){return "Overdraft.Operation cancelled."+"\n";}else{
sum-=num;
return "Withdraw Success."+"\n";}}
public void deposit(int num){
sum+=num;}
public int checkBalance(){return sum;}
public int toDollar(){
double rate=MoneyTran.RmbtoDollar();
return (int) (rate*sum);}
}
/* Module name:MoneyTran.java this module servers as stub module; */
public class MoneyTran{
static double RmbtoDollar(){return 0.12081964;}
}
在上述代码中,被测单元Account.java有构造方法、存钱(deposit)、取钱(withdraw)、余款查询(checkBalance)以及人民币与美元兑换(toDollar)这些方法。CaseCheck.java构造了TomAccount这个对象,测试该对象上述方法是否能正常工作。注意到toDollar方法中调用了另一模块中的RmbtoDollar这个静态方法,因此,在本测试程序中加入了桩模块MoneyTran。实际中MoneyTran的RmbtoDollar()方法可能要完成实时的数据表查询操作,然而,因为被测单元是Account.java,所以采用一个简单的数值返回就行了。
目前常用的JUnit以及Nunit基本上都采用了上述实现架构。例如,在JUnit中上述CaseCheck.java文件可以用如下文件代替:
import junit.framework.*;
/* * Using junit to complete test task. */
public class JunitCaseCheck extends TestCase {
protected Account TomAccount;
protected Account NullPointer;
public JunitCaseCheck(String args0){ super(args0); }
protected void setUp() throws Exception{ TomAccount=new Account(8000);}
protected void tearDown() { TomAccount=NullPointer;}
public static Test suite() { return new TestSuite(JunitCaseCheck.class);}
public void testConstructor() {assertTrue(TomAccount.checkBalance()== 8000);}
public void testWithdraw(){ TomAccount.withdraw(1000);
assertTrue(TomAccount.checkBalance()== 7000);}
public void testDeposit(){ TomAccount.deposit(1000);
assertTrue(TomAccount.checkBalance()== 9000);}
public void testtoDollar(){assertTrue((int)(MoneyTran.RmbtoDollar()*8000)==TomAccount.toDollar()); }
public static void main(String[] args){ junit.swingui.TestRunner.run(JunitCaseCheck.class);}
}
保持其他两个java文件不变,可以看到JUnit将以绿条表示上述测试全部通过。由于NUnit一般采用C#描述测试脚本,上述三个程序都要做一些词法上的调整。
单元测试工具之外的工作
单元测试工具必须在人的辅助下完成单元测试任务。测试人员在运行单元测试工具之前,应设计好相应的测试用例。然后将测试用例输入驱动模块进行相应软件单元的测试工作。
如何设计高质量的测试用例是一个很有技术含量的论题,而且,一个设计完好的测试用例本身有时也应随编程语言、运行环境等做适应性修改。这里笔者给出几点经验之谈。
● 设计正常测试用例
这里,正常测试用例是指在实际业务中经常使用到的、不能出错的测试用例。设计正常的测试用例,关键是做到全面。要充分考虑到系统客户可能会实际面对的各种应用的情境,而不能只测一种或几种应用情境,忽略其他的情境。
● 设计边界值测试用例
边界值测试用例是指使用处于条件的边界的数值来测试被测软件单元能否作出预期反应的测试用例。比如对于一个int型数据,可以考虑输入一个int型数据最大值看会发生什么情况,又比如对于循环或条件语句,可以考虑输入条件的临界值,看看软件单元如何反应。边界值测试用例能较好地暴露编码人员逻辑不严密的地方。
● 设计异常测试用例
异常测试用例非常重要。一般的开发过程只测试代码能否在正常情境中工作,而不测试代码能否针对异常情境所做出适当的反应。这种做法是很片面的,对于复杂系统而言,更要引起足够重视。设计异常测试用例采取的方法是输入一些古怪的数值,看软件单元如何反应。如输入越界数值,输入类型不匹配的数值,输入参数个数不匹配等。
除了设计测试用例以外,单元测试人员还应该对关键软件部件的程序代码做必要的核查,检查编码人员是否在代码中引入了“后门”(一种能侵入系统取得控制权或窃取数据的程序段代码)、代码中是否存在冗余代码等。
单元测试工程实施要领
在工程实践中,单元测试应该坚持如下原则进行展开:
● 单元测试越早进行越好。在TDD方法中,Kent甚至认为开发团队应该遵行“先写测试、再写代码”的编程途径。
● 对于修改过的代码应该重做单元测试,以保证对已发现错误的修改没有引入新的错误。
● 测试人员的测试用例应经过审核,如有必要应经过会议评审,以保证测试用例的质量。
● 当测试用例的测试结果与设计规格说明上的预期结果不一致时,测
试人员应如实记录实际的测试结果。
除了上述四点原则之外,单元测试还应注意以下几点:
● 单元测试应该依据《软件详细设计规格说明》进行,而不要只看代码,不看设计文档。因为只查代码,仅仅能验证代码有没有做某件事,而不能验证它应不应该做这件事。
● 单元测试应注意选择好被测软件单元的大小。软件单元划分太大,那么内部逻辑和程序结构就会变得很复杂,造成测试用例过于繁多,令用例设计和评审人员疲惫不堪;而软件单元划分太细会造成测试工作太繁琐,失去效率。工程实践中要适当把握好划分原则,不能过于拘泥。
● 注意使用单元测试工具。目前市面上有很多可以用于单元测试的工具。如果一味地排斥自动化测试工具,有可能会导致大量的重复劳动。因此,好的测试团队应对市面的测试工具保持高度敏感,并在技术条件许可的情况下尽量开发一些通用的自主版权的测试工具。这样日积月累,测试团队就能很好地把握测试进度,降低工作强度,把测试人员的精力花在更有创造性的工作上。
Bugfree安装问题解决方案
2008-10-10 15:49:15
【摘自小水滴的个人空间】
总结一下我在安装Bugfree时遇到的一些问题和相关的解决方案。
服务器端环境:
操作系统:RedHat AS 4 ;数据库:Mysql;Web服务器:Apache;脚本系统:Php
错误提示一:不能通过'/tmp/mysql.sock'连到服务器
解决方案:这个问题是用户权限不够造成的,数据库里赋予用户足够权限即可解决。具体操作方法如
下:
[root@localhost etc]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7 to server version: 4.1.16
mysql> grant all privileges on *.* to 'jifang'@'' identified by 'hello';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
[root@localhost etc]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9 to server version: 4.1.16
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from user;
mysql> exit
Bye
错误提示二:客户机浏览器显示的是php的源码
解决方案:只需要重起Apache,即可解决。具体操作方法如下:
]#cd /path/to/apache/bin
]#apachectl restart
or
]#servcice httpd restart错误提示三:目录下找不到mysql.sock
解决方案:重新启动Mysql。命令执行完成后,需要等待一段时间,才能有
mysql.sock生成。具体操作方法如下:
1、使用 service 启动:service mysqld restart
2、使用 mysqld 脚本启动:/etc/inint.d/mysqld restart
国内软件测试中文书籍大全
2008-10-10 15:27:19
【摘自mnrslyl的个人空间 】
一、自动化测试类:
1、软件自动化测试:引入、管理与实施
Automated Software Testing Introduction,Management,and Performance
2、软件测试自动化技术与实例详解
Software Test Automation
3、高效软件测试自动化
Effective Software Test Automation
4、图形用户界面测试自动化
Effective GUI Test Automation
5、软件测试自动化
Just Enough Software Test Automation
6、软件工程与软件测试自动化教程
二、Web应用测试类:
1、Web安全测试
Testing Web Security:Assessing the Security of Web Sites and Applications
2、Web应用测试
Testing Application on the Web:Test Planning for Internet-Based Systems
3、Web应用测试(第二版)
Testing Applications on the Web: Test Planning for Mobile and Internet-Based Systems, Second Edition
4、Web测试指南
The Web Testing Companion: The Isider's Guide to Efficient and Effective Tests
三、软件测试基础类:
1、软件测试(原书第2版)
Software Testing A Craftsmaj's Approach(Second Edition)
2、软件测试
Software Testing
3、面向对象的软件测试
A Practical Guide to Testing Object Oriented Software
4、软件测试与质量管理
5、计算机软件测试(原书第2版)
Testing Computer Software,Second Edition
6、实用软件测试过程
Testing IT:An Off-the-Shelf Software Testing Process
7、软件质量和软件测试
Software Quality and Software Testing in Internet Times
8、系统的软件测试
Systematic Software Testing
9、软件子系统测试
The Craft of Software Testing:Subsystem Testing,Including Object-Based and Object-Oriented Testing
10、面向对象系统的测试
Testing Object-Oriented System:Models,Patterns,and Tools
11、软件测试技术概论
12、软件β测试
Beta Testing for Better Software
四、软件测试应用类:
1、有效软件测试
Effective Software Testing
2、实用软件测试方法与应用
3、软件测试:经验与教训
Lessons Learned in Software Testing
4、软件测试入门
Introducing Software Testing
5、实用软件测试指南
How to Break Software A Practical Guide to Testing
6、软件评估:基准测试与最佳实践
Software Assessments,Benchmarks,and Best Practices
7、嵌入式软件测试
Testing Embedded Software
8、软件测试求生法则
Surviving the Top Ten Challenges of Software Testing : A People-Oriented Approach
9、软件测试:过程改进
Software Testing in the Real World Improving the Process
10、快速测试
Papid Testing
11、软件测试的有效方法(原书第2版)
Effective Methods for Software Testing,Second Edition
12、网络测试深入解析
五、单元测试类:
1、单元测试之道Java版——使用Junit
Pragmatic Unit Testing:In Java with JUnit
2、测试驱动开发(中文版)
Test-driven development:by example
3、单元测试之道C#版——使用Nunit
Pragmatic Unit Testing:In C# with NUnit
4、测试驱动开发——实用指南
Test Driven Development: A Practical Guide
5、软件测试与Junit实践
六、性能测试类
1、2EE性能测试
J2EE Performance Testing With BEA WebLogic Server
2、Microsoft .NET Web应用程序性能测试
Performance Testing Microsoft .NET Web Applications
七、软件安全测试类:
1、黑客攻击测试篇
Hack Attacks Testing:How to Conduct Your Own Security Audit
2、Web安全测试
Testing Web Security:Assessing the Security of Web Sites and Applications
八、测试管理类:
1、测试流程管理
Managing the Testing Process
2、软件测试过程管理(原书第2版)
Managing the Testing Process(Second Edition)
九、软件测试培训类:
1、软件测试员培训教材
2、软件测试实用指南1、Q:给测试新手的建议和指导
A:http://bbs.testage.net/thread-3921-1-28.html
http://bbs.testage.net/thread-3202-1-26.html
http://bbs.testage.net/thread-6223-1-24.html
http://bbs.testage.net/thread-6217-1-24.html
2、Q:testcase 具体都包含哪些内容?
A::http://bbs.testage.net/thread-3571-1-32.html
3、Q:网管软件需要做哪些方面的测试?
A:http://bbs.testage.net/thread-4208-1-31.html
4、Q:测试工程师流程、入门、经验介绍
A:http://bbs.testage.net/thread-3199-1-31.html
http://bbs.testage.net/thread-5971-1-25.html
http://bbs.testage.net/thread-3259-1-22.html
5、Q:测试覆盖率详解
A:http://bbs.testage.net/thread-4195-1-31.html
6、Q:软件测试基本概念和分类
A:http://bbs.testage.net/thread-3512-1-31.html
7、Q:软件测试书籍列表:
A:http://bbs.testage.net/thread-4303-1-30.html
http://bbs.testage.net/thread-5249-1-26.html
8、Q:单元测试概念
A:http://bbs.testage.net/thread-4593-1-30.html
9、Q:软件测试常识
A: http://bbs.testage.net/thread-3173-1-30.html
http://bbs.testage.net/thread-3172-1-26.html
http://bbs.testage.net/thread-6110-1-25.html
http://bbs.testage.net/thread-5988-1-25.html
http://bbs.testage.net/thread-6121-1-21.html
10、Q:PC测试概念
A:http://bbs.testage.net/thread-4221-1-30.html
11、Q:C/S、B/S结构的测试简介
A:http://bbs.testage.net/thread-4221-1-30.html
12、Q:安装与卸载测试
A:http://bbs.testage.net/thread-3241-1-30.html
13、Q:软件测试工程师(初中级)职业前景
A:http://bbs.testage.net/thread-3759-1-27.html
14、Q:关于黑盒测试
A:http://bbs.testage.net/thread-5523-1-26.html
http://bbs.testage.net/thread-5522-1-26.html
http://bbs.testage.net/thread-5524-1-26.html
http://bbs.testage.net/thread-3721-1-22.html
15、Q:有关压力测试
A:http://bbs.testage.net/thread-6038-1-25.html
16、Q:如何设计编制软件测试用例
A:http://bbs.testage.net/thread-6031-1-25.html
17、Q:测试设计中需要考虑的测试类型
A:http://bbs.testage.net/thread-6153-1-24.html
18、Q:测试工具大全[转帖]仅供参考
A:http://bbs.testage.net/thread-6234-1-24.html
http://bbs.testage.net/thread-7488-1-21.html
19、Q:有关自动化测试
A:http://bbs.testage.net/thread-6198-1-24.html
20、Q:测试术语
A:http://bbs.testage.net/thread-6827-1-23.html
http://bbs.testage.net/thread-6037-1-23.html
http://bbs.testage.net/thread-6341-1-22.html
21、Q:Bug汇总
A:http://bbs.testage.net/thread-6828-1-21.html开通日志
2008-10-09 20:34:37
今天正式开通个人空间了!
开始做白盒测试已经有2个月了,可是目前来说还是没有进入状态,一片迷茫,看到这里很多高手的指导文章,很是兴奋,于是开通了这个空间,希望以后能有更多机会向高手们学习,与和我一样的新手共同进步!