奇迹世界十大奇迹怎么过河

奇迹世界怎么设置成为窗口模式?_百度知道
奇迹世界怎么设置成为窗口模式?
我打开3DFileAccess.dll文件,是一堆乱码~!郁闷
提问者采纳
奇迹世界窗口画面 (疯子置顶) 在奇迹世界目录下 找到 3Dsetup这个文件, 鼠标右键-属性-把《只读》勾没了(如果没勾的话就不用理他) 然后用记事本打开 把FullScreen=1 改成 FullScreen=0 Width=1024 Height=768 width 和height 根据你电脑的windows的分辨率而定 比如 你windows的分辨率是 那么 你的width 和height就可以 是
如果你的windows是
那么你这个就相应的改小就可以 比如说 800*600 这样进入游戏就可以了 窗口在我这里的主要作用是宽屏, 开全屏的话,任务会很难看,看着也不舒服,要看你们怎么用了 这还是很好用的是3Dsetup
其他类似问题
奇迹世界的相关知识
其他1条回答
打开3dsetup.ini按下面改:[Screen]Renderer=0FullScreen=0LockSizeMove=1Width=1024Height=768
您可能关注的推广
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
一个老大不小的人,一个重情守义的人,一个淡定内敛的人,一个通情达理的人,一个愿看爱写的人!
LOFTER精选
阅读(761)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'【原创】无厘头诗《浅湾儿》(怎样巧记键盘上字母键的位置)',
blogAbstract:'& 无厘头诗《浅湾儿》(怎样巧记键盘上字母键的位置)\n&\n&&&&&& 初学电脑者,大多都会感到记住电脑键盘上的字母太吃力了,因为它不是按照26个英文字母的顺序排列的;若按汉语拼音字母记,更是牛头难对马嘴。其实,大家在初练电脑打字时找了很多窍门,可以说是八仙过海各展神通。我现在虽然不是新手了,但为了为初练打字者助一把力,特将键盘上的26个字母按照汉语拼音的声母的谐音从左上角横向到右下角,编了一首无厘头诗,或许对初练打字的新手们有点儿小作用呢!\n&&&&&& 我的这首无厘头的窍门诗是这样写的:& &',
blogTag:'丙戌sun0909,无厘头诗,电脑,键盘,巧记',
blogUrl:'blog/static/2',
isPublished:1,
istop:false,
modifyTime:1,
publishTime:4,
permalink:'blog/static/2',
commentCount:63,
mainCommentCount:31,
recommendCount:4,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'一个老大不小的人,一个重情守义的人,一个淡定内敛的人,一个通情达理的人,一个愿看爱写的人!',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}奇迹世界怎么查看游戏ID_百度知道
奇迹世界怎么查看游戏ID
奇迹世界怎么查看游戏ID。。。我是游戏白痴。。请答!
奇迹世界不能查看对方的ID,现在只能显示对方的名字、等级和行会,装备只能通过肉眼观察,不能查看对方装备的属性。
其他类似问题
奇迹世界的相关知识
按默认排序
其他2条回答
奇迹世界好象不能看ID的吧~~只能看到别人的名字~
没有办法查看
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁1.在java环境中的classPath添加ac_framework.jar
2.在case文件头添加 import
framework.JobDOM.ACSeleniumJ
将selJava 的父类改为ACSeleniumJob,
public class selJava extends ACSelniumJob
Ok,到这里,新的selenium case已经完成了(红色为修改处),如下:
package com.example.
import com.thoughtworks.selenium.*;
import java.util.regex.P
framework.JobDOM.ACSeleniumJob
public class selJava extends&ACSeleniumJob&{
&&&&&& public
void setUp() throws Exception {
&&&&&&&&&&&&& &setup("http://change-this-to-the-site-you-are-testing/", "*firefox");
&&&&&& public
void testSelJava() throws Exception {
&&&&&&&&&&&&& selenium.open("/calc.htm");
&&&&&&&&&&&&& selenium.click("//input[@name='alex'
and @value='1']");
&&&&&&&&&&&&& selenium.click("//input[@name='alex'
and @value='+']");
&&&&&&&&&&&&& selenium.click("//input[@name='alex'
and @value='2']");
&&&&&&&&&&&&& selenium.click("//input[@name='alex'
and @value='=']");
&&&&&&&&&&&&& verifyEquals("3",
selenium.getValue("display"));
将Selenium case添加到TestJobFile中,运行AC,获得测试结果
TestJobFile中添加Selenium Job,按如下格式定义
name="selenium_demo" description="Test calc"& depends="" &
&&&&&&&&&&&&&&&&&& &TestData
type="xml"&
location="selenium\config.xml"/&
&&&&&&&&&&&&&&&&&& &JobInput
name="$MAIL_SUBJECT"/&
&&&&&&&&&&&&&&&&&& &ClassPath
location="selenium\selenium-java-client-driver_self_extended_oracle.jar"/&
&&&&&&&&&&&&&&&&&& &ClassPath
location="selenium\orajtst.jar"/&
&&&&&&&&&&&&& &ClassPath location="
selenium\qa.jar"/&
&ClassPath location=" selenium\selJava.class"/&
&&&&&&&&&&&&&&&&&& &SelTestCase
path="selJava"&
&&&&&&&&&&&&&&&&&&&&&&&&&&& &SelTest name="
testSelJava "/&
&&&&&&&&&&&&&&&&&& &/SelTestCase&
&/Selenium&
运行AC framework,即可执行selenium Job,并获得测试报告
我们最常用的是Selenium
RC模式,即先启动一个selenium
server,然后才能运行selenium脚本。
java启动selenium server的命令行语句如下:
java –jar selenium-server.jar –port 4444 –
proxyInjectionMode –log selServer.txt
如何把启动 selenium
server的java命令行也集成到AC中来呢?
这里要用到AC的Ant Engine。
创建基于Ant Engine的TestJob,TestJob内容遵循Ant语法,如下:
name="Ant_StartSelenium" description="selenium
initialization"&
depends="" daemon="true"&
&&&&&&&&&&&&&&&&&& &java
fork="true" spawn="true"
jar="D:\selenium-server.jar"&
&&&&&&&&&&&&&&&&&&&&&&&&&&& &arg
line="-port 4444 "/&
&&&&&&&&&&&&&&&&&&&&&&&&&&& &arg
line="-proxyInjectionMode"/&
&&&&&&&&&&&&&&&&&&&&&&&&&&& &arg
line="-log sel.txt"/&
&&&&&&&&&&&&&&&&&& &/Java&
&&&&&&&& &/Ant&
启动Selenium
server的TestJob可与Selenium Test Job做一个dependence的定义,保证每次运行selenium测试的时候,selenium server是处于启动状态的
name="Ant_StartSelenium" description="selenium
initialization"&
depends="" driver_type="ANT"
daemon="true"&
………………………
name="selenium_demo" description="Test calc"& depends="
Ant_StartSelenium " &
…………………….
&/Selenium&&&
pass(String msg): 向AC汇报当前运行状态,为成功
fail(String msg):向AC汇报当前运行状态,为失败
reportWarning(String msg):向AC汇报当前运行状态,为警告
getDataProperty(String key):获得测试数据
getEnvProperty(String key):获得环境变量及输入数据
getConfProperty(String key):获得配置数据
setOutputValue(String key,String value): 向全局数据通道输出数据
&运行TestJob,产生基于html页面的测试报告总览报告细分诊断报告&
对于金融业务系统来说,测试案例往往涉及到数据校验,交易确认,业务关联等等,手工测试执行起来比较复杂,更不用提自动化测试的实施了。这也是当前金融系统业界功能自动化测试程度不高的原因之一。
比如某个银行支付系统的转账案交易,手工测试大概的流程如下:
1. 创建Test Account A和Account B,并在各自名下建立相应权限的转账卡
2. 使用Account A登录银行转帐系统,使用名下某一张卡对Account B做转账交易,支付金额为1000元人民币.
3.查看Account A和B的余额,确认A账户减少1000元,B账户上增加1000元。
以上三个步骤从银行业务角度来看是各自独立的三个功能,但在转账场景里,又有密切的联系。步骤2依赖于步骤1的先决运行,步骤3则需要步骤2的转账数据。
使用QTP等工具针对以上案例开发脚本,则会面临棘手的问题,如果把三个功能写在一个脚本里,就会大大降低每个功能脚本的复用性。若开发成三个不同的脚本,那么彼此的关系和数据交互又需要增加额外的开发成本来实现。
在AC的世界里,一切都得非常简单,三个功能将被定义成三个TestJob。
Create_Account_Info负责创建测试账户A和B,然后将accountA,accountB作为参数输出。 在AC中做如下定义:
&QTP name="Create_Account_Info"
description="以管理员身份登录后台系统创建测试账户及相关卡信息
"& depends="" &
&&&&&&&&&&&&&&&&&& &JobOutput
name="accountA"/&
&&&&&&&&&&&&&&&&&& &JobOutput
name="accountB"/&
&&&&&&&&&&&&&&&&&& &Lib
location=”common\lib\lib_utility.vbs”/&
&&&&&&&&&&&&&&&&&& &Run
path="testcase\qtp\admin_createaccount"&&/Run&
其中admin_createaccount是录制好的qtp脚本路径,
lib_utility.vbs是脚本使用到的lib文件,AC将会自动加载到QTP运行环境中。
Transfer_FromAToB则会运行转账交易,将account A里的款项转给account B,并将转账数额作为参数输出。在AC中做如下定义:
&QTP name="Transfer_FromAToB"
description="以账户A登录,转账给B账户"& depends=""Create_Account_Info"
&&&&&&&&&&&&&&&&&& &JobInput
name="accountA"/&
&&&&&&&&&&&&&&&&&& &JobInput
name="accountB"/&
&&&&&&&&&&&&&&&&&& &JobOutput
name="transfer_amount"/&
&&&&&&&&&&&&&&&&&& &Lib
location=”common\lib\lib_utilityvbs”/&
&&&&&&&&&&&&&&&&&& &Run
path="testcase\qtp\transfer_bank"&&/Run&
&&&&&&&& &/QTP&
Verify_Account根据输入的两个account信息和转账金额,检查account的余额是否预期变化。在AC中做如下定义:
&QTP name="Verify_Account
" description="检查账户A和账户B的余额是否预期变化
"& depends=""
Transfer_FromAToB " &
&&&&&&&&&&&&&&&&&& &JobInput
name="transfer_amount"/&
&&&&&&&&&&&&&&&&&& &JobInput
name="accountA"/&
&&&&&&&&&&&&&&&&&& &JobInput
name="accountB"/&
&&&&&&&&&&&&&&&&&& &Lib
location=”common\lib\lib_utilityvbs”/&
&&&&&&&&&&&&&&&&&& &Run
path="testcase\qtp\transfer_bank"&&/Run&
&&&&&&&& &/QTP&
以上三个TestJob被AC组织起来,将会根据depends关系计算出执行路径:
Create_Account_Info→Transfer_FromAToB→Verify_Account
同时,AC搭建一条全局数据通道,所有TestJob的JobInput和JobOutput等数据都可在这条通道中进行交互。针对QTP脚本,AC提供了框架vbs 函数writeInitoACChanel(paraname,paravalue)和getDataFromChannel(paraname)实现写入和读出全局数据的功能。
上面谈到的是一种理想的TestJob结构模型,在实际的业务中,还有一些比较复杂的因素。比如,Create_Account_Info创建测试账户,测试卡号等信息这些工作,更合适在产品实例安装结束之后,作为基础数据被sql脚本直接创建至Database中。
这时,我们可将Create_Account_Info从QTP改由Java类型,而接口维持不变。
&Java name="Create_Account_Info"
description="Java程序调用jdbc运行sql脚本,在数据库中创建基础数据"& depends="" &
&&&&&&&&&&&&&&&&&& &JobOutput
name="accountA"/&
&&&&&&&&&&&&&&&&&& &JobOutput
name="accountB"/&
&&&&&&&&&&&&&&&&&& &ClassPath location=”javacase\jdbc_sql.jar”/&
&&&&&&&&&&&&&&&&&& &Run
path="jdbc.createAccount"&&/Run&
&&&&&&&& &/Java&
其中jdbc.createAccount是按照AC规范自开发的java程序,调用jdbc运行sql脚本。
这种好处显而易见,Create_Account_Info从QTP转换成Java类型之后,只要接口维持不变(JobOutput不变),那么其它两个TestJob,Transfer_FromAToB和Verify_Account不会受到任何影响。
同理,Verify_Account也可改写成Java或者selenium类型,以不同的方式进行验证。
另外一种复杂的情形可能会出现在QTP层面上,如果QTP的脚本规模较大,而又在同一个产品实例的上下文中完成不同的功能。比如,登录后做查账,查账之后做理财交易等等,都是基于一个web session上完成的。针对这种情况,AC的QTP提供了一种Factory Mode(工厂模式)的开发方式,使得所有的测试案例的定义和执行可以在同一个QTP执行环境中完成,非常适合QTP大规模的脚本开发工作。
基于录制生成的QTP脚本,是面向功能的,而不是结构化的测试案例。这使得QTP在维护和增加测试案例时,成本十分昂贵。为此,AC引入工厂开发模式,使得QTP的开发像Junit一样清晰方便。
QTP的工厂开发模式有如下规范:
1.每个QTP的测试案例在表现形式上都是一个Vbscript的函数,测试案例的增加/删除通过增加/删除一个VBS的Function来达到。
2.工厂模式不支持对象库模式的脚本,所有的功能都以Description编程来实现
3.使用checkDependence函数来检查每个测试案例的运行结果状态
4.调用writeIntoACChannel和getDataFromChannel来完成测试案例之间的数据交互。
5.& 每个测试案例都是一个函数,一个函数是否成为一个测试案例取决于在TestJobFile.xml中的定义。
QTP自带的Flight演示程序,录制生成的脚本如下模式:
‘登录客户端
Dialog("Login").WinEdit("Agent
Name:").Set "testing"
Dialog("Login").WinEdit("Password:").Set
Dialog("Login").WinButton("OK").Click
‘输入机票信息,下订单
Window("Flight
Reservation").ActiveX("MaskEdBox").Type "081210"
Window("Flight
Reservation").WinComboBox("Fly From:").Select
"Frankfurt"
Window("Flight
Reservation").WinComboBox("Fly To:").Select "London"
Window("Flight Reservation").WinButton("Insert
Order").Click
Window("Flight Reservation").Close
从QTP录制脚本转换成工厂模式脚本,步骤如下:
1.创建一个testcase.vbs
2.将原始脚本进行description改写,并按照工厂模式规范,写入testcase.vbs
Function login
&&&&&& '调用框架函数ReportRunningInfo,写日志
&&&&&& ReportRunningInfo
"start to run login test case"
&&&&&& ……………Description创建……………………
&&&&&& Dialog(dlgLoginDesc).WinEdit(editUserDesc).set
getDataFromACChannel("user")
&&&&&& Dialog(dlgLoginDesc).WinEdit(editPasswdDesc).set
getDataFromACChannel("passwd")
&&&&&& Dialog(dlgLoginDesc).WinButton(btnOKDesc).Click
&&&&&& if(Window(flightWindowDesc).Exist(30))
&&&&&&&&&&&&& ‘调用reportPass,向AC报告当前案例成功状态
&&&&&&&&&&&&& reportPass
"has sigin in successfully"
&&&&&&&&&&&&& login
&&&&&& Else
&&&&&&&&&&&&& ‘调用reportFail,向AC报告当前案例失败状态
&&&&&&&&&&&&& reportFail
"failed to sigin in"
&&&&&&&&&&&&& login
&&&&&& End
&&&&&& '将用户名写入数据通道,供后续执行的测试案例使用.&
&&&&&& username
= "sheng.liu"
&&&&&& writeIntoACChannel
"displayname",username
End Function
Function bookFlight
&&&&&& ReportRunningInfo
"start to run book flight test case"
&&&&&& '检查login案例是否成功,如果失败,当前案例则返回失败.
Not CheckDependence("login") Then
&&&&&&&&&&&&& bookFlight
&&&&&&&&&&&&& Exit
&&&&&& End
&&&&&& …………..Description创建及调用……………………
&&&&&& '从数据通道中获得login案例写入的用户名,作为订单用户名下单.
&&&&&& username
= getDataFromACChannel("displayname")
&&&&&& Window(flightWindowDesc).WinEdit(nameEditDesc).Set
Window(flightWindowDesc).WinButton(insertBtnDesc).Click
&&&&&& ……………………….
End Function
3.定义TestJobFile.xml文件,指定工厂模式和测试案例。
&QTP& name="QTP_DesktopClientTest_AC"
description="demo" factoryMode="true"
depends="Java_Init" iteration=""&
&&&&&&&&&&&&&&&&&& &Lib
location="testscripts\DesktopClient\testcase.vbs"/&
&&&&&&&&&&&&&&&&&& &Testdata
type="xsl" location="data\data_global_shining.xls"/&
&&&&&&&&&&&&&&&&&& &Testdata
type="xsl" location="data\data_global_shining.xls"/&
&&&&&&&&&&&&&&&&&& &Testdata
type="iteration"&
location="data\testdata.xls"/&
&&&&&&&&&&&&&&&&&& &Case
name="test.vbs" description="demo" depends=""&
&&&&&&&&&&&&&&&&&&&&&&&&&&& &Test
name="login" description="login flight
app"&&Run path="login"/&&/TestJob&
name="bookFlight" description="book
flight"&&Run path="login"/&&/TestJob&
&&&&&&&&&&&&&&&&&& &/Case&
&&&&&&&& &/QTP&
4.运行AC框架
AC会从指定的lib路径中获得testcase.vbs,然后以工厂模式运行login和bookflight两个测试案例。并最终形成测试报告。
从上面的示例可以看出,经过工厂模式改写后,QTP自动化测试具有以下优势
1.测试案例的粗细粒度更加细微,可以有效地与手工测试案例形成一一对应的映射关系
2.扩展性大大增强,增加新的功能点,只需开发新的function函数即可集成到AC中。
3.案例之间的依赖关系和数据交互更加密切。
总之,工厂模式非常实用于大规模的QTP的自动化测试脚本开发,大大减少维护成本,提升开发效率。Automation Center免费,并逐步在发布开源,详情了解
AC以Test Job Object Model(测试任务模型)为核心,以Test Job File(测试任务文件)为输入,根据Job type启动不同类型的测试引擎,执行测试任务,最后输出一份基于html的自动化测试报告。如图:
&& & & & & & & &图1-1 Automation Center结构示意图
AC目前支持五种主流测试引擎,Ant,Java,Selnium,QTP和Junit,这意味着,AC的用户可以将这些不同类型的测试脚本统一集成到AC中进行管理,调度和执行,最后形成一份自动化测试报告。
同时,JobEngine是基于Java的interface接口技术开发,因此,AC的用户也可以根据自己的需求对JobEngine进行扩展,开发不同Engine,比如RobotEngine,silkEngine等等。
TestJobObject Model是AC的运行核心,它是一个树形结构,每个TestJob下包含多个属性和对象,结构图如下:
&& & & & & & &图1-2 TestJobObject 架构图
的模型构建
一个TestJob有如下属性信息:
name:TestJob的名称
description:TestJob的描述信息
depends:TestJob的依赖信息。比如在TestJob A的depends定义为Test Job B,则AC会首先运行B,并根据B的成败,判断是否执行A。
driver_type: 此TestJob的引擎类型,AC会根据此字段启动对应类型的JobEngine。
一个TestJob还可以包含以下一个或多个附属对象:
&JobInput&:测试任务输入信息,在本Test Job开始执行之时,AC会检查其所有JobInput是否已经准备好。
&JobOutput&:测试任务输出信息,在本Test Job结束执行之后,AC会检查其所有的JobOutput 是否都已经按照定义输出。
&PropFile&:环境文件,遵循Java Properties定义规范,和测试环境相关的信息,比如被测服务器地址,测试帐号及口令等等。
&ConfFile&:AC配置文件,遵循java Proeprties定义规范,和任务设置相关的信息,比如测试超时时间,重复运行次数等等。
&TestData&:测试数据,支持xsl和xml两种数据格式。AC会在Test Job执行的时候加载测试数据,供Test Case使用。
&Lib&:QTP TestJob专用,AC在启动QTPjob时,会加载相应的lib文件
&ClassPath&: Java TestJob专用,AC在运行java job时,会调用classloader将所引用到的jar包装载至jvm中。
另外,TestJob同时还是一个递归的自定义结构,这意味着一个Test Job下可以递归包含若干个子Test Job,这种TestJob又称作抽象Job,AC在运行抽象Job时,会首先递归运行其下的所有子TestJob,然后分析这些TestJob的结果状态,最终确定抽象Job的运行结果状态。
抽象Job和实体Job在定义时唯一不同之处是,实体Job的属性会指定driver_type引擎类型,而抽象Job则没有driver_type属性或者为空。AC通过driver_type的值来决定是否应该启动相应的JobEngine。
使用xml文件来定义TestJob,以下是一个TestJobFile.xml示例:
&TestJob name=”机票预定系统测试” description="测试机票系统安装,登录,预定等功能" depends=""&
&PropFile name="$ENV" location="serverInfo.xml"/&
&ConfFile name="$CONFIG" location="config.xml"/&
&&&&&&&& &Java name="getTestCaseFromCVS" description="使用java程序从cvs中获得相应的测试代码"& depends="" driver_type="JAVA"&
&&&&&&&&&&&&&&&&&& &ClassPath location=”javacase/jar/cvsLoader.jar”/&
&&&&&&&&&&&&&&&&&& &JobOutput name="$TESTVERSION"/&
&&&&&&&&&&&&&&&&&& &Run path="cvsLoader.getFiles "&
&&&&&&&&&&&&&&&&&& &/Run&
&&&&&&&& &/Java&
&&&&&&&& &VBS name="VBS_Install_Client" description="使用VBScript脚本完成机票系统客户端的安装" &depends="getTestCaseFromCVS" driver_type="VBScript"&
&&&&&&&&&&&&&&&&&& &Lib location=”common\lib\lib_install.vbs”/&
&&&&&&&&&&&&&&&&&& &Run path="testcase\vbs\install_client.vbs"&&/Run&
&&&&&&&& &/VBS&
&QTP name="QTP_bookFlight" description="调用QTP脚本完成机票的预定"& depends=" VBS_Install_Client" driver_type="QTP”&
&&&&&&&& &JobOutput name="$FlightNo"/&
&JobOutput name="$CustomerName"/&
&&&&&&&&&&&&&&&&&& &Lib location=”common\lib\lib_utilityvbs”/&
&&&&&&&&&&&&&&&&&& &Run path="testcase\qtp\qtp_bookFlight"&&/Run&
&&&&&&&& &/QTP&
&Selenium name="Selenium_queryFlighOnWeb" description="调用Selenium脚本通过web查询订单的信息是否正确"& depends="QTP_bookFlight" driver_type="SELENIUM”&
&ClassPath location=”seleniumcase/web/selcase.jar”/&
&JobInput name="$FlightNo"/&
&JobInput name="$CustomerName"/&
&&&&&&&&&&&&&&&&&& &Run path="selcase.checkWeb"&&/Run&
&&&&&&&& &/Selenium&
&/TestJob&
以上TestJob文件描述了一个机票系统的完整的自动化测试流程,总计包含4个不同类型的TestJob,分别为getTestCaseFromCVS,VBS_Install_Client,QTP_bookFlight和Selenium_queryFlighOnWeb。 TestJob的depends定义揭示了AC的运行过程:
(1)AC会首先运行名为getTestCaseFromCVS的java测试案例,getTestCaseFromCVS从代码管理系统cvs中下载测试案例代码到本地。为后续的案例运行准备好执行环境。
(2) VBS_Install_Client的Vbscript脚本负责在本机windows上安装订机票客户端。
(3)QTP脚本QTP_bookFlight下了一张机票订单,并将订单号和乘客名输出。
(4)订单号和乘客名成为Selenium_queryFlighOnWeb的输入参数,Selenium脚本则完成web页面订单的查询和验证。
“不积跬步,无以至千里;不积小流,无以成江海”。—荀子《劝学》如果说自动化测试的成功实施是一副壮丽的山水画卷,那么测试脚本/程序的一行行代码就是这幅画卷里一个个彩色元素;如果自动化测试框架是一幢雄伟坚实的大厦,那么函数代码就是其中的一砖一瓦。因此,对于我们自动化测试开发人员来说,要想成功地构建并实施自动化测试框架,切勿好高骛远,必须要踏踏实实地掌握基本功,从学习开发高质量的测试程序或脚本代码开始,这才是一个训练有素自动化测试开发人员的成长之道。什么样的代码才算得上是高质量的代码?高质量的代码到底是怎样开发出来的呢?本章将以案例进行介绍并点评。
1.1& 案例1:脚本开始处首先进行环境检查下面是一段linux系统上运行的perl脚本代码,功能是调用产品后台管理位于$ORACLE_HOME/bin目录下的add_user命令,根据存储在users.txt中的用户信息列表,依次在产品系统中创建测试账户。
my $open FH, “& users.txt”;while (&FH&) {&&print “users are $_\n”;&$data=$_;}my @users=split(’,', $data);foreach my $val (@users){print “$ORACLE_HOME/bin/add_user –firstname $val –loginid $val –initial_password 123456 –email_address “;}
上面的这段脚本由负责产品安装测试的工程师小李开发,每次安装完被测软件系统版本后,自动地运行这段脚本,就能直接把测试用户信息等初始数据创建到数据库中去。但,可以看出要想能够成功运行该脚本,其前提条件是$ORACLE_HOME必须已经在linux系统环境变量设定,如下:export ORALCE_HOME=/home/oracle/10123/Orahome1这时,脚本代码print “$ORACLE_HOME/bin/add_user –firstname $val –loginid $val –initial_password 123456 –email_address “;会将$ORACLE_HOME替换成环境变量里设定的实际目录,实际执行如下:print “/home/oracle/10123/Orahome1/bin/add_user –firstname $val –loginid $val –initial_password 123456 –email_address “;
但这段脚本显然忽略了一个很有可能发生的场景,那就是在脚本运行之前,如果测试人员忘了设定或者设错了$ORACLE_HOME环境变量,脚本就会因为找不到add_user命令,报出一堆莫名其妙的错误。这会降低测试脚本执行的效率,提高诊断错误的难度。要想解决这个问题,就应该增强脚本的健壮性,在脚本开始处检测$ORACLE_HOME环境变量是否存在,并作相应地处理。修改如下:
#detect the $ORACLE_HOME, if not exist, then prompt info to user and exitif($ORACLE_HOME eq “”){&&&&&&& print “Error: Please specify the Beehive Home\n”;&&&&&&& print “\n”;&&&&&&& print “Usage:\n”;&&&&&&& print “& perl create_user.pl -beehome &BEE_HOME&\n”;&&&&&&& print “- beehome: The location of the Beehive Home.\n”;&&&&&&&}#end detectmy $open FH, “& users.txt”;while (&FH&) {&&print “users are $_\n”;&$data=$_;}my @users=split(’,', $data);foreach my $val (@users){print “$ORACLE_HOME/bin/add_user –firstname $val –loginid $val –initial_password 123456 –email_address “;}
修订后,脚本能够在第一时间内检测到环境变量的错误,并提示用户,然后退出,避免了错误扩散。
【思考1】一个产品安装脚本,在脚本开始处应该考虑做哪些环境检查?【思考2】在脚本开始时进行环境检测,那么在脚本结束时应该做哪些操作?
衡量一个软件自动化测试团队成熟度的一个很重要标志就是是否建立了测试脚本开发标准规范体系。
1.3.1 自动化测试为什么需要规范& 下面以一个实际场景故事来说明自动化测试开发规范的作用:场景主人公1:老王,团队自动化测试元老场景主人公2:老李,团队自动化测试元老场景主人公3:小李,跟随小李学习自动化测试场景主人公4:小王,跟随小王学习自动化测试场景主人公5:小赵,机房管理维护人员场景故事:&&&&& 某公司决定组建一个团队来开发自动化测试,老李和老王被选作自动化测试团队的成员,各自负责不同的模块开发测试脚本。他们上任之后,开始紧张忙碌地去学习测试工具,录制开发脚本,当然由于时间紧,他们两人各自忙碌着,没有时间去交流。一个月之后,对自动化测试的需求逐渐增大,公司决定增加两个新人手,小李和小王。按照公司“老手带新手”的惯例,老李负责带小李,而老王负责带小王。不出意料地,小李学习了老李一套编程风格和函数库规范,同样地,小王学习了老王的工作风格。不过到这里,一切工作都运行顺利,相安无事,因为他们一直负责各自脚本的开发,运行及维护。随着自动化测试规模的扩展,现在老王和老李的两个小团队已经开发出了数千行的自动化测试脚本代码,这么大规模脚本在提高测试效率的同时,也增加了脚本运行和维护的工作量。公司领导决定将所有的脚本交放到一个共享的脚本服务器上,并交付给一个专人-小赵去负责维护运行自动化测试。小赵拿到脚本后,试图在机房的一台崭新的服务器上运行这些脚本,但是结果十分令人沮丧,所有的脚本刚启动,就失败了。&&&&& 小赵立即通知老李和老王来查看脚本问题,但不凑巧的是,老李上个星期已离职,老王检查了他自己的脚本,找出了问题所在,原因是老王和小赵的主机系统环境不同,前者为windows XP系统,而后者则为Windows 2003.两个系统下的应用程序的默认安装路径是不一样的,导致启动失败而面对老李的脚本,老王无计可施,因为老李的脚本的风格和结构完全和他的不一样。不过幸好,还有小李在,小李费了九牛二虎之力,把“师傅”的脚本搞明白,修改了一段代码之后,脚本总算可以运行了。&&&&& 公司领导在听小赵汇报这个事情之后,意识到脚本的维护需要相关的注释和文档。于是安排小李给原先的脚本代码都加上不少于20%的注释。&&&& 但似乎噩梦还没有结束,小赵在维护运行的过程中,又发现了几个致命的问题。(1).有时在实际运行中,被测软件已经出现了问题,报出了“因故障暂时不能登陆”的错误,而脚本却视而不见,最后的结果还是成功状态。(2). 老王和老李的自动化运行产生的结果报告格式是不一样的,在有失败的情况下,小赵无法确认这是环境问题而需要重新运行一次脚本,还是真正的软件bug,他只能让小李和老王来查看结果并进行诊断。(3)&公司的产品有一个新功能需要自动化测试,这个功能是老李和老王的脚本都要调用的。看样子,把这个新功能的自动化测试脚本作为一个公共库文件应该是最合适的。但是很糟糕的是这个库文件根本无法做到共享,因为老王和老李对库文件的引用接口是完全不一样的!
这些都是对自动化测试的致命问题。第一个问题直接质疑自动化测试的有效性,第二个问题是有关自动化测试的可维护性,第三个问题则是自动化测试的可扩展性。这三个问题综合在一起,就动摇了自动化测试它在项目中本来的作用和意义。而出现这些问题的主要原因就是在一开始的时候,自动化测试项目没有尽早地建立相应的规范体系。
&1.3.2 规范应该考虑哪些因素规范(standards)是大规模自动化测试实施的一个重要先决条件。通常它也是一个团队自动化测试成熟经验的智慧结晶。它要帮助自动化测试团队建立如下共识。1. 测试工具市场有很多自动化测试工具,大多是基于录制-回放的。但在实现中,不同的工具有不同的侧重点,要根据项目自身特点来选择合适的工具。2. 自动化测试脚本库自动化测试脚本库的建立原则是每个项目应该有自己的脚本库,并且要保证脚本库里没有冗余的代码。比如我们有一个公共库函数负责创建随机数和随机字符串,那么这样的公共库函数有且只能存在一个。而且,在扩展函数库的时候,不应该影响到已有脚本正常调用函数库。3. 日志定义一个共用的日志策略对自动化测试维护来说非常有帮助,它可以让团队的每个成员都能理解和调试自动化产生的报告。策略要明确一些信息:1)日志采用什么格式?是文本还是html,还是xml?2)日志存储在什么地方?是放在文件系统里,还是数据库?3)自动化测试人员在什么情况下写日志?日志里包含哪些信息?4. 错误处理当脚本遇到错误的时候,应该怎样处理?应该立即退出脚本运行,还是清除环境再运行一次?如果比较复杂的话,就应该考虑建立一个错误等级制度,以使脚本遇到不同等级的错误时,做出不同的处理。5. 运行环境要明确定义脚本运行的环境要求,比如1)操作系统信息,是XP还是visita2)被测软件的安装情况3)是否需要其他产品的安装,比如测试outlook插件的前提是必须先安装outlook。6. 与框架的接口框架应该脚本传递什么样的参数信息?采用什么方式传递?这些信息包括被测系统的地址,需要运行的测试集合,测试账户,密码等等。7. 环境初始化及清除工作应该定义每个脚本在开始运行之前都应该做环境预检测和初始化操作,在结束的时候做环境的清除工作。每个脚本都要做这些操作,因此以公共函数库的方式提供给脚本开发者更合适些。8. 编码风格编码风格包括变量命名规范,函数定义,注释率等等
1.3.3 如何有效地推行自动化测试规范建立自动化测试规范是自动化测试实施的一个重要环节,但同时要注意的是,规范建立了,不一定代表它就会有效地被遵循。因此,在推行自动化测试规范的时候要注意以下几个因素1.团队充分参与在建立规范的时候,一定确保团队中的每个成员都要有效地参与,并最终达成共识。2.文档化规范要文档化。一份好的文档会大大提高组内成员的交流效率。3. 评审在规范执行的过程中,还应该建立定期评审的机制,以确认规范被切实地执行。
4. UI框架第四步:自动化测试工件的管理策略
自动化测试的实施和运行的过程中,至少会产生三种工件:(1)自动化测试案例脚本(2)自动化测试公共函数库(3)自动化测试结果报告一般来说,对于文件有两种管理策略(1)严格的版本管理策略比如代码管理工具clearcase,cvs等,它们的特点是提供了先进的版本分支和归并功能,并且同时具有非常严格的检入/检出机制。在很多成熟软件组织的版本控制过程中,开发人员修改一个文件要经过多层流程上的审核,多次测试之后,然后才可以进行归并等操作。因此,它的优点是保证安全性和稳定性,缺点是流程繁琐,效率不高。自动化测试工件采用代码管理工具的工作流程图如图7-25所示。&图7-25 基于严格版本管理系统的自动化测试脚本管理图
在上面的解决方案中,自动化测试脚本的版本分支与归并应该遵循其对应的被测软件产品源码的管理策略。比如1.0.1版本的软件产品代码下建立一个automation目录,专门存储自动化测试工件,这样,每当软件版本升级时,脚本也同样进行升级。【思考】:为什么这样做?
(2). 宽松的版本管理策略宽松的版本管理可以由文件目录存储来实现,通过规划文件目录层次和目录名来描述文件的版本结构。如图7-26所示。&图7-26 基于目录结构的测试脚本管理方案
需要注意的是,利用windows文件系统中管理自动化测试工件,一般要符合以下两个原则:(1). 一般地,目录结构的深度不超过三层,三层以上的目录会带来查阅的困难和维护工作量。(2). 因为在基于目录的代码管理策略中,版本由目录来描述。升级到1.0.2版本,就需要建立一个新的目录来存放1.0.2版本的脚本集。因此,我们的原则是尽量减少版本目录中脚本的个数,以减少相应的维护工作量
【思考】:我们为什么把function lib放在根下,而不是版本目录下?【思考】:针对目前的QTP自动化测试脚本,我们是采用严格的管理策略还是宽松的策略?那么在框架的实现中,又该如何整合这些管理策略?&到此,现在我们的框架如图7-27所示。&图7-27 UI框架管理方案
5. 自动化测试框架高级解决方案
在完成上述四个步骤后,我们的测试框架已经从从代码到策略到规范上,都有了一套实现和解决方案。到这里,聪明的读者从这一步步的框架完善的过程中,已经意会了框架到底是何物,没错,框架其实就是为解决我们在自动化测试中的种种问题而生。因此,框架不是我们自动化测试的最终目的,它只是高效高质量自动化测试的保障手段。为了提高自动化测试的效益和效率,我们开动脑筋,可以开发代码,可以制定规范,也可以重构流程等等,这些最后形成了一个有机的体系。这个体系我们给它取了个名字,叫软件自动化测试框架。
因此,可以推断,框架是一个自动化测试长实施过程中长期实践积累的最终结果。那么对于一个软件测试自动化刚起步的企业来说,就只能“摸着石头过河”,没有办法缩短这个过程吗?答案当然是否定。根据唯物分析观,世界上有万事万物,每种事物在本质上都具有共性和个性。因此,一个企业遇到的自动化测试实施问题可以划分为:全部问题=自动化测试的常见问题+企业的独特问题自动化常见的问题包括健壮性问题,执行拓扑问题和测试报告问题等等,这些完全可以借鉴一些成熟的经验和解决方案,而企业则把更多的精力放在解决个性问题上。这个通用问题的框架解决方案是什么?它又如何工作?这就是下章我们要介绍的主角-Automation Center分布式测试框架解决方案。
1.2.2 第二步:框架—数据驱动在经过第一步之后,虽然可以自动化测试,但是每次运行都会用“测试”,“UTF-8”两个常量做参数,这达不到我们的201个测试数据组合的目标。为了解决这个问题,我们要对常量进行参数化,使得每次运行都要提交不同的数据。这个过程叫做数据驱动。如图6-4所示。&图6-4 URLEncoder单元测试数据驱动数据驱动要考虑如下三个因素:(1)数据源选择什么类型?&数据源有很多种选择,比如1) 文本文件2) 数据库3)excel4)xml5)其他选择哪种数据源,要根据项目的需求和特点而定。以当前的项目要求来看,URLEncoder的单元自动化测试需要频繁地从数据源读取数据,数据库显然在性能上不太合适。另外,数据源至少要能存储不同语言的字符,比如德文,中文,日文,韩文等等,对数据源的要求就是要很好地支持unicode,因此xml和excel入围。如果我们的单元自动化测试要求在unix和windows下都能运行,那么excel作为windows应用被淘汰,而xml最终胜出。(2)数据如何被描述和组织?&在第一步里,我们看到有三个常量,strToEncode,strEncoding和strExpected。根据这个信息,生成mydata.xml如下。&?xml version=”1.0″ encoding=”UTF-8″ ?&&DataPool&&& &EncodeData id=”1″&&&&&&& &EncodeString&NLS_en_abcdefghigklmnopqrstuvwxyz&/EncodeString&&&&&&& &Charset&US-ASCII&/Charset&&&&&&& &Expected&NLS_en_abcdefghigklmnopqrstuvwxyz&/Expected&&& &/&EncodeData &&& &EncodeData id=”2″&&&&&&& &EncodeString&NLS_fr_àèòù&/EncodeString&&&&&&& &Charset&utf-8&/Charset&&&&&&& &Expected&NLS_fr_%C3%A0%C3%A8%C3%B2%C3%B9%3F&/Expected&&&& &/&EncodeData &&&& &EncodeData id=”3″&&&&&&& &EncodeString&NLS_zh_软件自动化测试框架-柳胜&/EncodeString&&&&&&& &Charset&gb2312&/Charset&&Expected&NLS_zh_%C8%ED%BC%FE%D7%D4%B6%AF%BB%AF%B2%E2%CA%D4%BF%F2%BC%DC-%C1%F8%CA%A4&/Expected&&&& &&/EncodeData&&&& &EncodeData id=”4″&&&&&&& &EncodeString&NLS_ja_なリンクをクリックすると&/EncodeString&&Charset&ISO-2022-jp&/Charset&&&& &Expected&NLS_ja_%1B%24%42%24%4A%25%6A%25%73%25%2F%24%72%25%2F%25%6A%25%43%25%2F%24%39%24%6B%24%48&/Expected&&&& &/&EncodeData&&/DataPool&
(3)代码实现data层驱动函数如下:import java.net.URLEpublic class TestURLEncoder{&& public static void main(String args[])& {try{//初始化数据源,即完成从xml文件到对象的存储&& MyXMLData data=new MyXMLData();&& For (int i=0;i&data.getSize();i++)& {String strToEncode = data.get(i).getValue(“EncodeString”);String strEncoding= data.get(i).getValue(“Charset”);String strExpected= data.get(i).getValue(“Expected”);;//调用URLEncoder&String strAfterEncoded = URLEncoder.encode(strToEncode, strEncoding));&//对比&If(strAfterEncoded== strExpected)&&&//输出&&System.out.println(”Pass: Verification is successful”);Else&&System.out.println(”Fail: Verification is fail”);}}catch(Exception e){&& e.printStackTrace();&& System.exit(1);&}}}
作了如上修改之后,单元自动化测试框架实现了两个目的。(1). 每次测试URLEncoder的数据都通过MyXMLData对象从数据源mydata.xml中提取(2). mydata.xml有多少条EncodeData记录,For循环就会运行多少次,从而实现了数据源灵活扩展的目的。为了达到上述的目标,我们需要自己开发MyXMLData类,至少实现三个方法1)MyXMLData()初始化方法,实现从xml文件里读取数据2)MyXMLData.get(int i)方法, 按序号获得某条记录,以哈希表的方式返回3) MyXMLData.get(i).getValue(String)方法,通过key名获得某条记录的字段值,即我们想要的EncodedString,Charset,Expected。
【注意】:MyXMLData就是我们测试框架的data层的雏形。
【注意】:第二步的整体思路其实就是Junit的功能雏形
自动化测试架是怎样产生的?到底什么是框架?为什么框架是自动化测试发展中一个不可逾越的阶段?它到底能帮助我们解决什么问题?我们本章将围绕着这些问题去和软件自动化测试框架进行一次亲密接触。测试框架(Test Framework)作为实现高效率高质量自动化测试的完整解决方案,从诞生之日开始,越来越多的软件组织和个人用自己的逻辑去诠释测试框架,所以我们看到了,一套测试管理系统被称之为测试框架,一个测试工具被冠以关键字驱动框架之名,甚至,一段程序也可以声称其实现了数据驱动的框架理念。在如此纷纭的头脑风暴中,测试框架犹如盲人摸象中的那头大象一样,有人说它是一个软件,只不过它的功能是测试另外一个软件,有人认为它是一套流程和规范,否则怎称框体架构。本书的观点是,所谓“测试框架”这个概念名词只是一个封装了很多东西的盒子,这个盒子的外观和形状对我们来说无关紧要,我们最关心的是这个盒子到底存放了什么东西。所以,如果只是停留对概念咬文嚼字的层面,而不整理其内在的发展动力和脉络关系,这就成了“买椟还珠”的现代版。因此,本章的目的是旨在帮助读者打开测试框架这个盒子,理清其中的脉络。让我们一起追随自动化测试的发展历程,看看自动化测试框架是怎么产生的,对于自动化测试的发展,可以分为三个阶段。
1.1& 测试的自动化-以工具为中心自动化测试是在软件质量要求日益提高,测试工作愈加繁重的背景下横空出世的。显然在自动化测试诞生之初,测试人员最迫切的愿望就是通过自动化测试的实施来摆脱重复的工作量,即回归测试中的案例执行工作。怎样完成这个从测试案例到测试程序的转化呢?显然,使用已有的自动化测试工具解决方案是最有效的。因此,这个阶段最明显的特征是所有的自动化测试实施工作是以工具为中心,在这个阶段的过程中,要完成的工作如下:
…………………………………………………………………
&1.2 百家争鸣-形形色色的自动化测试框架在众多书籍和网络论坛中,经常被提到的有代表性的自动化测试框架思想有以下几种形式:1.2.1& 数据驱动测试框架(The Data-Driven Testing Framework)
1.2.2关键字驱动或表驱动测试框架(The Keyword-Driven or Table-Driven Testing Framework)
1.3 自动化的测试-测试框架应该是这样的如果说前面谈到的自动化测试实施还是在一个点上下功夫,那么本阶段就是在一条线上作战了。“自动化的测试”的内涵更加丰富,它意在将软件自动化测试中所涉及的各个环节作为一个统一的整体考虑,从测试脚本的管理,测试脚本的执行到测试报告的展现都有相应的策略,规范定义及自动化实现,故称这个阶段为“自动化的测试”。
简而言之,我们在自动化测试实施中会遇到各种各样的问题,有的是关于流程,有的是关于自动化测试本身,还有的是关于规范等等,这些问题不可能通过单一的自动化测试编程手段解决,而是需要一个有机的系统的解决方案,这个解决方案就是测试框架。
因此,测试框架相比单个的测试脚本具有以下特点:a.测试框架位于软件测试的战略规划层次,而非执行层面&很显然,测试框架在测试流程上表现为手工测试与自动化测试的整合策略,在组织上是一套自动化测试管理开发及执行的规范。这些改变对传统手工软件测试的工作内容和方式的影响是巨大而深远的。b. 测试框架具有组织上的延续性和软件上的扩展性&测试框架在软件测试组织中的建立和成熟是一个长期的过程,一旦建立,测试框架就可作为组织的知识经验甚至文化的一部分,随着团队的发展而延续,同时,由于被测软件的更新和测试人员技能的不断完善,测试框架也是一个不断进行扩展和更新的发展过程。这必然就对软件框架要求在软件上具有较高的扩展性性。
那么自动化测试框架作为一个整体解决方案,到底包含哪些组成部分呢?
引: 毫无疑问,从企业的立场来看,它期望自动化测试能为企业带来生产效率的提升和测试成本的缩减,说通俗点,就是能用尽可能少的人干尽可能多的事。因此对于那些能够在自动化测试领域做出突出成绩的测试人员,企业从来都是一贯地不遗余力地进行奖赏和激励。因此,在自动化测试领域里,一方面如我们前章所说布满了风险和陷阱,同时另一方面,我们更应该看到充满了很多的机会,对测试人员的职业生涯发展有着至关重要的影响。好,聪明的你上场了,你正在接管一个正在做手工测试的团队,或者你目前就处于这样的一个团队里,而老板对自动化测试概念又知之不多,不能给予你完全信任的强有力支持,你如何在重重困难中,推行自动化测试实施,而最终取得团队和个人的最大成功?这是我们本章要讨论的重点。
一个好的目标,首先它能够赢得老板的眼球,并有可能逐步转化为老板对你自动化测试实施的支持。自动化测试项目的实施离不开上级领导的支持,这是一个组织上很关键的因素。因为自动化测试前期的准备要投入人,时间,金钱等资源,比如自动化测试需要买工具,工具则需要培训,而开发工具脚本又需要投入人和时间,如果领导不能在这些方面给予支持,测试人员就真的就成了“巧妇难为无米之炊”,自动化测试的成功更无从谈起了。所以,在自动化测试的启动阶段,一定要先有一个好的而且可行的自动化测试的目标或想法,它会吸引老板的注意力,并可能获得支持。尤其在自动化测试实施已经比较成熟的企业里,在众多自动化测试解决方案里,一个让人耳目一新甚至拍案叫绝的方案会给老板留下深刻的印象。
但是对于自动化测试刚起步的企业来说,有一些需要特别注意和警惕的地方。这是因为,在知识和经验都不丰富到足以洞察自动化测试本质和规律的时候,很多老板表面上对自动化测试是热情的支持,但实际真实的态度却是底气不足,半信半疑。我曾遇到过两个极端的例子,一个是某通讯企业的研发总监,在软件开发和测试领域都有深厚的经验,但对自动化测试却有着深刻的怀疑,他认为QTP等测试工具并不能真正地从根本上解决测试效率的问题,因此他一直下意识地回避和推迟团队中自动化测试的实施;而另外一个例子是某大型外企的测试经理则是一个技术专家,他对软件自动化测试十分地钟情,几近狂热,认为任何工作都可以交付给程序来做,因此他把自动化测试推到了极致,他的团队开发了大量的脚本和程序,有的只为demo,有的只为验证bug。这两个极端的例子其实是当前软件业界自动化测试实施的缩影,实际上,这两个人的表现更像是同一个人的两面性格,自动化测试上马时盲目乐观,失败后“恨屋及乌”。一番折腾下来,他们对自动化测试是敏感和谨慎的,对于你提出的任何自动化测试目标,他们表面上会支持,实际上更多采用的是观望态度。换句话说,在这种情形下,老板对自动化测试项目的支持是犹豫的和脆弱的。因此,老板是否能够保持对你强有力和持续的支持,不光你要有一个好的自动化测试目标,而是更取决于后续的自动化测试实施能带来实实在在的效益。&
【案例】:测试主管小王打算在自己的测试部门实施系统测试自动化,在经过工具评估后(有关评估详见第三章Evaluation一节),他和他的团队决定使用java开源的selenium做为测试工具。这个想法获得了小王上级张总的认可和支持。挑战:小王在着手实施的时候,有如下疑惑和困扰:(1)小王和他的团队没有丰富的自动化测试实施经验,因此,虽然经过了前期的测试自动化效益估算,但对于selenium的解决方案到底能否在项目中实施成功,要开发投入多少人力,维护量有多大,小王依然心里没有十足的把握。(2)小王的上级张总是一个雷厉风行的人,他对这次自动化测试的实施也抱有很高的希望,小王如何能够说服张总认识到自动化测试实施的风险,并能给予理解和持续的支持,这是一个要考虑的问题。
对策:小王决定采取以下的措施来最大程度地减小风险,并获得张总的理解和支持。(1)对于第一个问题,由于对测试脚本程序的规模和功能都无法准确预测,小王决定采用快速原型法来开发自动化测试程序,首先在部分核心功能模块中做试点,一边实施一边总结经验,然后再将成功经验进一步推广到整个产品模块。(2) 关于和张总的沟通交流问题,小王决定先准备一个自动化测试的演示程序,邀请张总参加演示会。在演示会上,小王准备了三个演示点,一个是有关自动化测试能替我们做那些工作,一个是自动化测试不能替我们做的工作,另外一个是自动化测试运行中的各种风险和干扰因素。结果:最后实施的结果是:a. 小张通过快速原型开发方法,以时间为代价换来了自动化测试实施的稳定和高质量,这为自动化测试的成功实施提供了技术保障。b. 张总对演示会的内容十分感兴趣,并且和小王约定每隔一个月就进行一次演示会,以便了解自动化测试的状态和进展,并及时解决中间出现的问题。这为自动化测试的成功实施提供了组织保障。
序:PERAL模型的实施背景严格意义上来讲,在软件领域中,“过程”是一个外来词,我们很难从中文的字面意思上去把握它的精髓所在,它的内在含义是来自英文的process,通常用在软件流程,软件规范的描述和定义上,比如CMM中的各种software development process,Test process,qa process等等。这些process指的是为了达到目标而执行的一些方法原则和操作步骤等。需要特别注意的是,这些方法和步骤不是从天生就有存在的合理性的,否则就成了教条主义,它们其实是在不同项目不同组织中总结形成的行之有效的通用经验,为我们所用的(不是用来仰视和崇拜的)。因此,我个人倾向认为用中文的“章法”来表达“process”更为准确。如何规划和实施一个成功的自动化测试呢?根据经验总结,我们如果能够遵循一些章法,就可大大降低失败的风险。所谓章法,就是一步步来做,每步都有自己的关注点,在本步的问题未得到解决之前,不得继续下一步,从而避免问题向下扩大,最终导致失败。自动化测试的章法就是我们下面要介绍的PERAL模型。第一步Purspose(目标):如何建立一个务实明确的自动化测试目标?
第二步Evaluation(评估):如何量化评估自动化测试规模并选择合适的工具?第三步Architecture(构建):如何构建和设计自动化测试?
第四步 Run and debug(开发调试):如何开发和调试自动化测试?
第五步Link with manual test(与手工测试链接):如何将自动化测试与手工测试进行有效的整合?
& Purpose:如何建立一个务实明确的自动化测试目标一个务实而明确的自动化测试目标是自动化测试成功的第一步,反之,则是噩梦的开始。回顾前面那个情景故事,李经理试图把123个测试案例全部自动化,这是一个不切合实际的主意,却从未得到任何质疑和纠正,导致后来小张只是为了运行而运行自动化测试,完全成了“政绩工程”。务实的目标必然是可实施的,明确的目标必然是某种程度的量化。怎样构建一个务实而明确的自动化测试目标呢?可以通过三个问题来摸清其轮廓:
问题1:自动化还是手工?这是一个问题为什么要做自动化测试?我们常看到这样的理由:A. 节省手工测试的人力和时间成本B. 有助于提升测试团队的技术力量C . 能够生成直观的图形化报表D. 我不知道,领导要求做的如果你来负责决策是否自动化测试,而且ABCD都是你的考虑因素,贪心将注定你最后什么也不会得到。正确的答案是只有一个A,只有A才是我们自动化测试的目标。这是一个非常简单而朴素的道理:自动化测试的横空出世,是为了帮助手工测试解决繁重的工作压力,我们在自动化测试实施中所做的任何工作的目的都是最终能够节省手工测试的成本,如果离开了这个指导思想,自动化测试就成了浓妆艳抹,面目全非的女人。【案例】我在某知名软件测试网站上曾看过某高人写的一个自动化测试解决方案,真叫人叹为观止,从测试程序的版本化管理系统,到bug的提交与存储系统统统都塞入自动化测试解决方案之中,似乎包罗万象,无所不能。我虽猜不中这个自动化测试项目的开始,但我确信我能预测到它的轨迹和结局,要么实施起来因技术资源不足而中途流产,要么因为投入远远大于产出而被老板最后执行枪决。这是一个痛苦的从生到生不如死再到彻底死亡的过程。不幸地是,我发现这样的一个自动化测试构想却在网上倍受测试人员欢迎,顶礼膜拜。这不由让我对业界自动化测试的前景有些担心:我们正在赋予测试自动化更多的理想符号,而忘记了它的本来的意义。正象一首歌的歌词形容的:我们都在赶路,却忘记了出路。
因此,自动化测试是为了节省测试成本的这个指导思想应该一直贯穿在自动化测试设计到实施的过程中,最后评价自动化测试是否成功的标准不是测试程序有多么复杂多么大规模,实际上,一个灵光突现的想法+一段精短而实用的测试程序就可能是一个非常成功的自动化测试实施,只要它最后真正地节省了软件测试的人力成本或时间成本。
要怎么判断是否“节省了软件测试成本”,甚至度量“节省了多少测试成本”呢?下面,我们来看一下自动化测试的效益分析。
1.1.2 问题2:如何估算分析自动化测试效益?在市场经济的今天,做任何事情都讲究经济效益,效益就是投入产出比,投入越少,产出越多,效益就越好。怎样度量测试自动化的效益呢?当然,要做的第一步就是要找出测试自动化的投入成本和收益。
1.1& 企业自动化测试实施的情景故事
1.1.1& 自动化测试实施故事背景介绍顶级公司是一家国内小有名气的软件企业,经营项目主要是为移动和电信客户提供软件产品解决方案,随着电信业的发展,公司规模也在蓬勃扩张,从2000年到2008年,软件开发团队已经有了一百多人。看到这样的局面,公司管理高层又喜又忧,喜的是电信市场扩大给公司带来很多机会,忧的是电信软件市场竞争日益激烈白热化,客户对产品的质量要求一天比一天“苛刻”,而发布给客户的软件的问题总是层出不穷,解决不完,客户似乎对本公司产品抱怨越来越多,这样下去,势必会影响公司的业绩,甚至是将来的生存。顶级公司的管理高层已经看到了这个危险的信号,决定把软件质量提升一个重要的高度,并计划在管理高层设置一个产品质量总监的角色,他们最终选定了在外企具有多年软件质量管理经验的黄先生。黄总监上任后,分析了顶级公司软件组织中存在的问题,做了如下两件事。第一,组建正式的软件测试团队,成立独立的软件测试部门,并建立规范的软件测试流程,希望使得软件测试更加有力和有效。第二,推行自动化测试,来实现“测多”和“多测”,希望可以使手工测试人员从重复性的劳动解放出来,而把精力投入一些“灰色区域”测试,来发现更多的潜在的bug。
1.1.2 自动化测试实施场景回放在这样的一个局势下,作为新成立的测试部门的负责人,李经理虽然手下“兵不算多,马不算壮”,团队一共有4个手工测试人员,但是新组新气象,大家都摩拳擦掌,想尽快作出一番业绩来。李经理所在的测试部负责一个电信管理平台的测试,基于web 的UI。由于客户经常提出对UI的修改要求,每一次修改,就要进行一轮的手工测试,因此重复工作量非常大。1.【决策】【人物】:李经理,测试人员小张,小赵,小孙等【地点】:某次会议上李经理:我统计了一下,客户这个月提出产品界面和功能的修改有15处,开发部修改了代码后,工作量和时间的压力就传到了我们测试组,所以这个月大家忙得焦头烂额,不停地手工回归测试,大家对这种局面有什么想法和建议?
小孙:太郁闷了,开发人员三天两头就提交一个版本,我现在每天都在重复测试同样的功能和界面,真不知道我们现在的工作到底是有什么意义。
小张:回归测试也不能不做,昨天我发现开发人员修改了查询模块后,导致管理员用户无法登陆系统了,这样的问题要是到了客户那里,就严重了。
李经理:对,回归测试必须要做的。
小赵:对了,我在网上看到有人说,使用第三方测试工具QTP,只要录制一次,就能自动生成脚本,然后回放脚本,QTP就能像人一样在Web页面上进行点击,输入等操作了。如果真能这样,我们让QTP来帮我们做测试,怎么样?
李经理:恩,这是个好主意,前两天开会时,黄总监还提到要推广实施自动化测试。咱们争取做在前头,小赵,就由你来负责一下这个事吧,你研究一下QTP自动化测试的可行性,如何?
小赵:。。。好的,给我一个月的时间。。。。。
2.【预研】距离决策,两个星期过去了【人物】:李经理,小赵【地点】:小赵的电脑旁
李经理:小赵,QTP研究得怎么样了
小赵:唔,我已经使用QTP自带的flight demo程序,学会了录制和回放脚本,但是我也发现QTP不是当初想象的那么简单,因为我录制我们的测试案例,发现所有的菜单操作回放的时候都报出错误了。在网上查了一些资料,据说是对象识别的问题,所以我现在正在研究对象库,还没搞明白,可能我还需要一个月的时间。。。
李经理:看来实际困难超出我们的估计了,小赵,你有把握再过一个月就能解决问题么?
小赵:这个,我也不太确信,因为我也无法预测前面还会有什么问题。但是我觉得如果请专业人士给我们做个QTP培训,应该会有很大帮助。
李经理:恩,有道理。
3.【改变】距离决策,一个半月过去了【人物】:李经理,测试人员小赵,小张,小孙【地点】:某次会议上
李经理:上个月我们请QTP自动化测试专家做了一次培训,大家对QTP自动化实施有什么进展么?
小赵:我现在已经能够录制和回放我们的测试案例了,我们的模块一共有123个测试案例,从编号1开始逐个做录制和回放,到现在总共完成了11个了。
李经理:恩,不错。不过我们还可以再快些么?按照目前的速度,全部做完要五个月啊。我希望我们不要落在别的部门后面。
小赵:这个,QTP脚本是基于VB script的,我以前没有编程经验,调试脚本比较花时间。。。
李经理:原来这样。开发脚本其实也就是开发程序。对了,小张,我记得你以前做过vb script语言的开发有两年的时间,你能不能从小赵这里接手这项自动化测试任务?争取一个月后,让所有的自动化脚本都能运转起来,怎样?
小张:好,我尽力。
4.【成果】距离决策,两个半月过去了【人物】:李经理,测试人员小赵,小张,小孙【地点】:某次会议上
小张:我昨天终于完成了任务,用QTP完成了123个测试案例的自动化,下面我给大家演示一下成果。。。(小张演示)
李经理:非常好,看来我们往下就可以用这些脚本做回归测试了。
5. 【结局】却是【结局】(1)小张因为自动化测试演示的成功,展示了其软件开发能力,而获得了一个开发职位,于是,他毫不犹豫地转到开发部去了。
(2)小张留下了数千行的脚本代码,而无任何文档,因此没人能看懂,更谈不上对脚本进行修改和扩展。但是脚本还可以继续运行,因此测试部门还沿用它来做回归测试。
(3)在回归测试中发现,产品界面一旦变更,就会有部分测试案例运行失败,测试人员花了很长时间才定位出这不是产品的问题,而是脚本的问题。
(4)在多轮回归测试之后,产品终于发布给用户了,但是仅仅过了一天,用户就愤怒地打电话投诉到顶级公司:产品有一个非常重要的管理功能根本就不能work。李经理赶紧调查,发现这个功能正是一直由脚本来进行自动化测试的,但奇怪的是,虽然这个功能有问题,但自动化测试从来没有报过错。经过排查认证,了解到,小张当时为了能让脚本迅速运转起来,省却和忽略了一些检查点和验证的功能。
(5)李经理离职后,新一任测试经理上任后,认为原有的自动化测试文档不全,设计不清,维护不力,所以他决定弃用原先的脚本,重新开始开发自动化测试。
相信很多有过自动化测试经验的朋友对这个故事的场景都不会感到陌生,故事的结局更有写实主义的残酷意味,我们仿似看到一个轮回又开始了,自动化测试之路上的人们又从零开始苦苦寻找出路。没错,这就是目前企业自动化测试实施的普遍情形,“做的人不少,成功的不多”是业界的一个真实写照。那么,对于那些将要踏上和已经走在自动化测试之路上的人来说,测试是否真的能够并且值得自动化?我们所期望的,究竟是镜花水月般的一个海市蜃楼的神话?还是一个真实存在并可及的“理想国”?如果我们能够再次遇见李经理,很想听听他的看法和答案。
1.2.2软件自动化测试的推动力
上面的单元测试自动化,我们开发了近百行的测试代码去测试一个代码行为10行的函数;在UI测试自动化,则调用了IE的COM接口去驱动IE application,以模拟在界面上的两个动作,输入“测所”和点击“搜索”按钮,总共9行代码(如果考虑自动化健壮性的话,还要增加错误处理代码)。观察到这些,我们暂且不考虑自动化测试开发之后的维护,至少可以有一个直观的认识:从手工测试向自动化测试的转变是要付出的成本的,而且这个投入要远比做一次手工测试的代价要高,比如,一个有经验的自动化测试开发人员完成一段健壮的100行左右的测试脚本大概需要一天左右的时间,而手工完成这个功能点的测试则只需要10分钟。一天VS十分钟,按理说,这是一个赔本的买卖,但为什么还有这么多的软件企业对测试自动化情有独钟呢?排除一些盲目跟风,试图提高测试技术含金量的情感因素,至少有以下几个理性的现实驱动力。1. 测试自动化主要是做长线投资,而非一时之计显而易见地,开发一个程序,只为了运行一次自动化测试是非常不划算的。那么要想能收回开发自动化测试的投资,就要尽可能多地运行测试程序,每多运行一次,就会多节省一份手工测试工作量。这个简单的道理可以说明为什么如今测试自动化应用最多的就是回归测试阶段。由于回归测试往往是验证软件bug的fix或者软件补丁的有效性,理论上,每一次bug的修复,都需要进行一次全面回归测试。如下图1-5所示。
& && && && && & 图1-5 回归测试周期图&&& &这样在软件测试流程里,回归测试包括在测试分支(Test Branch)上进行的bug验证测试,还有在发布分支(Release Branch)上进行的补丁更新测试(在实际的企业实践中,发布分支的更新远远比图中频繁),这样回归测试的重复性就非常高,而且持续时间长,直到软件在市场上的退出才结束。这对于手工测试人员来说,可以说是一个对耐心和毅力的巨大考验,再美好有趣的事情如果天天重复去做,而不做任何变化,最终也会成为枯燥乏味的代名词。所以手工测试人员是有愿望通过自动化测试来改变现状的。这就为回归测试自动化的实施同时提供了主观的动机和客观需求。【案例】:一些有经验的软件测试团队通常会采用一些激励或游戏规则来增加回归测试的趣味性,我曾看过一个TOP500的软件企业里的测试部门,每隔一段时间就会由高层发起一个“虫子打猎”(Bug hunting)的活动,通常在一个不太繁忙的周五午后,通知邮件一发出,全体部门立即行动,不论职务高低,不分经理,工程师,纷纷赤膊上阵。为了找到猎物,每人都各显神通,尽可能地设计一些平时想不到的测试场景去寻找软件里的bug,但有一个前提条件,就是他不能测试自己本来负责的系统模块,必须去测试别人的而且他不熟悉的的模块。比如小张是负责测Email的,那他在这次活动中,偏偏就要去测试Messenger;测试messenger的小李这次又要去测试calendar,这完全是一个网状交叉的测试。打猎活动结束后,高层还要召开“庆功会”,评定出“最好的bug”,“最有创意的bug”等等称号,虽然没有奖金,但是每个获得荣誉的人都会倍感自豪。而且,对于团队来说,打猎活动收到成效也是显著的,是一举三得的好事情。第一,交叉测试会找到以往被忽略的bug。第二,熟悉不同模块,测试人员将来可以在工作中互为备份。第三,增强了团队凝聚力,并激发对测试工作的热情。<font color="#. 测试自动化可以随时触发运行测试自动化一旦开发完成,就可以在任何时间被触发运行,而没有下班或周末的概念,测试人员完全可以在下班之前触发某个自动化开关,把测试任务移交给自动化脚本,然后经过一夜的运行,第二天早上上班来查看自动化测试报告,这是自动化的独特优势所在。从这个意义上讲,测试自动化延伸了手工测试的工作时间和范围。【思考】怎样根据自动化测试运行时间和方式,在自动化测试的运行效率和健壮性之间的平衡取舍?<font color="#. 测试自动化有助于知识的存储和移交这是一个潜在的事实,在以前的手工测试一统天下的时候,测试人员的知识主要是靠文档存储,比如测试计划,测试案例说明书,bug数据库等等。因此,我们看到,当一个测试工程师离职的时候,他会把他的知识以文档的方式留给原来的团队。而随着自动化测试的发展,这种测试知识的形式也在发生变化,测试人员的技术可以通过测试程序保留下来。对整个测试团队来说,能够量化共享的知识越多,团队就越稳定,受到个体测试人员的影响就越少。这是老板愿意看到的场面,因此,从这个角度来说,测试经理比测试工程师更有动力去推动软件测试自动化。<font color="#. 第三方自动化测试工具的使用提高了自动化测试开发的效率
如果说前三点已经讲清了自动化测试的合理性动机,那么自动化测试工具的应用则为自动化测试实施提供了保障,使得做自动化测试不在那么困难和复杂,而变得简单和有效率。使用Junit来完成案例一import junit.framework.TestCpublic class funTest extends TestCase {&&&& protected void setUp() throws Exception {&&&&&& super.setUp();&&&&& }&&&& protected void tearDown() throws Exception {&&&&& super.tearDown();&&&&& }&&&& public void testFun() throws Throwable {&&& //调用被测函数&&&&int i = Fun(2);&&& //使用junit提供的assert断言语句比较结果&&& assertTrue(1,i);&&&& }}在以上代码中, funTest类,以及funTest类的setup函数和teardown函数(环境回收工作)是由Junit自动生成的,我们写的测试程序只有2条语句,其中断言语句assertTrue会通过比较,给出pass还是fail的结果报告。可以看出,使用Junit工具帮我们减少了自动化测试开发的工作量使用QTP来完成案例二,如下:使用QTP录制同样的google搜索操作,只有两条语句生成:Browser("Google").Page("Google").WebEdit("q").Set "测所"Browser("Google").Page("Google").WebButton("Google 搜索").Click其中Browser,page,webEdit,webbutton都是QTP提供的对象,操作起来非常直观方便。【思考】:使用自动化测试来verify bug合不合算?结合实际情况,用数据分析一下。
第一篇 初级篇——认识自动化测试框架&
&&&& 第1章 将降大任——自动化测试 
&&&&& &1.1 软件测试面临的困境与迷
&&&&& &&1.1.1 软件质量困境 
&&&&& &&1.1.2 软件成本困境
&&&&& &1.2 “时势造英雄”——软件测试自动化的异军突起 
&&&&& &&1.2.1 软件自动化测试如何代替手工测试 
&&&&& && 
& 第2章“神话”破灭——自动化测试能否担当大任 
&&&&& &&2.1.1 自动化测试实施背景介绍 
&&&&& &&2.1.2 自动化测试实施场景回放 
&&&&& &2.2 自动化测试的“神话”破灭 
&&&&& &&2.2.1 昂贵的自动化测试实施成本
&&&&& &&2.2.2 实际上并不强大的自动化测试脚本 
&&&&& &&2.2.3 自动化测试实施的命门:维护成本 
&&&&& 第3章 成功之道——如何构建高质量的自动化测试 
&&&&& &3.2 Purpose:如何建立一个务实明确的自动化测试目标 
&&&&& &&3.2.1 问题1:自动化还是手工测试 
&&&&& &&3.2.2 问题2:如何估算分析自动化测试效益 
&&&&& &&3.2.3 问题3:如何构建高收益成本比自动化测试目标 
&&&&& &3.3 Evaluation:评估和估算的量化决策指南 
&&&&& &&3.3.1 工具选择定律一:测试界面决定工具类族 
&&&&& &&3.3.2 工具选择定律二:测试项目综合特征确定工具应用方案
&&&&& &&3.3.3 工具选择实际案例分析 
&&&&& &&3.3.4 总结 
&&&&& &3.4 Architecture:构建和设计自动化测试 
&&&&& &&3.4.1 自动化测试的最终用户是测试工程师 
&&&&& &&3.4.2 自动化测试的实质是开发一个测试软件
&&&&& &3.5 RuncandcDebug:开发调试 
&&&&& &&3.5.1 高内聚和低耦合的模块实现原则 
&&&&& &&3.5.2 数据驱动原则 
&&&&& &&3.5.3 自动化脚本开发质量优先级 
&&&&& &3.6 LinkcwithcManualctest:自动化测试与手工测试的有效整合 
&&&&& &&3.6.1 自动化测试和手工测试的关系 
&&&&& &&3.6.2 自动化测试与手工测试流程整合
&&&&& &3.7 PEARL模型实施成功经验 
&&&&& &&3.7.1 重置目标,39长远规划 
&&&&& &&3.7.2 强大的自动化测试框架 
&&&&& &3.8 总结 
&&&&& 第4章 组织实施——怎样建立与培养自动化测试团队 
&&&&& &4.2 明确自动化测试目标
&&&&& &&4.2.1 好的目标是自动化测试实施的发动机
&&&&& &&4.2.2 建立一个高收益并可行的自动化测试实施目标
&&&&& &4.3 积极有效的沟通技巧
&&&&& &&4.3.1 勤汇报,多交流 
&&&&& &&4.3.2 实用为先 
&&&&& &4.4 培养和建立自动化测试团队
&&&&& &&4.4.1 手工测试团队的规划 
&&&&& &&4.4.2 自动化测试实施中的团队
&&&&& &&4.4.3 自动化测试实施后的团队
&&&&& &4.5 自动化测试技术储备 
第二篇 中级篇——自动化测试框架基本原理及实现
&&&&& 第5章 庐山真面目——自动化测试框架
&&&&& &5.2 测试的自动化——以工具为中心
&&&&& &5.3 百家争鸣——形形色色的自动化测试框架
&&&&& &&5.3.1 数据驱动测试框架(ThecData-DrivencTestingcFramework) 
&&&&& &&5.3.2 关键字驱动或表驱动测试框架
(ThecKeyword-DrivencorcTable-DrivencTestingcFramework)
&&&&& &5.3.3 总结 
&&&&& &5.4 自动化的测试——测试框架原型 
&&&&& &&5.4.1 框架包括的具体技术 
&&&&& &&5.4.2 框架的用户 
&&&&& &&5.4.3 制定和开发框架
&&&&& &5.5 测试框架集大成者——无需人工干预的自动化回
自动化测试是当今软件测试行业一个很受关注的方向。目前实在业界实施施比较成熟的是性能测试自动化,其代表的技术有LoadRunner等工具。
但在系统测试自动化方面,包括UI测试自动化,单元测试自动化等领域,虽然可以用强大的第三方测试工具作为解决方案,如QTP、WinRunner、Selenium,Junit等,但在具体实践中,却鲜有企业依靠某个工具实施测试自动化的成功案例。
究其原因。首先,系统测试运作涉及企业成本流程、技术、人员组织各个方面,虽然理论上利用测试工具进行自动化测试可以替代部分工作,但在实践过程中并不能完整地解决测试质量与效率、,投入与产出等一系列现实存在的矛盾。从这个角度来说,测试工具提供的测试技术只是自动化测试实施的一部分。其次,测试人员开发了一堆自动化测试脚本若没有具体的框架来规定实施和执行的原则,也会无用武之地,这就像象造车一样,只具备了零件等元素但缺少整体的造车图纸来指导使用它们。因此,现实的测试实践中,我们需要一个完整而务实的自动化测试解决方案,真正地实现达到高效高质量的软件自动化测试。
测试框架(Test Framework)作为实现高效率高质量自动化测试的完整解决方案,从诞生之日开始,越来越多的软件组织和个人用自己的逻辑去诠释测试框架,所以我们看到了种种说法,一套测试管理系统被称之为测试框架,一个测试工具被冠以关键字驱动框架之名,甚至,一段程序也可以声称其实现了数据驱动的框架理念。在如此纷纭的头脑风暴中,测试框架犹如盲人摸象中的那头大象一样,有人说它是一个软件,只不过它的功能是测试另外一个软件,有人认为它是一套流程和规范,否则怎称框体架构。
在本书的作者看来,所谓“测试框架”这个概念名词只是一个封装了很多东西的盒子,这个盒子的外观和形状对我们来说无关紧要,我们最关心的是这个盒子到底存放了什么东西,否则就成了“买椟还珠”的现代版。因此,本书旨在帮助读者打开测试框架这个盒子,把里面的“宝贝”呈现给读者。相信聪明的你读了本书之后,不会再追问测试框架到底是什么,而你会更关心怎样构建一个高效务实的自动化测试解决方案,从而获得测试团队和个人的成功。
&相信本文会对处于下面两种状态的测试工程师朋友会有所启发和帮助
1. 正要但还没开始做性能测试的朋友,除了loadrunner,不知道从哪里下手
2. 已经开始做性能测试,正在被一堆问题困扰得焦头烂额的朋友。
听说过有的工程师运行几轮性能测试,就能迅速定位性能bug;更多地是听到某工程师运行N多次,就是不能复现问题,甚至整个研发部门开发人员测试人员齐上阵,都无法找到性能问题所在。这是为什么呢?是运气不好么?还是技术能力不强?
说说我看过的一个真实的案例:某大型外企的产品上线后,当用户数超过某个值的时候,在线的软件系统就会重启。这是一个严重的bug,但非常糟糕的是,在测试环境里,测试人员无论如何,都复现不出这个bug,研发部门的老总调用了精兵强将,包括众多开发骨干,苦苦搜索一个多月,也都无终而归,最后的结果是企业最终失去了这个大客户。其实这样一个大型系统,面对这种问题,别说开发人员,就是比尔盖茨来了,也无济于事。
显然这不是技术能力范畴内能解决的困境,怎样使得性能诊断变得更加容易和方便?这其实是一个软件开发要考虑的可测试性问题。
对于性能测试来说,有必要在软件设计开发阶段遵守规范,建立一整套性能度量体系。体系包括
1. 性能诊断日志
2. 在应用系统层次上建立性能度量
3. 数据库系统性能度量
性能诊断log包括一系列log等级设置和log格式,使得性能问题能够在log层次上被捕捉到,比如下面是一个SMPP协议网关实现的log
TimeStatistic --------Statistic name&&&&&&&&&&&&&&&&&&&& : EnquireLengthDescription&&&&&&&&&&&&&&&&&&&&&&& : Time taken for a round trip ENQUIRE_LINK PDU.Measurement unit&&&&&&&&&&&&&&&&&& : MILLISECONDMeasurement start time&&&&&&&&&&&& : 5Last measurement time&&&&&&&&&&&&& : 3# times the operation was invoked& : 3max time&&&&&&&&&&&&&&&&&&&&&&&&&& : 19min time&&&&&&&&&&&&&&&&&&&&&&&&&& : 12total time&&&&&&&&&&&&&&&&&&&&&&&& : 46
在性能诊断模式开启后,软件程序就会每隔10秒钟打印如上信息,从以上信息可以很清楚地看到SMPP网管处理多少个PDU,每个PDU花了多长时间。这样会第一时间内捕获网管的性能处理效率。
在应用层次上的度量多种多样,根据应用的不同,也有不同的度量方法。比如我们最常见的web 处理能力一般用每秒请求数(requests/second),每秒吞吐量(throughoutputs/second)。其实针对每一个应用,开发人员都应该建立相应的度量。
比如一个email 的IMAP server,我们为其建立如下度量
&APPEND Average Time (milliseconds)
&APPEND Failure Rate (Failures/minute)
APPEND Rate (Requests/minute)
AUTHENTICATE Average Time (milliseconds)
AUTHENTICATE Failure Rate (Failures/minute)
一般地,度量要分为度量名,采集频率,预警值设置,预警信息等等。
开发人员则遵循规范,在开发过程中实现以上度量信息的采集。
在建立一个完善的性能度量体系后,性能的诊断和定位就变得更加容易,也完成了定性分析到定量分析的转变。
(有兴趣的朋友可以参看oracle的AWR报告,这是一个典型的基于度量的report)
从出版社得到消息,《性能测试从零开始-loadrunner入门》一书一版已经售罄,正在追印2000册
在这里,谢谢各位支持的朋友,包括路过的朋友
对本书有什么意见和建议,请大家留言在这里。留言的朋友附上您的邮箱,个人有资料赠送
一. 为何需要软件自动化测试框架& 软件测试框架是软件测试自动化规模发展到一定阶段的必然需求,因为自动化测试将会面临如下问题:1. 如何定义脚本的规范,使之具有良好的可复用性和可维护性。2. 众多脚本的管理问题,如何管理不同版本的测试脚本以及测试脚本之间的关联关系。3. 众多脚本的执行问题,如何无人值守地执行测试脚本,以节约测试时间4. 如何获得最大的自动化测试收益,怎样调整测试策略来达到最高的automation效益。目前在微软,IBM等自动化测试比较成熟的公司,都已经实现并应用了软件自动化测试框架。可以说,框架是自动化测试的趋势。
二.软件自动化测试框架架构思想
其实MS也好,IBM也好,自动化测试框架虽然形式各有不同,但思想却大同小异。总体来说,成熟的自动化测试框架必须提供以下几个功能:1. controller-agent的拓扑结构。此点最妙之处是扩展性极强,在空间上能够兼容各种类型测试程序及脚本,在时间上能够并发执行测试任务。2. 内嵌灵活的自动化测试案例的管理策略。此处可根据企业实际具体应用定义相应的测试组件3. 强大的测试报告和日志展现。一份好的自动化测试报告能满足不同人的口味和需要,比如给老板以清晰直观的测试图表分析;给开发人员以强大的日志debug分析;给测试人员以bug自动关联作用。
下面以automation center为例,分析一下自动化测试框架的设计
展现层:给终端用户提供基于Web页面的四大功能模块·& 测试任务&发起安装/测试任务,并对任务状态进行实时监控·& 测试结果&展现测试结果,生成测试报告,邮件通知,提交bug全程自动化·& 日志分析&SMB协议访问日志服务器,轻松获得automation执行时的日志和抓图·& AC管理&& 脚本管理策略&& 测试组件策略&& 测试实例生成&& Agent 资源管理,添加/删除&& Server资源管理,添加/删除&&&AC核心设置控制层:controller是AC核心,负责如下工作·& 接收并处理用户发送的任务请求·& 管理和控制安装/测试Agent·& 分析和整理测试结果·& 内嵌测试报表/邮件逻辑·& 连接数据库,日志服务器和脚本服务器Agent层:Agent 安装在任务机上,负责:·& 执行安装任务·& 执行测试任务·& 生成log/抓图数据,供后续分析
框架应用策略1. 自动化测试框架是代码,流程,策略的集合(这句话已经耳熟能详了,但能深刻理解并能成功地用到工作实践中却不容易)2. 当你有超过10个自动化测试案例时,就应该开始考虑自动化测试框架的实施了(规范,管理,执行策略等等)3. 实现框架的语言以编译语言为优先选择(我看过用vbscrīpt编写的上万行的框架代码,惨不忍睹,维护和扩展那是相当滴困难)4. 在设计时,框架和案例要分工清楚明确(框架,纲举目张也,不宜管得太多太细,否则案例丧失了灵活性,框架推广起来就步履维艰了,嘿嘿)

我要回帖

更多关于 新奇迹世界2官网 的文章

 

随机推荐