发布新日志

  • 检查该网站上有多少个链接,并取得link.

    2009-06-19 11:31:51

    这是代码!
    SystemUtil.Run "IEXPLORE.EXE","http://www.baidu.com","","open","3"
    Dim i,j,arry()
    i=0
    m=0
    Set a=Browser("百度一下,你就知道").Page("百度一下,你就知

    道").Object.links
    For each element in a
            ReDim preserve arry(i+1)
            arry(i)=element.href

    'msgbox arry(i)
    i=i+1
    m=m+1
    Next
    msgbox(m)

    实质:

    链接是Web应用系统的一个主要特征,它是在页面之间切换和指导用户去一些不知

    道地址的页面的主要手段。链接测试可分为三个方面。首先,测试所有链接是否

    按指示的那样确实链接到了该链接的页面;其次,测试所链接的页面是否存在;

    最后,保证Web应用系统上没有孤立的页面,所谓孤立页面是指没有链接指向该页

    面,只有知道正确的URL地址才能访问。

    在此代码中没有达到验证网页上link有效性的作用!

  • QTP获取当前路径总结

    2009-04-23 13:59:37

    QTP当前路径总结


    说明:本总结不涉及相对路径的应用


    以下为获取当前路径的三种方法,包括QTP和vbs的或二者都可用的。
          以下为本人实验过的。用的QTP版本为9.2版。

    1.
    environment("TestDir")
    使用environment("TestDir")能获取当前测试的绝对路径,不包括最后的“\”
    方法:
    Path = environment("TestDir")

    2.
    WshShell.CurrentDirectory
    (注:不包括地址最后的“/”)
    方法:
    Dim WshShell,path
    Set WshShell = WScript.CreateObject("WScript.Shell")
    Path = WshShell.CurrentDirectory
    以上为vbs中的用法,如果是在QTP中使用,则可以用以下方法(vbs也可以用以下方法):
    Dim WshShell,path
    Set WshShell = CreateObject("WScript.Shell") ‘就这一句少了“WScript”
    Path = WshShell.CurrentDirectory
    注意:此方法在QTP运行时获取的将是QTP安装目录下bin目录的路径,如果是写在vbs文件中,然后加载到QTP中,在QTP运行时也是获取QTP安装目录下bin目录的路径。但是如果是编辑一个测试脚本(脚本里包含此获取路径方法,或引用的vbs文件包含此获取路径方法),然后保存(不要关闭脚本),这时运行脚本,则此方法将获取测试脚本存放的当前路径。关闭脚本再打开运行,则还是会获取QTP安装目录下bin目录的路径。因此在调试时可能是正常的,但到运行时就出错了。
           而如果用environment("TestDir"),则获取的都是当前测试的存放路径,但是不能用在VBS文件中(除非此文件是加载到QTP中运行的,那就可以)。
    例:QTP安装目录下的bin路径:C:\program files\Mercury Interactive\QuickTest Professional\bin

    3.
    left(Wscript.ScriptFullName,len(Wscript.ScriptFullName)-len(Wscript.ScriptName))
    (注:包括地址最后的“/”)
    方法:
    Path = left(Wscript.ScriptFullName,len(Wscript.ScriptFullName)-len(Wscript.ScriptName))
    注意:此方法只能用在单独的vbs文件中,加载到QTP中的vbs文件如果含有此方法也会报错。因为QTP不支持WScript。

  • DB2中的数据仓库和OLAP服务

    2009-04-22 14:24:30

    Question:

    这种表表工具能够在大数据量的生产系统中能够得到良好的数据分析效果和反应速度?

    Answer:

    如果基于MOLAP,运算/产生Cube的过程比较慢,但是生成Cube后,能够在数据量的生产系统中能够得到良好的数据分析效果和反应速度。

    基于动态查询/EIS等,就要看你查看的数据室如何组织的,数据量如何,表的join是不是很多,以及针对数据库物理方面的一些索引、分区、I/O并行、数据库cache等了,这方面不一定能够在大数据量的生产系统中能够得到良好的数据分析效果和反映速度。

    附:OLAP基本知识

    联机分析处理 (OLAP) 的概念最早是由关系数据库之父E.F.Codd于1993年提出的,他同时提出了关于OLAP的12条准则。当时,Codd认为联机事务处理(OLTP)已不能满足终端用户对数据库查询分析的需要,SQL对大数据库进行的简单查询也不能满足用户分析的需求。用户的决策分析需要对关系数据库进行大量计算才能得到结果,而查询的结果并不能满足决策者提出的需求。因此Codd提出了多维数据库和多维分析的概念,即OLAP。以下是odd提出OLAP的12条准则来描述OLAP系统:

     准则1 OLAP模型必须提供多维概念视图

     准则2 透明性准则

     准则3 存取能力推测

     准则4 稳定的报表能力

     准则5 客户/服务器体系结构

     准则6 维的等同性准则

     准则7 动态的稀疏矩阵处理准则

     准则8 多用户支持能力准则

     准则9 非受限的跨维操作

     准则10 直观的数据操纵

     准则11 灵活的报表生成

     准则12 不受限的维与聚集层次

    =============================

    OLAP的提出引起了很大的反响,OLAP作为一类产品同联机事务处理 (OLTP) 明显区分开来。[当今的数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing)、联机分析处理OLAP(On-Line Analytical Processing)。OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如银行交易。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。下表列出了OLTP与OLAP之间的比较。]

    =============================

    OLAP是使分析人员、管理人员或执行人员能够从多角度对信息进行快速、一致、交互地存取,从而获得对数据的更深入了解的一类软件技术。OLAP的目标是满足决策支持或者满足在多维环境下特定的查询和报表需求,它的技术核心是"维"这个概念。[“维”是人们观察客观世界的角度,是一种高层次的类型划分。“维”一般包含着层次关系,这种层次关系有时会相当复杂。通过把一个实体的多项重要的属性定义为多个维(dimension),使用户能对不同维上的数据进行比较。因此OLAP也可以说是多维数据分析工具的集合。]

    OLAP的基本多维分析操作有钻取(roll up和drill down)、切片(slice)和切块(dice)、以及旋转(pivot)、drill across、drill through等。[·钻取是改变维的层次,变换分析的粒度。它包括向上钻取(roll up)和向下钻取(drill down)。roll up是在某一维上将低层次的细节数据概括到高层次的汇总数据,或者减少维数;而drill down则相反,它从汇总数据深入到细节数据进行观察或增加新维。

    ·切片和切块是在一部分维上选定值后,关心度量数据在剩余维上的分布。如果剩余的维只有两个,则是切片;如果有三个,则是切块。

    ·旋转是变换维的方向,即在表格中重新安排维的放置(例如行列互换)。]

    =============================

    OLAP有多种实现方法,根据存储数据的方式不同可以分为ROLAP、MOLAP、HOLAP。

    MOLAP表示基于多维数据组织的OLAP实现(Multidimensional OLAP)。以多维数据组织方式为核心,也就是说,MOLAP使用多维数组存储数据。多维数据在存储中将形成"立方块(Cube)"的结构,在MOLAP中对"立方块"的"旋转"、"切块"、"切片"是产生多维数据报表的主要技术。

    =============================

    OLAP工具是针对特定问题的联机数据访问与分析。它通过多维的方式对数据进行分析、查询和报表。维是人们观察数据的特定角度。例如,一个企业在考虑产品的销售情况时,通常从时间、地区和产品的不同角度来深入观察产品的销售情况。这里的时间、地区和产品就是维。而这些维的不同组合和所考察的度量指标构成的多维数组则是OLAP分析的基础,可形式化表示为(维1,维2,……,维n,度量指标),如(地区、时间、产品、销售额)。多维分析是指对以多维形式组织起来的数据采取切片(Slice)、切块(Dice)、钻取(Drill-down和Roll-up)、旋转(Pivot)等各种分析动作,以求剖析数据,使用户能从多个角度、多侧面地观察数据库中的数据,从而深入理解包含在数据中的信息。

    =============================

    Excel 便是一种不错的OLAP工具:

    Built into Excel is the ability to connect to a variety of external data sources: Microsoft Access databases, Microsoft SQL Server databases, OLAP cubes, Jet databases, and any other OLE DB data source for which there is an OLE DB provider. This versatility in connecting to so many data sources gives users just the power they need to browse almost any data they want. It is easy to use Excel to connect to an existing OLAP cube in Microsoft SQL Server 2000 Analysis Services.Finally,You can“Slicing and Dicing” Data with PivotTable and PivotChart Reports.

    Excel可以连接多种数据源,包括Microsoft SQL Server 2000 Analysis Services 中的OLAP cubes(立方体),从而实现OLAP的基本多维分析操作如钻取(roll up和drilldown)、切片(slice)和切块(dice)、以及旋转(pivot)等。

    参考:

    http://www.olapreport.com/fasmi.htm

  • CVSNT服务器端配置实现权限分配(二)

    2008-12-24 11:43:20

    1.            cvswrappers 文件:

    refers to

    http://www.mobilefish.com/developer/cvsnt/cvsnt.html

    Before using CVS, it is recommended to update the cvswrappers file. The cvswrapper file contains file extensions which determines which file should be stored as binary files in the CVS Repository. To update this file do the following:

    Add the following file extensions in the cvswrappers file, e.g.:

    *.cab -k 'b'

    *.class -k 'b

    *.doc -k 'b'

    *.dll -k 'b'

    *.ear -k 'b'

    *.exe -k 'b'

    *.exp -k 'b'

    *.fla -k 'b'

    *.gif -k 'b'

    *.gz -k 'b'

    *.jar -k 'b'

    *.jpg -k 'b'

    *.jpeg -k 'b'

    *.lib -k 'b'

    *.msi -k 'b'

    *.mso -k 'b'

    *.pdf -k 'b'

    *.pfw -k 'b'

    *.png -k 'b'

    *.ppt -k 'b'

    *.sit -k 'b'

    *.swf -k 'b'

    *.tar -k 'b'

    *.tlb -k 'b'

    *.vsd -k 'b'

    *.xls -k 'b'

    *.war -k 'b'

    *.wmz -k 'b'

    *.zip -k 'b'

    三、CVSNT服务器端配置实现子目录权限分配:

    1.             实现方式:直接修改fileattr.xml 文件实现

    2.             达到的效果:

    一个项目的CVS标准库结构包括两部分:开发库和受控库。每个人员在项目中担当的角色不同,从而在不同的子目录中应当拥有不同的权限。现假定一个项目,项目名为PJ-XXXXX,项目经理为杨捷,配置管理员为王怡岚,开发人员为胡晓玲姜洁,确定项目经理拥有开发库与受控库中所有权限(即相当于管理员权限);配置管理员拥有受控库中所有权限以及开发库中项目管理子目录的所有权限,开发库中其它子目录拥有只读权限;开发人员拥有开发库中所有权限,受控库只有只读权限。所以,可以确定完成的效果:

    1)     adminyangjie 能设置 CVSNT 服务器的配置,并且能对所有的 Repository 拥有全部权限,密码与用户名一致;

    2)     普通用户有3个:wangyilanhuxiaolingjiangjie,密码与用户名一致;

    3)     受控库:yangjiewangyilan可以对受控库进行 checkout,commit,add (read,write,create)huxiaolijiangjie只能进行 checkout (read)

    4)     开发库中的项目管理子目录:yangjiewangyilanhuxiaolingjiangjie均拥有该目录的所有权限,可以进行checkout,commit,add (read,write,create)

    5)     开发库中其他子目录:yangjiehuxiaolingjiangjie可以进行 checkout,commit,add (read,write,create)wangyilan只能进行 checkout (read)

    /*

    说明:

    权限参数有 read,write,add,tag,control. 这里只举例说明最常要的 read,write,add(参见帮助文档)control 没有应用成功。

    */

    3.             开始配置:

    1)      使用CVSNT在服务器端创建一个名为PJ-XXXXX的项目库;

    2)      在服务器端对CVSROOT进行设置,创建admin文件(无扩展名),添加管理员用户:adminyangjie

    3)      定义 group 组:

    cvsroot 建立文件名为 group 的文件(注意,无扩展名),内容为:

    #groupall:hava all permissions

    Groupall: admin yangjie

    #controlall:have all permissions of control repository

    controlall: admin yangjie wangyilan

    #controlreadonly: read only of control repository

    controlreadonly: huxiaoling jiangjie

    #developall:have all permissions of develop repository except DPM subdirectory

    developall: admin yangjie huxiaoling jiangjie

    #developreadonly: read only of develop repository except DPM subdirectory

    developreadonly: wangyilan

    #DPMall: have all permissions of DPM subdirectory in develop repository

    DPMall: admin yangjie huxiaoling jiangjie wangyilan

     

    /*

    说明:

    groupall有完全权限;

    controlall对受控库有完全权限;

    controlreadonly受控库只读;

    developall对开发库中除项目管理子目录外有完全权限;

    developreadonly对开发库中除项目管理子目录外有只读权限;

    DPMall对开发库项目管理子目录有完全权限。

     

    该文件不用注册到 checkoutlist

    */

    4)      CVSROOT中创建passwd文件(无扩展名),设置所有用户的初始密码为空;

    5)      在本地登录CVSNT Server

    /*

    说明:

    pserver     为登陆协议,是一种明文协议,用户名和密码可以被监测到。本次实验用这种协议,其他的协议以后再总结;

    localhost   为登陆的机器地址,可以用 IP

    /cvsroot    cvsroot 是安装 CVSNT server 的时候,指定 CVSROOT 的别名。

    */

    6)      使用管理员用户从本地导入项目的CVS标准库结构(开发库和受控库);

    7)      使用管理员用户检出PJ-XXXXX的项目库至本地与存放此项目的文件夹中;

    8)      修改passwd文件用户密码信息:

    WinCVS管理->命令行中分别执行以下命令:

    cvs passwd -r administrator –a admin

    cvs passwd -r administrator –a yangjie

    cvs passwd -r administrator –a huxiaoling

    cvs passwd -r administrator –a wangyilan

    cvs passwd -r administrator –a jiangjie

     

    /*

    说明:

    -r 是管理的操作系统用户的别名

    注意:

    该命令不会影响操作系统用户;

    此操作系统用户必须为管理员。

    -a 添加用户

    添加用户的时候,会提示输入密码。(本次实验,用户名和密码取相同)

     

    建立的 passwd 查看(684) 评论(0) 收藏 分享 管理

  • CVSNT服务器端配置实现权限分配(一)

    2008-12-24 11:39:29

     

    一、CVSNT的用户验证方式

    CVSNT的用户验证方式分两种:

    1.    Windows系统用户与CVSNT用户共存的混合验证方式:即 windows 操作系统用户和 CVSNT passwd 文件定义的用户都可以作为 CVSNT 的用户。

    1.1 作为操作系统的用户登陆:输入操作系统的用户和密码;

    1.2 作为 CVSNT 的用户登陆:输入 passwd 文件中定义的用户和密码。在这种方式,操作系统的管理员帐户同时也是 CVSNT 服务器的管理员帐户。

    2.    CVSNT用户单一验证方式: 只有 CVSNT passwd 文件定义的用户作为 CVSNT 的用户。

    登陆:输入 passwd 文件中定义的用户和密码。

     

    默认工作模式是混合验证方式,但是使用单一验证方式对用户的管理比较方便一点,因此下面的介绍,基于 CVSNT 用户单一验证方式。

    二、CVSNT的主要配置文件:

    CVSNT 服务器安装完成之后,要定义 ROOT Repository,在该目录中,定义了服务器的各种配置,在这里可以定义管理选项参数。

    本文主要介绍以下几个文件:configpasswdadmingroupcheckoulistfileattr.xmlcvswrappers

    1.           config 文件:

    只关注文中第一、二行注释

    #Set this to `no" if pserver shouldn"t check system users/passwords

    #SystemAuth=yes

    SystemAuth 定义验证方式,默认是 SystemAuth=yes ,即混合验证方式。

    这项设置默认是注释掉的,相当于 SystemAuth=yes

    如果想要修改为 CVSNT 用户单一验证方式,修改为 SystemAuth=no

    注意,如果修改为  SystemAuth=no ,操作系统用户就不能登陆 CVSNT 服务器了,所以要在定义好 CVSNT 服务器的管理员之后(即修改好 passwd,admin,checkoutlist 三个文件之后),再修改它。

    2.           passwd 文件:

    该文件中定义了 CVSNT 用户的用户名、密码、操作系统用户别名;

    默认该文件是不存在的,只有管理员有权限创建和修改它;

    该文件不能被 checkout

    格式:cvsadmin:fqr1fS4gDghrt:administrator

    用户名:密码:操作系统用户别名

    密码是CVS使用UNIX标准加密函数对密码进行加密后的结果;这个用户名和密码和操作系统用户没有关系,修改它们不会对操作系统产生任何影响;每个用户必须要有一个操作系统用户别名,这个别名必须在操作系统中真实存在,并且是管理员身份,否则该用户无法进行 cvs 操作。(为什么必须是管理员?)

    /*

    实际上, CVSNT 服务器是以该操作系统用户的身份进行文件的读写操作的,如果该操作系统用户为 guest ,则不能 checkout ,ls 等。

    不知道为为什么 CVSNT 服务器没有把这项设置对使用者透明化,因为每个用户都要进行  checkout ,ls 等基本的操作,如果连这些基本的操作都不能进行的话,这个用户就没有存在的必要了。

    按我的理解,格式就要用户名和密码,后面的操作系统别名默认为管理员,就像 servu 一样易于使用。(也可能有其他的原因)

    附:cvsnt manual

    The cvs passwd command can be used to add or delete new users. Only an administrator can do this.

    Note that deleting a user does not remove them from any user permissions.
    */

    3.            admin 文件:

    文件中定义了 CVSNT 服务器的管理员列表。

    格式:

    user1

    user2

    ...

    该文件中的用户同样必须出现在 passwd 文件中;该文件中的用户,拥有 CVSNT 服务器管理员的所有权限;该文件默认是不存在的,需要手工建立;该文件要加入到 checkoutlist 文件中。

    实际上,cvsnt server 把这个文件当作一个特殊的 group 来对待的。

    4.            group 文件:

    这个文件用来定义组,我们可以将同样性质的用户归入一个组,然后用给用户赋权限的方式给组赋权限,这样,一个组的用户就会具有同样的权限。

    格式:

    group1:user1 user2 user3

    group2:user4 user5 user6

    group3:user7 user8 user9

    组的名称+冒号+用户名+空格+用户名+空格...

    多个用户名之间用空格来进行分割;组中的用户,要在 passwd 文件中存在。

    5.            checkoutlist 文件:

    # The "checkoutlist" file is used to support additional version controlled

    # administrative files in $CVSROOT/CVSROOT, such as template files.

    #

    # File format:

    #

    # [<whitespace>]<filename><whitespace><error message><end-of-line>

    #

    # comment lines begin with '#'

    该文件用来支持附加的版本控制操作,在 CVSROOT 中添加的文件,要在此文件中声明。

    目前只知道,admin 文件需要声明。(还没用到,不知道怎么用4,有什么作用)

    格式举例:

    admin err msg by Apollo

    注意:不要忘记文件名称之前的空格。

    6.            fileattr.xml 文件:

    在每一个 Repository 建立之后,都会在 Repository ROOT 中建立一个名字叫做 CVS 目录,该目录中只有一个文件 fileattr.xml

    fileattr.xml 文件中定义了访问该 Repository 的用户的权限;7

    对于新建立的 Repository ,默认是所有人拥有所有权限(CVSNT ROOT 除外)

    CVSNT ROOT fileattr.xml:默认是只有管理员拥有其所有权限。

  • CVSNT配置

    2008-12-24 11:34:38

    CVS是版本控制的利器,目前在LinuxWindows下都有不同版本;但是国内大多数应用介绍都是基于Linux等开放源代码的开放性软件组织,而且讲解的也不系统,让人摸不着头脑;Windows下的CVS使用介绍更是了了无几。

    本文是针对WindowsLAN环境下使用CVS的经验介绍,一步一步的向您介绍如何配置和使用CVS的服务器端和客户端。同时,本文只使用到了CVS当中最基本的东西,还有很多更为高级的东西,本文暂不涉及。下面是本文的另一个连接映射,欢迎大家讨论使用,共同进步。

    相关知识链接:http://www.kuihua.net/bbs/dispbbs.asp?boardID=15&ID=13&page=4

    http://www.chinaitpower.com/A/2005-02-20/108573.html

     

    1、安装版本:

     

    1.1、服务器端(CVSNT)

     

    1. 本文使用的是CVSNT-2.0.4,这是一个比较稳定的版本,不要使用最新的CVSNT-2.1.1,本人在使用中发现有比较严重的Bug

    2. 下载连接http://www.cvsnt.org 目前,它提供2.0.62.1.1版本的下载。

    3. 上面连接还提供源代码,有兴趣的朋友还可以下载下来仔细研究:)。

    4. 有心的朋友,仔细观察就会发现http://www.cvsnt.org 并没有提供任何客户端的下载,那是因为CVS.exe既可以用于服务器端又可以用于客户端,WinCVS是为了客户端使用的方便而定制的外壳。(关于这一点,本人未得到任何证实,只是本人在使用过程中的一种体会,欢迎大家讨论。)

     

    1.2、客户端(WinCVS)

     

    1. 本文使用的是WinCVS-1.3b13,这应该是一个最新版本:),本人在使用过程中并没有发现有任何严重的Bug

    2. 下载连接http://sourceforge.net/projects/cvsgui/

    3. 此网站还提供丰富的CVS文档和相关源代码,以及多个OS下面的相关文档和代码;有收藏癖的朋友有福了:)。

    4. WinCVS-1.3b13 使用的CVSNT的版本是CVSNT-2.0.2,在与服务器端的CVSNT-2.0.4 版本配合使用时,未发现任何不兼容或冲突现象。

    5. 在本人的系统中用cvs version命令显示的结果如下:

    Client: Concurrent Versions System (CVSNT) 2.0.2 (client/server)

    Server: Concurrent Versions System (CVSNT) 2.0.4 (client/server)

     

    2、服务器端(CVSNT)的安装与配置:

     

    2.1、服务器端机器和环境配置:

     

    1. 操作系统:Windows 2000 Professional SP2中文版

    2. 机器名称:Server

    3. 机器地址:192.168.0.6 (内部IP)

    4. 网络环境:100兆交换局域网

    5. 硬盘分区格式:FAT32NTFS都可以。

    6. 准备2CVSNT的工作目录:

    F:\KHRoot (存放自己源代码的根目录)

    F:\KHTemp (存放CVS出错信息的目录)

    7. 本机上存在有的用户列表:(由NT或本机的使用者创建)

    Administrator (系统管理员)

    Jackey (普通用户)

    Goury (普通用户)

    Riolee (普通用户)

     

    2.2、安装CVSNT

     

    1. 下载CVSNT-2.0.4;使用administrator登陆到Server机器上。

    2. 双击自解压的exe文件,选择Full Install,其它按照默认方式安装;安装完毕后可以在服务控制器中发现多了2个服务:cvsntcvslocking

    3. 发送Service Control Panel到桌面,形成快捷方式。

    4. 安装程序会自动将CVS安装路径,设置到系统的Path环境变量当中,因此使用者可以在控制台(cmd)中任意位置执行cvs.exe,这一点对下面的配置很重要!!

     

    2.3、配置CVSNT服务器:

     

    1. 双击Service Control Panel快捷方式,在Service Status页面,确认2个服务正常和稳定运行。

    2. 选择Repository页面,点按Add按钮,选择已经准备好的F:\KHRoot这个目录,确认,OKYes,这时会在F:\KHRoot下面建立CVSRoot目录,这是CVS默认的管理目录(默认模块)。如果报错,那是系统Path路径未设置正确。

    3. 选择Advanced页面,勾上Use local users for pserver ...,(Why? I dont know!J,Temporary栏选择已经准备好的F:\KHTemp,确认,OK

    4. 点按【应用】按钮,确认,退出,OK,搞定!!

     

    2.4、小结:

     

    1. 至此,CVSNT服务器端基本配置完毕,下面进行WinCVS的使用和管理。

    2. 由于CVS支持远程管理,也就是客户端与服务器集成的特性,因此,我们将添加用户、权限控制、模块维护等所有的管理工作都放到远端(WinCVS)进行管理,服务器端这时可以Ctrl+Atl+Del进入锁定状态了,下面的所有工作都交给远端的WinCVS来进行管理。

     

    客户端(WinCVS)的安装与配置:

    3.1 客户端机器和环境配置:

     

    1. 操作系统:Windows 2000 Professional SP2中文版

    2. 机器名称:YCW2000

    3. 机器地址:192.168.0.2 (内部IP)

    4. 网络环境:100兆交换局域网,可以直接访问到Server

    5. 硬盘分区格式:FAT32NTFS都可以。

     

    3.2 安装WinCVS

     

    1. 下载WinCVS 1.3b13,全部按照默认安装就可以了。

    2. 启动WinCVS,开始使用。特别注意:以下的所有操作都是在YCW2000(192.168.0.2)这台机器上远程完成的,此时的Server(192.168.0.6)主机已经进入了锁定状态。

     

    管理员使用WinCVS进行远程管理:

     

    4.1 配置WinCVS成管理员状态:

     

    1. 准备管理员工作目录:(YCW2000机器上)

    E:\CVSClient\Admin (管理员工作目录)

    E:\CVSTemp (WinCVS临时目录)

    2. 第一次启动WinCVS时会自动弹出Preferences配置页面,也可以通过Admin=>Preference菜单进入;第一次使用时需要配置如下的3个页面:

    General页面设置:

    注:按照图示方式输入即可,需要注意的是Path部分的格式是Unix路径格式,它指的是CVSNT端设置的工作根目录。

    CVS页面设置: 注:Home路径是设置密码等文件的存放位置,必须指定,否则在登陆时,WinCVS也要弹出设置框。这个Home路径需要Python.exe这个外挂程序才有效。这里选择已经准备好的路径:E\CVSTemp

    WinCVS页面设置:

    注:此页面设置WinCVS的外挂编辑程序,通常使用UltraEdit比较方便。

    3. 设置管理员的工作路径:可以点按图标 ,或View=>Browse Location=>Change…菜单进行设置,选择已经准备好的路径:E:\CVSClient\Admin,确认,OK,这时此目录将出现在WinCVS的左边导航栏【Workspace】内。

    4. 至此,WinCVS就被配置成了远程的管理员使用状态,下面进行一般管理员需要的基本操作演练。演练的内容为:Administrator需要管理JackeyGouryRiolee三个用户,分别为这3个用户建立工作目录,每个人只能访问自己的工作目录。同时,只有Administrator能够进行权限分配,其它人没有任何管理权限。

     

    4.2 管理员进行管理演练:

     

    1. 登陆远程CVSNT

      ◇ 选择Admin=>Login菜单,默认设置,OK

      ◇ 弹出密码输入框,确认,OK。注意观察输出框【OutPut】的返回结果。

    2. Checkout默认模块:(CVSRoot管理模块)

      ◇ 在左边导航栏【Workspace】内,选择【Admin】点按右键,选择【Checkout

      modules…】,在【Checkout settings】中输入CVSRoot,确定,OK。如下图:

      ◇ 如果成功的话,会在【Admin】栏下增加一个【CVSRoot】目录。表示您已经将【

      CVSRoot】这个管理模块下载到本地了。

     

    3. CVS中目录权限介绍:

     

    系统支持的目录权限列表:

    r (读取权限)

    w (写入权限)

    c (创建和删除权限)

    n (没有任何权限)

    默认情况下,任何用户都拥有任何目录的所有权限。

    任何情况下只有目录的拥有者和Administrator才有权力更改目录的使用权限。下面将会介绍如何修改目录权限和目录的拥有者。

     

    4. 修改CVSRoot的权限:只让Administrator拥有rcw三种全部权限。

     

    选中刚刚下载的【CVSRoot】模块,【Ctrl+L】或Admin=>Command Line…,弹出Command Line Settings对话框,直接执行CVS命令。

    取消所有用户的默认权限:cvs chacl default:n 回车,OK,完成。

    设置Goury拥有所有权限:cvs chacl goury:rcw 回车,OK,完成。

    查看【CVSRoot】的权限状态:cvs lsacl 回车,OK,在【Output】中显示: Owner: administrator default:n goury:rwc

    按照以上的方法依次分别设置【Jackey】与【Riolee】的工作目录访问权限。 至此,完成了3个用户的目录权限分配。注意,虽然Administrator也没有权力再次【Checkout】那3个用户的工作目录,但是它是这些目录的拥有者又是Administrator,因此,只有它才有

  • QTP数据表数据库操作(z)

    2008-12-19 14:55:56

    1、Datatable方法GetRowCount
       DataTable.GetSheet("Action1").GetRowCount   //获取总行数
    使用如:
    CountNum=DataTable.GetSheet("Action1").GetRowCount

    2、Datatable方法SetNextRow
       DataTable.GetSheet("Action1").SetNextRow     //取得下一行
       datatable.setcurrentrow(n)   //取得某一行

    3、Datatable方法getcurrentrow    //获得当前行数
       例如:datatable.getcurrentrow

    4、获取datatable值
       4.1 DataTable("p_Text", dtLocalSheet) //取得datatable中参数名称为:p_Text的值
       4.2 DataTable.GlobalSheet.GetParameter("p_Text").Value   //获取参数值方法和DataTable("p_Text", dtLocalSheet)一样
       例如:xname为变量,dim xname
       xname=DataTable("p_Text", dtLocalSheet)
       xname=DataTable.GlobalSheet.GetParameter("p_Text").Value

    5、datatable.value("num")只在global形式下的一种省略形式;完整形式是:
    datatable.value("num",dtlocalsheet)

    -----向某一列的单元格赋值:
    datatable.value("column_name",dtlocalsheet)="nanjing"

    6、字符转换Cstr
       dim mm
       Cstr(mm)

    7、获取对象属性名称用法:
    GetRoProperty----从应用程序界面上获取对象属性(即,是脚本运行时,获取的对象动态属性值)
               例如:获取对象库中index属性值,似乎只能用GetToProperty,因为应用程序界面上对象没有该属性,只是
          QTP为识别该对象创立的描述属性;
    GetToproperty----从对象库中描述对象的属性,静态值
    GetToProperties----获取用于标识对象的属性集;对于这个集合,有count等属性方法

    8、如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证
    if browser("web_name").dialog("dialog_name").exist(1) then'如果不出现=false
         error_message=browser("web_name").dialog("diaglog_name").static("用户密码错误!".getRoproperty("text")
       if error_message<>(datatable.value("error_info"))then
             msgbox(error_message)
          end if
         browser("web_name").dialog("diaglog_name").close
    end if
    这里总结了两点技巧:
      一是:对于dialog中,虽然提示信息对象名称是"用户密码错误",但如果信息对象名称是“该用户不存在”,不用更改会自动识别,我想主要是录制第一遍时,“用户密码错误”只是让运行时能找到这个控制,而不管它是什么内容,因为在对象仓库中,text不是决定该对象的属性
        二是:如果对于提示信息比较长的,可以用mid(error_message,n,m)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理

    9、数据库检查点模块:
    sub database_check
    set con=createobject("adodb.connection")
    con.open "Descrīption=IBM_ODBC;DRIVER=SQL Server;SERVER=IBM;UID=sa;"&_
                     "PWD=123456;APP=Quick Test Pro;WSID=IBM;DATABASE=IBM_table"
    'access方式:con.open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\test.mdb"
    'Orocle 方式:con.open "DRIVER={Oracle in OraHome92};SERVER=CESHI;UID=CND_TEST;PWD=CND;DBQ=CESHI;DBA=W;APA=T;EXC=F;XSM=Default;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;GDE=F;FRL=Lo;BAM=IfAllSuccessful;MTS=F;MDI=Me;CSR=F;FWC=F;PFC=10;TLO=O;"
    set record=createobject("adodb.recordset")
    sql="select*from ibm_one_table"
    record.open sql,con
    DO
    if(record("ibm_table_column")="kai")then'//查找表格中有多少kai
    num=num+1;
    end if
    record.movenext
    loop until record.eof=true
    record.close
    set record=nothing
    con.close
    set con=nothing
    end sub

    10、"is+*"类型function
    isarray'是否是数组
    isconnected'判断QTP是否连接到TD
    isdate'是否是合法的日期类型
    isempty'判断是否初始化
    isNull'判断是否为空值
    isNumeric'判断是否是数字型
    isobject'判断是否一个功能对象
    isready'判断设备是否准备就绪
    isRootFolder'是否是根目录

    11、for方法1,参数化时选择:dtLocalSheet
    Dim CountNum
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    For i=0 to CountNum-1
    ----xunhuanti------
    DataTable.GetSheet("Action1").SetNextRow    //使用SetNextRow方法
    Next

    12、for方法2,参数化时选择:dtLocalSheet
    dim countNum
    countNum = DataTable.GetSheet("Action1").GetRowCount
    For i=1 to countNum
    DataTable.GetSheet("Action1").SetCurrentRow(i) //使用SetCurrentRow(i)方法
    ―――ddd―――
    next
    13、while方法1,参数化时选择:dtLocalSheet
    Dim CountNum,i
    i=1
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    While i<=CountNum
    ------xuhuanti---
    DataTable.GetSheet("Action1").SetNextRow
    i = i+1
    Wend

    14、while方法2,参数化时选择:dtLocalSheet
    Dim CountNum,i
    i=1
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    While i<=CountNum

    DataTable.GetSheet("Action1").SetCurrentRow(i)
    ----xuhuanti---
    i = i+1
    Wend

  • 在QTP中随机取下拉菜单的值(转)

    2008-12-19 14:53:27

     

    摘要:产生期望的随机数来选取到动态的下拉菜单的值。
    关键字:随机数;GetROProperty
            有网友在论坛上提出问题,在使用QTP中如何随机选取动态的下拉菜单。在此笔者总结了一些测试经验,利用51testing的登录界面(http://bbs.51testing.com/logging.php?action=login)作为测试页面进行讲解。
            首先我们拿登录页面中的  安全提问  这个下拉菜单作为测试对象。
             

            我们可以先录制一段选取下拉菜单的脚本。
            Browser("51Testing软件测试论坛 测试 | 软件测试\").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").Select "您个人计算机的型号"。
            备注:无

            这边有个技术处理就是使用#加数字来选择我们的下拉菜单。
            Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").Select "#2"
            备注:这个方法在论坛上也出现过,比较适合这个例子。

            下面我们要取得下拉菜单中选项的个数。
            Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
            备注:这边使用GetROProperty,应该算比较常见的,所以不多做解释。

            接下来是要个随机函数,参考帮助。
    Randomize
    x=RandomNumber (0,2)
            备注:这边是随机生成0-2之间的三个数字中的一个。

            我们可以把随机函数写成function,方便以后使用。
    Function Get_Ran(i)
       Randomize
      Get_Ran=RandomNumber (0,i)
    End Function
            备注:这边需要注意的就是使用了函数返回值

            最后我们把脚本整合起来
    Function Get_Ran(i)
       Randomize
      Get_Ran=RandomNumber (0,i)
    End Function


    Get_Count=Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
    Ran_Number=Get_Ran(Get_Count-1)
    Browser ("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").Select "#"&Ran_NumberBrowser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
    Browser("51Testing软件测试论坛 测试 | 软件测试").Page("51Testing软件测试论坛 测试 | 软件测试").WebList("questionid").GetROProperty ("items count")
            备注:需要注意的就是在下拉菜单选择的时候从#0开始计算的,所以随机数字从0开始,传入的值也需要减去1。

            题外话:这边主要是使用QTP自带的随机数字函数这个方法来实现随机选择下拉菜单的内容,其实这个随机数字可以开展到随机字符串。因为我们经常会有一些输入域的测试,有的就需255个字节,多的就更可怕,使用随机函数能大大减少我们的工作量。而下面这个例子是实现在abc这三个字母中随机取出来拼成字符串。
    Function makestring(inputlength)
    If IsNumeric(inputlength) Then
    For I = 1 To inputlength
    'you may add a random function here
    A = Array("a","b","c")
    Randomize
    x=RandomNumber (0,2)
    B = A(x)
    makestring =makestring +B
    Next
    msgbox ("output the string:"&makestring )
    else
    msgbox ("error format:"&inputlength)
    End If
    End Function
    Call makestring("8")

  • QTP实现对文本文档的读写

    2008-12-19 14:51:31

    '几个重要的方:OpenTextFile,AtEndofLine,Split

    Dim Fileobj,FilePath,FileName,Arrayline

    FilePath="E:\cntesting.txt"       '操作文本的所在路径也可以为表达式

    '创建一个文本文件并写入数据 1塂!}`tg? 
    Set ōbjth = CreateObject ("scrīpting.FileSystemObject") ;9籔??@  
    Set AdFile = objth.OpenTextFile(FilePath,2,true)      '此方法打开指定的文件并返回TextStream对象 ,第一个参数为要打开文件字符串表达式,第二个参数有三个值1,2,8可选,第三个参数True为创建新文件 巬暌/DV;  
    AdFile.WriteLine "###############################" ?o絎5?  
    AdFile.WriteLine "此脚本为读写文本文件的脚本例子" 輐g?滝? 
    AdFile.Close

    Set AdFile =  objth.OpenTextFile(FilePath,1,false)    '此中的参数1为只读方式打开

     While not AdFile.AtEndofLine    '如果文件指针正好位于OpenTextFile返回的TextStream文件中的行尾符之前,则返回True,否则返回False,只读 *禂?娘O  
      Arrayline = Split(AdFile.ReadLine,",")'此方法将一个字符串分割为子字符串,然后将结果作为字符串数组返回 ?Y??渗a  
      msgbox Arrayline(i) ?B懭懋鰐? 
     Wend

  • 一些问题的解决方案:

    2008-12-19 14:49:20

    ---------------------------------------------

    ->“实际项目录制脚本时经常遇到这种情况,伴随着系统不断的版本升级更新,需要我们在许多不同情况下回放同样的脚本,这样带来大量脚本中IE跳转地址的变动,有更好的方法能更快速,准确的实现这个需求吗?”

     

    ->有的,一般情况下最好的方式是把IE跳转地址,在脚本中实现而不是在Record and run settings 中设置打开固定的IE请求地址。如下:InvokeApplication "C:\Program Files\Internet Explorer\IEXPLORE.EXE http://www.cntesting.net/"

    ---------------------------------------------

    ->”录制脚本中发现同一模块的有些功能,步骤基本类似,是否能优化一下代码而减小脚本 代码的缀余呢?

     

    ->是的若脚本中缀余代码过多,不仅看起来麻烦,维护起来也很不方便,所以我们应该在脚本中善于使用过程,函数,对功能模块步骤基本类似的可以写成过程或则函数来提供调用。

    ---------------------------------------------

    ->”能提供一些QTP常用的快捷键吗?这样我想工作的效率也会提高很多,用起来也方便

     

    ->几个重要又经常使用到的QTP快捷键应该记住: CTRL+Y专家视图编辑前进;CTRL+Z专家视图编辑后退; CTRL+G移动到指定行; F2重新命名Ative的名字; F9设定断点,F3录制,F5运行,F4停止。还有很多快捷键都是经常要用到的,要经常用了才能记牢,我在这就不一一写出来了。

    ---------------------------------------------

    ->”项目中,我们经常会遇到这样的需求,需要记录一套脚本的运行时间,如果手工一个个操作去记录下时间的话,一来不是很精确,二来确实手工的方法太麻烦,有中方法解决这个问题吗?

     

    ->”这个需求是经常遇到的,以前我做项目的时候临近上线要验收测试了,因为时间紧迫必须大概知道脚本的运行时间,当时比较傻一个脚本手工的拿着个表记录时间,后来研究了一下,还是有方法的:在运行脚本的下一行记录下开始时间: startTme = timer; 在结束脚本的上一行记录下结束时间: endTime = timer; 然后 加一句这样的代码 runtime= round(endTime – startTime),2) 。用四舍五入的方法算出这个时间差就是脚本的运行时间。

    ---------------------------------------------

    ->”QTP能录下键盘的操作吗?能把我移动窗口的动作录制下来吗?”

     

    ->”可以的,但是我用过的就Table,如果要实现键盘按键的操作需要自己编码了,要把一些微小的操作录制下来,那就得启用微小录制了。

    ---------------------------------------------

    ->”我需要使用不同Action Datatable 里面的值,实现起来复杂吗?

     

    ->不复杂: DataTable.GetSheet("Action1").GetParameter("cntesting").ValueByRow(1)

    ---------------------------------------------

    ->”项目中有这样的需求,需要我们通过修改系统时间来做一笔定单,但是我总不能手动去修改啊.”

     

    ->呵呵,都手动去了都不需要自动化了,修改系统时间实际项目中很多要用到,需要自己写个dat文件在本地,里面设置好所要修改的时间,然后在QTP中执行这个dat文件,可以实现这个需求。Dat文件里面只要有这几代码就可以: time%1, 然后在QTP, SystemUtil.Run "c:\settime.bat","所要修改的具体时间

    ---------------------------------------------

    ->”经常遇到这样的情况,因为要验证弹出的窗口里面的内容,所以在IE属性中设置了不阻止窗口,但问题出来了窗口有时候弹出有时候不弹真奇怪了,如果不弹出来脚本中又录制有则会报错,要怎么去判断窗口是否弹出呢?”

     

    ->有一个方法 Exit 。是这样用的  if Browser(…).Page(…)…().exit then ……

    ---------------------------------------------

    问:时间控件QTP能录制下来吗?

     

    :对于时间控件的录制问题与开发使用的技术有关,我可以建议你用种方法,但是不同技术开发出的控件可能录制情况也有所不同。试试总比不试的好: Browser("xxx").Page("xxx").WebEdit("StartDate").Object.value=DataTable("StarDate", dtLocalSheet)

    ---------------------------------------------

  • QTP对Excel文件的读写操作

    2008-12-19 14:18:03

    重要方法   ImportSheet后面的参数说明:文件路径,global名字,global 颋x呵??? 
    Function WriteExcel() ⒌:%忋1WA  
       Dim ExcelContent(3) 逷厁蒩?#  
       strFileName = "E:\cntesting.xls"  'Excel文件路径 eO4I=汽u?  
       For j = 0 to 3 罦烗d蔥蔵h  
       ExcelContent(j) = "" 'jM\?vS  
     Next

     ExcelContent(1) = DataTable("I_orderId", dtGlobalSheet) 斊 ?祗J  
     ExcelContent(2) = DataTable("I_orderAmountEqual", dtGlobalSheet) 睆ON彨壠? 
    ' 写数据到Excel文件 kR?t?d蘇  
     Dim Obj, Look, Sheet 麥9囧芆  
     Set Obj = CreateObject("Excel.Application")  镹:}/蝡擝  
     Obj.Application.Visible = True gK?DV席T? 
     Set Look = Obj.WorkBooks.Open(strFileName) u<冈郟"氙X  
     Set Sheet = Look.Worksheets(1) 胑墰旲猠拽  
     For j = 1 to 2 wXV9纸?? 
       Sheet.cells(2,j) = ExcelContent(j) ?:-V鑲?? 
     Next 3?cM_?? 
     Obj.DisplayAlerts = False ?j0贾朝  
     Look.Close(True) ?鞀鄧鵤}? 
     Obj.Quit I璍2鰆? 
     Set Obj = nothing J遴届fg?g  
    End Function

    '--------------------------------------------------------------

    '从Excel读数据 r\i? ? 
    Function ReadExcel() 1iE敡昰qB  
     datatable.AddSheet("Global")' ~9`J褹釋  
     datatable.ImportSheet "E:\cntesting.xls","test","Global"

     Dim i,RowCount FhnP`/软e? 
     i=0 Y-;宿,/? 
     RowCount=datatable.GetSheet("Global").GetRowCount ' 设置 RowCount 等于 Global中的行数。 ' 脡思Y缿牀  
     msgbox RowCount [羛Yp}t戓  
     Do while i<rowcount P4蟴 ?? 
     i=i+1 汱/9栍? 
     datatable.getsheet("Global") ' ?搆*讈?  
     datatable.setcurrentrow(i) 嶤芠衖阜!  
     msgbox DataTable.GetSheet("Global").GetParameter(i).Value '取得第一列的值 ?昴吻? 
      h;?Y繯歕  
     datatable.setcurrentrow(n) 厖榷z腌]  
     msgbox Datatable.GetSheet("Global").GetParameter(i+1).Value '取得第二列的值 怫錮洎Ac5  
     msgbox datatable.getsheet("Global").getparameter("I_orderAmountEqual").RawValue'取得特定的I_orderAmountEqua列的值 窼??魋? 
     loop hLn幕V塒  
    End Function @湥曷?N|  
    WriteExcel   '写入函数调用 k髣朙p6p?  
    ReadExcel    '读出函数调用

  • 并列Action之间的参数传递

    2008-12-19 14:18:03


    并列Action之间的参数传递:(目的:将并列Action_one中的参数传递给 Action_Two)

     

     

    步骤一:首先建立2个并列Action(并列Action_one,并列Action_Two),然后如图右击并列Action_one->选择Action properties.

     

     

    步骤二:选择Parameters单元,output parameters name 一列填写参数名。

     

     

    步骤三:右击并列Action_Two->Action Properties,设置Action_Two参数值。

     

     

    步骤四:在输入参数:input parameters中输入传入参数名。

     

     

    步骤五:让2个并列Action之间相互调用,点击Action call properties

     

     

    步骤六:点选parameter单元格。选择input parameter 中的 Value 一列。

     

     

    步骤七:点选parameter 在下拉列表中选择Test/action parameterAction一行选择传入并列Action_oneparameter 一行 选择Action_one中的Out Parameter 输出参数名。

     

     

    这样我们就达到了2个并列Action的相互参数传递, 此例并列Action_Two中的参数Inparametertwo,是由并列Action_one中的参数outparamter传递而来。

  • 一位高人的QTP学习笔记

    2008-12-19 14:06:56

    转贴一个高人的QTP笔记供大家学习。
       
    文章比较长,一共三部分:
    1
    、连接数据库查询例子,无参数化
    //
    查询收文操作,通过数据库查询记录数是否正确
    //1
    、输出记录数值,例如78  2、获取输出的记录数值  3、连接数据库,查询记录数
    4
    、输出记录数值和从数据库中查询记录数值,相比较,相等则成功,不等则失败
    Browser("
    湛江信息化测试登录").Page("湛江东兴石油企业有限公司办公自动化系统").Frame("mainFrame").Output CheckPoint("78")
    Dim mm
    'mm=DataTable.GlobalSheet.GetParameter("mainFrameOutput_Text_out").Value  
    //
    注释,获取datatable值与DataTable("mainFrameOutput_Text_out", dtGlobalSheet)一致
    mm=DataTable("mainFrameOutput_Text_out", dtGlobalSheet)
    MsgBox mm
    Dim res,cmd,sql
    Set res=createobject("adodb.recordset")
    Set cmd=createobject("adodb.command")
    Cmd.activec
    Cmd.CommandType = 1
    sql="select count(*) from oa_receivebumf  where BUMFNAME
    like '%收文测试%'"
    'sql="select  count(*)  from oa_receivebumf  where BUMFNAME='"&nn&"'"
    //
    注释,sql语句,等于时sql语句
    // sql="select  count(*)  from oa_receivebumf  where BUMFNAME like '%nn%'" //like
    sql语句
    Cmd.CommandText = sql
    Set res = Cmd.Execute()
    //msgbox res("name")

    MsgBox res(0)
    If   Cstr(res(0)) = Cstr(mm)Then
          Reporter.ReportEvent micPass, "test\",   "
    查询成功"     
      else
    Reporter.ReportEvent micfail, "test",   "
    查询失败"
    End If
    Set res = nothing
    Set cmd.ActiveConnection = nothing
    Set Cmd= nothing
    2
    、登记用户,查看是否登记成功
       //
    登记用户,查询用户是否存在在数据库中
         1
    参数化 2、取参数化值  3、查询语句中,赋值给查询条件
         4
    、从数据库中查询出用户名,与参数化中值做比较
       
    脚本如下:
    Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame_2").WebEdit("addressVO.name").Set DataTable("p_Text", dtGlobalSheet)
    Dim xname
    xname=DataTable("p_Text", dtGlobalSheet)
    MsgBox  xname


    Dim res,cmd,sql
    Set res=createobject("adodb.recordset")
    Set cmd=createobject("adodb.command")
    Cmd.activec
    Cmd.CommandType = 1
    sql="select  name from address_list t where name ='
    "&xname&"'"
    Cmd.CommandText = sql
    Set res = Cmd.Execute()
    'msgbox res("name")
    MsgBox res(0)
    Set res = nothing
    Set cmd.ActiveConnection = nothing
    Set Cmd= nothing

     

     

    第二部分

    1Datatable方法GetRowCount
       DataTable.GetSheet("Action1").GetRowCount   //
    获取总行数
      
    使用如:
      CountNum=DataTable.GetSheet("Action1").GetRowCount

    2
    Datatable方法SetNextRow
       DataTable.GetSheet("Action1").SetNextRow     //
    取得下一行
       datatable.setcurrentrow(n)   //
    取得某一行

    3
    Datatable方法getcurrentrow    //获得当前行数
       
    例如:datatable.getcurrentrow

    4
    、获取datatable
       4.1  DataTable("p_Text", dtLocalSheet)  //
    取得datatable中参数名称为:p_Text的值
       4.2  DataTable.GlobalSheet.GetParameter("p_Text").Value   //
    获取参数值方法和DataTable("p_Text", dtLocalSheet)一样
       
    例如:xname为变量,dim xname
       xname=DataTable("p_Text", dtLocalSheet)
       xname=DataTable.GlobalSheet.GetParameter("p_Text").Value

    5
    datatable.value("num")只在global形式下的一种省略形式;完整形式是:
    datatable.value("num",dtlocalsheet)

    -----
    向某一列的单元格赋值:
    datatable.value("column_name",dtlocalsheet)="nanjing"

    6
    、字符转换Cstr
       dim mm
       Cstr(mm)

    7
    、获取对象属性名称用法:
    GetRoProperty----
    从应用程序界面上获取对象属性(即,是脚本运行时,获取的对象动态属性值)
               
    例如:获取对象库中index属性值,似乎只能用GetToProperty,因为应用程序界面上对象没有该属性,只是
          QTP为识别该对象创立的描述属性;
    GetToproperty----
    从对象库中描述对象的属性,静态值
    GetToProperties----
    获取用于标识对象的属性集;对于这个集合,有count等属性方法

    8
    、如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证
    if browser("web_name").dialog("dialog_name").exist(1) then'
    如果不出现=false
         error_message=browser("web_name").dialog("diaglog_name").static("
    用户密码错误!".getRoproperty("text")
       if error_message<>(datatable.value("error_info"))then
             msgbox(error_message)
          end if
         browser("web_name").dialog("diaglog_name").close
      end if
    这里总结了两点技巧:
      一是:对于dialog中,虽然提示信息对象名称是"用户密码错误",但如果信息对象名称是该用户不存在,不用更改会自动识别,我想主要是录制第一遍时,用户密码错误只是让运行时能找到这个控制,而不管它是什么内容,因为在对象仓库中,text不是决定该对象的属性
       
    二是:如果对于提示信息比较长的,可以用mid(error_message,n,m)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理

    9
    、数据库检查点模块:
    sub database_check
    set con=createobject("adodb.connection")
    con.open "Descrīption=IBM_ODBC;DRIVER=SQL Server;SERVER=IBM;UID=sa;"&_
                     "PWD=123456;APP=Quick Test Pro;WSID=IBM;DATABASE=IBM_table"
    'access
    方式:con.open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=d:\test.mdb"
    'Orocle
    方式:con.open "DRIVER={Oracle in OraHome92};SERVER=CESHI;UID=CND_TEST;PWD=CND;DBQ=CESHI;DBA=W;APA=T;EXC=F;XSM=Default;FEN=T;QTO=T;FRC=10;FDL=10;LOB=T;RST=T;GDE=F;FRL=Lo;BAM=IfAllSuccessful;MTS=F;MDI=Me;CSR=F;FWC=F;PFC=10;TLO=O;"
    set record=createobject("adodb.recordset")
    sql="select*from ibm_one_table"
    record.open sql,con
    DO
    if(record("ibm_table_column")="kai")then'//
    查找表格中有多少kai
    num=num+1;
    end if
    record.movenext
    loop until record.eof=true
    record.close
    set record=nothing
    con.close
    set con=nothing
    end sub

    10
    "is+*"类型function
    isarray'
    是否是数组
    isconnected'
    判断QTP是否连接到TD
    isdate'
    是否是合法的日期类型
    isempty'
    判断是否初始化
    isNull'
    判断是否为空值
    isNumeric'
    判断是否是数字型
    isobject'
    判断是否一个功能对象
    isready'
    判断设备是否准备就绪
    isRootFolder'
    是否是根目录

    11
    for方法1,参数化时选择:dtLocalSheet
    Dim CountNum
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    For i=0 to CountNum-1
    ----xunhuanti------
    DataTable.GetSheet("Action1").SetNextRow    //
    使用SetNextRow方法
    Next

    12
    for方法2,参数化时选择:dtLocalSheet
    dim countNum
    countNum = DataTable.GetSheet("Action1").GetRowCount
    For i=1 to countNum
    DataTable.GetSheet("Action1").SetCurrentRow(i)  //
    使用SetCurrentRow(i)方法
    ―――ddd―――
    next
    13
    while方法1,参数化时选择:dtLocalSheet
    Dim CountNum,i
    i=1
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    While i<=CountNum
    ------xuhuanti---
    DataTable.GetSheet("Action1").SetNextRow
    i = i+1
    Wend

    14
    while方法2,参数化时选择:dtLocalSheet
    Dim CountNum,i
    i=1
    CountNum=DataTable.GetSheet("Action1").GetRowCount
    While i<=CountNum

    DataTable.GetSheet("Action1").SetCurrentRow(i)
    ----xuhuanti---
    i = i+1
    Wend

     

     

    第三部分

    15Do while方法
    Dim i,RowCount '
    定义两个变量
    i=0
    RowCount=DataTable.GetSheet("Action1").GetRowCount '
    设置RowCount等于Action1中的行数。
    msgbox RowCount
    Do while i<rowcount
    i=i+1 '
    第一次进入循环,执行这句后,i=1
    'DataTable.GetSheet("Action1").SetCurrentRow(i)  
    这句话被我注释掉了,正确的写法应该是下面这样,分开写。

    datatable.getsheet("Action1")
    datatable.setcurrentrow(i)

    ----xunhuanti----
    loop

    16
    、取对象属性(Property)值

    Dim usname
    usname =Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame_2").WebEdit("addressVO.name").GetRoProperty("Value")   '获取对象属性(Property)值,如PropertyValue
    MsgBox usname

    17
    、取得要删除的id,并删除
    'url
    在查看该新增记录的信息页面对象中取得,所以录制的时候,登记,查看(修改),删除

    Dim strUserid,id,strId

         id=Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame_4").GetROProperty("url") 'url这个属性值中存在我需要删除记录的ID信息
      strId=Mid (id,instr(60,id,"=")+1)  '
    这一步是把需要的id值取了出来,例如:strId=Mid (id,instr(1,id,"=")+1)
         strUserid =strId  'strUserid
    是我要删除的记录前的复选框属性值当中的ID信息
    Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame").WebCheckBox("value:="&strUserid).Set "ON" 这样就把想删除的记录选中了。
    Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame").WebButton(" ").Click '这样就删除掉啦,呵呵

    17.2
    通过数据库取得id值,并赋值进行删除

    Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame_2").WebEdit("addressVO.name").Set DataTable("p_Text", dtGlobalSheet)
    Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame_2").WebEdit("addressVO.address").Set DataTable("p_Text1", dtGlobalSheet)

    Browser("
    测试登录").Page("办公自动化系统").Frame("mainFrame_2").WebEdit("addressVO.unitTel").Set DataTable("p_Text2", dtGlobalSheet)

    Dim xname,address,unitTel
    xname=DataTable("p_Text", dtGlobalSheet)   '
    datatable中取值
    address=DataTable("p_Text1", dtGlobalSheet)
    unitTel=DataTable("p_Text2", dtGlobalSheet)

    Dim res,cmd,sql
    Set res=createobject("adodb.recordset")
    Set cmd=createobject("adodb.command")
    Cmd.activeconnection="DRIVER={Oracle in OraHome92};SERVER=HKORACLE;UID=USER22;PWD=ZJLH;DBQ=HKORACLE;DBA=W;APA=T;EXC=F;XSM=Default;FEN=T;QTO=T;FRC=10;FDL=10;LOB

  • 自动化测试框架设计指南

    2008-12-19 14:01:57

    Tarun Lalwani在《Guidelines for Automation Framework Design》一文中提出了自动化测试框架设计时应该考虑的20个方面:

    (1)选择合适的框架类型。
    (2)不要重复发明轮子。
    (3)可重用性。
    (4)支持对不同版本的程序的测试。
    (5)脚本的版本控制。
    (6)脚本的开发调试与发布环境应该分离。
    (7)外部可配置。
    (8)自适应性。
    (9)测试对象改变时,框架所需的修改应该最小化。
    (10)框架的执行。
    (11)状态监视。
    (12)报告。
    (13)修改框架时应该尽量不依赖自动化测试工具。
    (14)框架应该易于调试。
    (15)
    日志
    (16)易使用性。
    (17)灵活性。
    (18)性能。
    (19)开发框架配套的外部工具。
    (20)代码标准和规范。

  • 基于Web的自动化测试方法及应用

    2008-12-19 14:00:16

     随着Internet和Intranet/Extranet的快速增长,Web已经对商业、工业、教育、政府和娱乐及我们的工作生活产生了深远的影响。因为Web能提供支持所有类型内容连接的信息发布,容易为最终用户存取,更多传统的信息和数据库系统正在被移植到互联网上;电子商务正迅速增长,范围广泛的、复杂的分布式应用也正在Web环境中出现。基于Web的系统在变得越来越复杂的同时,Web应用软件的缺陷危机也更加严重、更加广泛。

      在Web工程过程中,基于Web系统的测试、确认和验收已成为一项重要而富有挑战性的工作。Web测试也毫无例外地必须进行自动化测试。以期能通过自动化测试工具按照测试工程师的预定计划进行自动化测试,来减轻手工测试的劳动量,从而达到提高软件质量的目的。

      两种基于Web的测试方法

      笔者长期以来一直从事Exchange Server 2007、E14(未来的Exchange Server 2009)的基于Web的帮助功能及UI测试,OWA(Outlook Web Access)的功能和UI测试。在实际工作中也深感各种应用Web化已经是大势所趋。

      Microsoft Exchange的Web功能和UI测试大部分是基于自动化测试,在此希望和大家一起讨论和分享一下Web自动化测试的方法和经验。

      基于Web的测试基本上采用两种思路和方法:一种可以称为“Browsers测试”(浏览器端测试)。这种测试通常是模拟浏览器端的一些操作,比如在TextBox输入一些文本,选择ComboBox中的某个选项。因为可以得到具体的操作界面,这种方法更多地应用到UI和Localization方面的测试。在进行OWA的46种语言的Localization方面测试时,我们就采用了这种方法,对各种操作产生出来的界面进行抓图,然后对这些screenshot进行分析,以发现一些UI和Localization方面的问题。

      另一种方法称为“Protocol测试”(协议测试)。这种方法是建立在HTTP协议级的测试,通过POST或Web Service向服务器发送请求,然后对服务器响应回来的数据进行解析、验证。对一些功能测试,会更多地采用这种方法。最简单的应用就是检查链接的有效性,向服务器发送URL请求,检查响应回来的数据,来判断链接是否指向正确的页面。

      在实际项目中,我们可以根据具体需求进行选择。以下是这两种方法优缺点的比较:

     测试方法  优点  缺点
     浏览器测试  能够测试客户真实的操作场景  慢
     协议测试  快,稳定 不能对UI和一些脚本进行测试 

      览器端测试的具体应用

      对于这种模拟浏览器端操作的测试,微软已经有了非常成熟的测试框架,其中应用比较广泛的是ECHO和KAF。ECHO是一个可以驱动Web UI的、面向对象的测试架构,它允许终端用户使用XML或受.Net托管的编程语言,如C#来编写自动化测试用例。而KAF可谓ECHO的后继者,目前基于ECHO的测试项目都在逐渐向KAF迁移。这是因为KAF不但包括ECHO的大部分功能,而且支持多种浏览器(目前支持IE和Firefox),对页面上的动态元素也有很好的支持,灵活性更强。当然这些测试架构都是微软内部使用的工具,是不允许对外发布的。但大部分的Web UI测试架构都是建立在如下的设计思路,按照这样的设计思路,我们完全可以构建封装适合自己项目的Web UI测试架构进行浏览器端的测试(见图1)。


      图1

      (1)UI Element

      Web页面是由一系列的对象元素组成的,比如按钮、文本框等。UI Element就代表了这些通用的网页接口元素。UI Element类一般都是super class(超类),这个类通常会有以下的类成员:

      string Name: UI Element元素的名称。作为这个元素的唯一标识。
      Driver UIDriver: 是对UI Element所使用的UI驱动实施的一个引用。针对不同的浏览器会选择不同的驱动方法。
      List<List<UIElementAttr>>AttributeLists: UI Element属性的集合,UI Driver将遍历所有的属性列表去定位匹配的Element。当某个元素在不同的状态可能会有不同的属性时,例如我们熟知的button的三态,我们就需要有多个属性列表。UIElementAttr通常是一个集合,一般包含有属性名称、属性值、是否准确匹配等。
      string ContainerName: UI Element所在的容器名称。对于Web页面,就是指元素所在的框架的名称。
      以上只是一些基本的类成员,可以根据实际情况对这个类进行补充。通常我们会创建一些UIElement子类内置到我们的测试架构中,这此子类主要是如下的一些常见的Web控件:

    TextBox
    Button
    RadioButton
    Link
    Label
    Image
    Checkbox
    SelectItem
    ComboBox
    DropDownMenu

      我们通常会将静态的UI Element存储到XML文档,这样做的好处是当UI Element元素发生变化时,只需要修改这个XML文档,而不必修改我们的测试代码。

      有时候可能在Test Cases运行期间,用来确定UI Element唯一性的属性会变化,这时候我们也需要用编码动态地去更新属性列表,来创建这个UI Element。

      (2)Browser Agent

      我们设计Web测试框架最主要的目的就是能够让测试代码在不同的浏览器,比如IE、Firefox中都能自动地、正常地运行。提供Browser Agent可以更灵活设置浏览器的类型,以及完成一些常规的浏览器功能,比如清除浏览器的缓存及载入页面等。

      (3)UI Driver Interface

      为了实现测试代码在不同浏览器都能够自动执行这个目的,可以抽象出一个UI的驱动层。在这一层里可以设计出能在各种浏览器里执行的、所有可能的UI动作,而且我们设计的Test Cases也只与这一层进行交互。这样可以将驱动的实现与Test Cases进行分离,将来Test Cases的修改不会影响到Driver Implement层代码的实现部分,而且UI Driver Implement层的改变也会不影响到测试代码。常见的一些方法如下:

    Click(…):
    Select(…):
    DragAndDrop(…)
    GetTitle(…):
    PressKey(…):

      (4)UI Driver Implement
      这是建立一个Web测试架构的基础,对于不同的浏览器可能会采用不同的驱动实现方法。

      协议级测试的具体应用

      图2

  • 用TestComplete实现一个关键字驱动测试框架(转载)

    2008-12-19 13:47:32

    最近在做使用TestComplete做一个自动化测试项目的时候,发现在TestComplete中,可以利用其中的FindChild方法来实现一个简单的关键字驱动的框架,方法如下:

    (1)在Excel编写测试关键字。
    在Excel文件中编写测试关键字,包括测试对象、测试操作、输入的参数等,如图所示:
     
    (2)编写测试脚本,读入Execl中的测试关键字。
    // 全局的变量数组,用于存储从Excel读入的测试关键字
    Var KeyWord_TestObject,KeyWord_Operation,KeyWord_Parameters;
    //.............................................................................
    // 目的:通过ADO查询Excel数据
    // 输入参数:
    //           ExcelFilePath :Excel文件的路径
    //           QueryString:查询语句
    // 返回结果:
    //           返回所有关键字数据,赋值给KeyWord_TestObject,KeyWord_Operation,KeyWord_Parameters这3个全局的变量数组
    // 注意事项:
    // 作者:陈能技
    // 日期:2008-6-3
    //.............................................................................
    Function ReadKeyWordFromExcel(ExcelFilePath,QueryString);
     Var ConStr,Connection,RS,ClassObjArray,LineIndex,ClassObject:OleVariatn;
    begin
     // 定义连接串
     ConStr := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%S;Extended Properties=Excel 8.0';
     ConStr := Utilities.Format(ConStr,[ExcelFilePath]);
     Connection := Sys.OleObject('ADODB.Connection');
     // 打开连接
     Connection.Open(ConStr);
     // 执行查询操作
     RS := Connection.Execute(QueryString);
     // 创建变量数组
     KeyWord_TestObject := CreateVariantArray(0,0);
     KeyWord_Operation := CreateVariantArray(0,0);
     KeyWord_Parameters := CreateVariantArray(0,0);
     LineIndex := 0;
     // 循环读入所有数据
     While Not RS.EOF do
     begin
        Inc(LineIndex);
        // 动态修改数组大小
        VarArrayRedim(KeyWord_TestObject,LineIndex-1);
        VarArrayRedim(KeyWord_Operation,LineIndex-1);
        VarArrayRedim(KeyWord_Parameters,LineIndex-1);  
        // 赋值
        KeyWord_TestObject[LineIndex-1] := RS['TestObject'].Value;
        KeyWord_Operation[LineIndex-1] := RS['Operation'].Value;
        KeyWord_Parameters[LineIndex-1] := RS['Parameters'].Value;   
        // 下一条数据
        RS.MoveNext;
     end;
     RS.Close;
     // 关闭连接
     Connection.Close;
    end;
    Procedure Test_ReadKeyWordFromExcel;
     Var I : OleVariant;
    begin
     ReadKeyWordFromExcel('D:\Code\MyTestSuite\Data\KeyWord.xls','Select * from [KeyWord$]');
     For I := 0 to VarArrayHighBound(KeyWord_TestObject,1) do
     begin
        Log.Message(VarToStr(KeyWord_TestObject[I])+ '   | '
                   + VarToStr(KeyWord_Operation[I])+' | '
                   + VarToStr(KeyWord_Parameters[I]));
     end; 
    end;
     
    (3)封装一个函数,用于根据Excel读入的测试关键字创建可用的测试对象。
    Uses CheckUIPerformance;
    //.............................................................................
    // 目的:返回当前进程中的指定测试对象
    // 输入参数:
    //           Process :进程对象
    //           TestObject:测试对象的描述
    // 返回结果:
    //           返回当前进程中的指定测试对象
    // 注意事项:
    // 作者:陈能技
    // 日期:2008-6-3
    //.............................................................................
    Function getObject(Process,TestObject);
    var
     PropArray, ValuesArray;
    begin
     PropArray := CreateVariantArray(0, 0);
     ValuesArray := CreateVariantArray(0, 0);
     PropArray[0] :='FullName';
     ValuesArray[0] := TestObject;
     // 调用 FindTestObject 函数,返回当前进程中的指定测试对象
     Result := FindTestObject(Process,PropArray,ValuesArray);
    end;
     
    这里调用了CheckUIPerformance脚本中编写的FindTestObject函数,该函数用于根据测试对象的描述信息查找指定进程中的测试对象,脚本如下:
    Function FindTestObject(Process,PropArray,ValueArray);
     var res;
    begin
     Result := False;
     // 查找指定的测试对象
     Process.Refresh();
     res := Process.FindChild(PropArray, ValueArray, 1000);
     // 返回测试对象
     if res.Exists then
     begin
        Result := res;
        Log.Message('找到测试对象: ' + res.FullName)
     end
     else
        Log.Message('未找到测试对象');
    end;
     
    (4)封装一个函数,用于根据Excel读入的测试关键字执行测试操作。
    //.............................................................................
    // 目的:执行测试操作
    // 输入参数:
    //           TestObject :测试对象
    //           Operation:测试操作的描述
    //           Parameters:测试操作对应的参数
    // 返回结果:无
    // 注意事项:
    // 作者:陈能技
    // 日期:2008-6-3
    //.............................................................................
    Function DoOperation(TestObject,Operation,Parameters);
    begin
     case Operation of
        'Keys' : TestObject.Keys(Parameters);
        'Click' : TestObject.Click;
        // 添加其它类型的测试操作的处理代码 ...
     else
        Log.Error('不支持该测试操作!');
     end; 
    end;
     
    注:这里仅仅添加了 Keys 和 Click 的测试操作。
     
    (5)关键字驱动的核心框架
    有了前面几个函数的基础,就可以写出下面一个简单的关键字驱动的核心框架:
    //.............................................................................
    // 目的:关键字驱动的核心框架
    // 输入参数:
    // 返回结果:
    // 注意事项:
    // 作者:陈能技
    // 日期:2008-6-3
    //.............................................................................
    Procedure Driver;
     Var TestObject,I;
    begin
     // 1、读入关键字
     ReadKeyWordFromExcel('D:\Code\MyTestSuite\Data\KeyWord.xls','Select * from [KeyWord$]');
     // 2、遍历关键字,创建测试对象、执行测试操作
     For I := 0 to VarArrayHighBound(KeyWord_TestObject,1) do
     begin
    //    Log.Message(VarToStr(KeyWord_TestObject[I])+ '   | '
    //               + VarToStr(KeyWord_Operation[I])+' | '
    //               + VarToStr(KeyWord_Parameters[I]));
        // 创建测试对象
        TestObject := getObject(Sys.Process('flight4a'),VarToStr(KeyWord_TestObject[I]));
        // 执行测试操作
        DoOperation(TestObject,VarToStr(KeyWord_Operation[I]),VarToStr(KeyWord_Parameters[I]));  
     end;
    end;
     
    经试验,这种方法是可以实现类似QTP的关键字驱动测试框架,但是仅仅是一个非常基础的关键字驱动测试框架,如果想把这个框架应用在实际项目中的话,还需要进一步地修改和完善,还有很多工作要做,包括:
    (1)关键字编辑器的编写。
    目前采用直接在Excel文件中填写测试关键字的方法,存在效率和可用性问题,需要创建一个类似QTP的更加好用的关键字视图编辑器。
    (2)添加更多的测试操作和方法。
    目前作为试验,仅仅添加了 Keys 和 Click 的测试操作,还有很多控件的很多测试方法需要封装,例如List控件的ClickItem、SelectItem等,另外,对测试对象的属性赋值操作、属性检查操作(类似于QTP的CheckPoint)等都需要进一步地编写框架代码来处理。
    (3)关键字代码与测试脚本之间的同步。
    仅仅依赖Excel的关键字数据来实现整个项目的自动化测试未免过于理想化了,QTP提供了很好的代码生成机制,关键字视图的数据与专家视图的测试脚本之间可以随时同步、切换,因此这个关键字驱动测试框架还缺少一个代码生成器,如何建立Excel数据与测试脚本之间的映射关系是下一步的主要工作之一。

数据统计

  • 访问量: 10374
  • 日志数: 17
  • 文件数: 1
  • 建立时间: 2008-12-11
  • 更新时间: 2009-06-19

RSS订阅