日历

« 2008-10-12  
   1234
567891011
12131415161718
19202122232425
262728293031 

我的好友

统计信息

  • 访问量: 1083
  • 日志数: 8
  • 建立时间: 2007-12-04
  • 更新时间: 2008-04-11

RSS订阅

我的最新日志

  • 软件测试笔试题目上(转)

    2008-4-11

    题与答案尽供参考

    一、判断题

    1.软件测试的目的是尽可能多的找出软件的缺陷。(Y

    2Beta 测试是验收测试的一种。(Y

    3.验收测试是由最终用户来实施的。(N

    4.项目立项前测试人员不需要提交任何工件。(Y

    5.单元测试能发现约80%的软件缺陷。(Y

    6.代码评审是检查源代码是否达到模块设计的要求。(N

    7.自底向上集成需要测试员编写驱动程序。(Y

    8.负载测试是验证要检验的系统的能力最高能达到什么程度。(N

    9.测试人员要坚持原则,缺陷未修复完坚决不予通过。(N

    10.代码评审员一般由测试员担任。(N

    11.我们可以人为的使得软件不存在配置问题。(N

    12.集成测试计划在需求分析阶段末提交。(N

    二、选折

    1.软件验收测试的合格通过准则是:(ABCD

    A 软件需求分析说明书中定义的所有功能已全部实现,性能指标全部达到要求。

    B 所有测试项没有残余一级、二级和三级错误。

    C 立项审批表、需求分析文档、设计文档和编码实现一致。

    D 验收测试工件齐全。

    2.软件测试计划评审会需要哪些人员参加?(ABCD

    A.项目经理

    BSQA 负责人

    C.配置负责人

    D.测试组

    3.下列关于alpha 测试的描述中正确的是:(AD

    Aalpha 测试需要用户代表参加

    Balpha 测试不需要用户代表参加

    Calpha 测试是系统测试的一种

    Dalpha 测试是验收测试的一种

    4.测试设计员的职责有:(BC

    A.制定测试计划

    B.设计测试用例

    C.设计测试过程、脚本

    D.评估测试活动

    5.软件实施活动的进入准则是:(ABC

    A.需求工件已经被基线化

    B.详细设计工件已经被基线化

    C.构架工件已经被基线化

    D.项目阶段成果已经被基线化

    三、添空

    1.软件验收测试包括:正式验收测试,alpha测试,beta测试。

    2.系统测试的策略有:功能测试,性能测试,可靠性测试,负载测试,易用性测试,强度测试,安全测试,配置测试,安装测试,卸载测试,文挡测试,故障恢复测试,界面测试,容量测试,兼容性测试,分布测试,可用性测试,(有的可以合在一起,分开写只要写出15就满分哦)

    3.设计系统测试计划需要参考的项目文挡有:软件测试计划,软件需求工件和迭代计划。

    4.对面向过程的系统采用的集成策略有:自顶向下,自底向上两种。

    5.(这题出的有问题哦,详细的5步骤为~~)通过画因果图来写测试用例的步骤为:

    1)分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),并给每个原因和结果赋予一个标识符。

    2)分析软件规格说明描述中的语义,找出原因与结果之间,原因与原因之间对应的是什么关系? 根据这些关系,画出因果图。

    3)由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况不可能出现。为表明这些特殊情况,在因果图上用一些记号标明约束或限制条件。

    4)把因果图转换成判定表。

    5)把判定表的每一列拿出来作为依据,设计测试用例。

    四、简答(资料是搜集整理的,感谢前辈的解题)无

    1.区别阶段评审的与同行评审

    同行评审目的:发现小规模工作产品的错误,只要是找错误;

    阶段评审目的:评审模块 阶段作品的正确性 可行性 及完整性

    同行评审人数:3-7 人员必须经过同行评审会议的培训,SQA指导

    阶段评审人数:5人左右 评审人必须是专家 具有系统评审资格

    同行评审内容:内容小 一般文档 <  40, 代码 < 500

    阶段评审内容: 内容多,主要看重点

    同行评审时间:一小部分工作产品完成

    阶段评审时间: 通常是设置在关键路径的时间点上!

    2.什么是软件测试

    为了发现程序中的错误而执行程序的过程

    3简述集成测试的过程

    系统集成测试主要包括以下过程:

    1. 构建的确认过程。

    2. 补丁的确认过程。

    3. 系统集成测试测试组提交过程。

    4. 测试用例设计过程。

    5. 测试代码编写过程。

    6. Bug的报告过程。

    7. 每周/每两周的构建过程。

    8. 点对点的测试过程。

    9. 组内培训过程。

    4 怎么做好文档测试

    仔细阅读,跟随每个步骤,检查每个图形,尝试每个示例。P142

    检查文档的编写是否满足文档编写的目的

    内容是否齐全,正确

    内容是否完善

    标记是否正确

    5 白盒测试有几种方法

    总体上分为静态方法和动态方法两大类。

    静态:关键功能是检查软件的表示和描述是否一致,没有冲突或者没有歧义

    动态:语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、条件组合覆盖、路径覆盖。

    6系统测试计划是否需要同行审批,为什么

    需要,系统测试计划属于项目阶段性关键文档,因此需要评审。

    7Alpha测试与beta的区别

    Alpha测试 在系统开发接近完成时对应用系统的测试;测试后仍然会有少量的设计变更。这种测试一般由最终用户或其它人员完成,不能由程序或测试员完成。

    Beta测试 当开发和测试根本完成时所做的测试,最终的错误和问题需要在最终发行前找到。这种测试一般由最终用户或其它人员完成,不能由程序员或测试员完成。

    8比较负载测试,容量测试和强度测试的区别

    负载测试:在一定的工作负荷下,系统的负荷及响应时间。

    强度测试:在一定的负荷条件下,在较长时间跨度内的系统连续运行给系统性能所造成的影响。

    容量测试:容量测试目的是通过测试预先分析出反映软件 系统应用特征的某项指标的极限值(如最大并发用户数、数据库记录数等),系统在其极限值状态下没有出现任何软件故障或还能保持主要功能正常运行。容量测试 还将确定测试对象在给定时间内能够持续处理的最大负载或工作量。容量测试的目的是使系统承受超额的数据容量来发现它是否能够正确处理。容量测试是面向数据 的,并且它的目的是显示系统可以处理目标内确定的数据容量。

    9测试结束的标准是什么?

    用例全部测试。
    覆盖率达到标准。
    缺陷率达到标准。
    其他指标达到质量标准

    10描述软件测试活动的生命周期?

    测试周期分为计划、设计、实现、执行、总结。其中:

    计划:对整个测试周期中所有活动进行规划,估计工作量、风险,安排人力物力资源,安排进度等;
    设计:完成测试方案,从技术层面上对测试进行规划;
    实现:进行测试用例和测试规程设计;
    执行:根据前期完成的计划、方案、用例、规程等文档,执行测试用例。

    总结:记录测试结果,进行测试分析,完成测试报告。

    11软件的缺陷等级应如何划分?

    A类—严重错误,包括以下各种错误: 1. 由于程序所引起的死机,非法退出 2. 死循环 3. 数据库发生死锁 4. 因错误操作导致的程序中断 5. 功能错误 6. 与数据库连接错误 7. 数据通讯错误

    B类—较严重错误,包括以下各种错误: 1. 程序错误 2. 程序接口错误 3. 数据库的表、业务规则、缺省值未加完整性等约束条件

    C类—一般性错误,包括以下各种错误: 1. 操作界面错误(包括数据窗口内列名定义、含义是否一致) 2. 打印内容、格式错误 3. 简单的输入限制未放在前台进行控制 4. 删除操作未给出提示 5. 数据库表中有过多的空字段

    D类—较小错误,包括以下各种错误: 1. 界面不规范 2. 辅助说明描述不清楚 3. 输入输出不规范 4. 长操作未给用户提示 5. 提示窗口文字未采用行业术语 6. 可输入区域和只读区域没有明显的区分标志

    E类—测试建议

  • QTP的学习历程[转载]

    2007-12-06

         对于我来说,学习QTP是一个漫长而有艰苦的过程 重伤 。首先我不是计算机及相关专业毕业的(医学相关)。跳入测试部时,我正在接受程序员的培训课程。由于自己认为需要,于是开始学习QTP。

        刚开始使用QTP,就一直对着说明书,不停的“订飞机票”(订飞机票是说明书里的一个例子)。学会了一个步骤就拿到公司产品上玩玩,回忆起来还是挺有趣的。

       当我用一些简单的功能开始录制脚本时,发现保存ActiveXScreen的话,生成的脚本很中空间(因为程序会保存每个不同的录制页面),多录一些硬盘空间就满了,而且回放过程会很慢。 郁闷 但如果不保存活动页(ActiveXScreen),对脚本的再改造/维护起来就相对困难一些。

       于是我开始去了解“关键字”视图里的内容,尝试了解代码。慢慢的,我了解到“关键字”视图显示了整个操作步骤,第个组件相对于程序里一个元素。同时还记录了录制过程对该元素的操作和结果。

        然后我又开始在论坛在找些资料看看,从有点所谓的高级应用中,我发现脚本的维护并不一定要有“活动页”。实际是QTP所有对象的识别,都存在脚本的一个对象库里了。QTP经常出现无法识别对象的问题,可以从这里着头修改。 灯泡 
       为了减少QTP脚本占用空间大、录制慢的问题。我查阅了一些资料,可以在设置中进行修改,让脚本中不保存活动控件(ActiveX)或仅保存出错时的录制页面。干脆,我就从此录制页面了。所有的调试都从“关键字”视图和“专家”视图中进行修改。而且关于对象库,QTP也有个选项,可以设置加载页面上所有的对象,我修改成只保存页面上录制过程使用的对象。 咖啡 这样,脚本的容量问题就解决了,录制后的脚本会比以前小很多,来了个彻底的瘦身。关于录制速度的问题,和保存“活动页”、动态脚本也有一定的关系,另外可以减小启动的加载项(如:去掉VB插件、.net插件,不需要的就不加进来)。这样的脚本上传到TestDirector上,或从TestDirector上调用就不会太慢了。

       然而真正的问题,棘手的问题就不是上面所述的那么简单了。不过都是有办法解决了的,嘿嘿……
       以下是我经常遇到的问题:
           一、无法识别控件。
           二、错误回放过程未知弹出窗口。
           三、加载.net插件后和TD的关联问题。
           四、动态加载元素的识别问题。
           五、调用外部dll的问题。
           六、随机验证码的问题。

    问题一,解决办法有三种:
       1、更改QTP自身对某控件的识别方式,在 tools——Object Identification 中。在这里列出了所有QTP能识别的控件,以及控件的识别方式。你可以给他添加X、Y坐标进行识别。或更明显的,列表中的信息,不按名称识别,而是按ID识别。这个修改可以解决一些问题,具体的赶紧动手试试吧……
       2、使用虚拟物件,来定义一个控件,在 tools——Virtual Object 中。在这里可以自定义一个控件。例如在ASP的程序中,程序出错,在客户端的表现形式大部分是一样的,你可以把整个错误页面当成一个控件来识别(感觉不错)。如果加一个判断,出错后你想做什么就由你自己定了。
       3、使用低级录制或鼠标录制。用 Test——LowLevelRecording/AnlogRecording 吧,用它录制就不需要什么设置了,他会记录你的程序控件相对屏幕的位置。用LowLevelRecording还有代码可改,用AnlogRecording动作就被封装了(维护性极差)。两者因实际环境更取其长吧……

    问题二的解决过程:
    关于弹出提示的问题,我当时需要情况是这样的。一个信息录入系统,由于数据量很大,查询需要一段时间。QTP回放时动作比较快,点了保存,程序还没反应过来它就进行了下一步操作。这时的操作就和录制时不一样了,程序给出一个提示,但这个提示是录制过程没有的。弹出框是一般都是POP形势(至上)的,导致QTP无法继续回放,结果就是回放失败。 调皮 
    解决办法有两个:
            1、进行判断,当出现这个提示时,点是/否/取消按钮。
            2、通过 Tools——Recorvery Scenario Manager 设置默认操作。
        我最初就是用的第一种方法。写一个函数判断是否出现这个提示,如果出现就点“取消”然后wait(2)。    每个可能出现弹出框的动作后都调用一次这个函数。虽然可以解决这个问题,但回放的效率就低了,而且需要你预知提示框的信息。
        当我知道了第二种方法,显然更科学^_^。它可以对所有预知甚至不知的提示进行指定的操作。
        实际上,当程序出现了未预知的提示时,可能就是程序的BUG,所以使用上述办法解决工具问题时,也要考虑是否会掩盖程序的缺陷。

    问题三的解决办法:
          用好QTP后,会不自觉的和TD关联起来。但从TD直接启动QTP时,程序只会加载QTP自带的插件,如果你安装了其它插件(如.net、java、etc.),默认是不加载的。这会导致上传的脚本无法正确执行。解决办法很简单,去 Test——Setting里进行Modify 吧。从本地打开的脚本,这里不能进行Modify的。所以办法很简单,但如果不知道的话就很难了。当初为这个问题我可是废了八牛三虎之力呢……

    问题四的解决过程:
         当我开始改代码时,定义一个动作,然后可以生成N个动作。假设N个动作产生了N个结果,你要对这结果进行处理时,你会发现这N个结果都不能被识别:

    网页上有个表格,是往数据库里加数据的。
    两个表格显示在同一个页面上,左边为父表,右边为子表。
    点击左表,右表显示其子项目。 
    结构如下: 闹钟 
    A
    ├─1
    ├─2
    ├─3
    └─4
    B
    ├─1
    ├─2
    ├─3
    └─4
                        ……
    思想很清晰:
    添加一个父项A、选中此父项A、对其添加子项1、2、3、4
    添加一个父项B、选中此父项B、对其添加子项1、2、3、4  ……

    代码也很简单:
    dim M          '定义父项数
    dim N          '定义每个父项包含的子项数

    For i=1 to M
          Call 添加父项( i )       
          选中父项( i )              '问题就出在这里 流泪 
       For j=1 to bwfl step 1
           Call 添加子项( j )
        Next       
    Next

    现在问题出来了,思路应该没有问题(除非这方法真的行不通),循环也是顺着思想来的。

    问题是,无法实现选中的父项(最多识别到一个)。
    由于此循环可以在录制过程进行,如果不改变变量名称,循环可且只可以成功运行一次。问题是这个名称都是从DataTable里获取的。
    因为,在运行过程中生成的项目没有加到对象库中,无法被识别。

       这个问题最后是从思想上解决的。答案是我做的是功能测试,为什么不先加父项,检查父项的功能是否正常,然后再去测子项的功能。不去改变名字,因为那没有必要。核心答案“功能测试、测试功能”。即对测试工具首先需要有正确的认识。
       当然,这个问题可以用代码去实现,但那需要有一定的编程功底且耗时,可维护性不一定好。有需要的朋友可以去试一下,然后把你的经验也共享一下。  *^_^*

    问题五,是对QTP很大的一个扩充。 强 
        对于QTP调用外部DLL的功能,由于我的编程功底不够,没有相关人士配合我,我只能望之垂涎了!
        如果能调用外部DLL的话,QTP的功能就可以变得很强大。自己写的程序,自己编一些过程用QTP进行测试,我想“后果很严重” 偷笑 。真想有一次给我尝试的机会……

    问题六,解决办法有4个:
        1、测试的时候,让程序员把这块限制去掉,免去验证这关。
        2、让程序员提供一个万能验证码,测试可以绕过这一关。
        3、请程序员提供识别的方法,从获取的图片读出验证数据,再传给QTP。
        4、进行位图检查,将验证码分段进行图像验证。

        实际上,验证码的目的就是防止用程序灌水或机器录入信息。所以有点为难我们测试了。
    方法1,如果程序已在发布并有客户使用,危险性是可想而知的。方法2虽然可以解决验证这一关,但跳过了输入码与验证码一致性问题。方法3就需要程序员配合了,可能就需要调用DLL了。方法4却将图像分段,把获取的图像和已经的图像进行比对,比对通过取对应的值;这个在数字验证会好做一点,因为最多就四个图像的比对。
        关于网上的汉字验证码,那块的测试我就不知道他们是怎么做的了。真想了解一下! 红心 
     
        以上就是我对过去QTP学习过程的一个总结。供天下各界朋友参观、发言、讨论,也是对我过去的一个写照,可能N年后,自己看到会很有感觉呢 谄媚 。
        现在又有项目来了,我学习的时间慢慢也少了。新项目里融合了C++程序,QTP对C++的识别似乎很不理想,也许是需要插件支持吧。过程中我尝试了Rational的Robot,Robot对C++的识别很好,但Rational一套组件内容太多,对汉字的支持似乎也不是很好。用了一段时间我就把它从硬盘中给清掉了…… 花谢 
        QTP的学习就在此停住了,不能应用到项目中,单纯看着说明书的学习,我好像不太在行。 微笑 也许是真的需要活学活用,边学边用吧。或者我不够书呆子吧……

  • 描述性编程不是可以医治百病的灵丹妙药

    2007-12-05

     

    昨天看见居然有人反对大量使用描述性编程而鼓励多用对象库,一时兴起,反驳了几句。没想到今天看了一下对方的回复,顿时惭愧万分,自己的经验的确不足,还需要多多学习。现将他人之玉记下,以供以后开山之用。红色为我的文笔,蓝色是best的反驳

    1、测试脚本应该灵活,而对象库固定的层次结构和名称,导致脚本太呆板,不能满足程序开发变动的导致脚本变动这一客观事实的需要!
          对象库和描述性编程,两者主要差别是把对象特征写在对象库里还是写在脚本里而已。它们的层次结构完全一样的,有什么差别吗?

    2、如果使用对象库,就必须采用录制——测试这种方式,而描述性编程可以使测试者自己编写脚本,完全脱离录制这种方式,然后灵活根据需要进行修改!这点上可以说是一种测试工作的更新!因为完全没有必要进行录制工作,减少了很多时间
      谁说一定要录制才能将对象加入仓库,我就经常直接抓取对象放入仓库,给对象起个好名字,然后手工写脚本
      而且录制也没什么不好,挺方便的,比你手工一个字母一个字母的敲出来轻松多了,还不容易出错。
      不能为了脱离依赖而搞脱离,你要看看它能给你带来什么好处。方便省事是第一的,不然你干脆用汇编用机器语言来编程好了,直接指挥硬件,最灵活,功能最强大!

    3、描述性编程+正则表达式功能非常强大,这点需要好好学习
    对象仓库里一样可以用正则表达式的啊!


    其实,对象仓库很像编程里的常数定义。

    1、首要的好处,是统一定义,一旦发生变化,只要改一个地方。
        几万行代码的大软件,使用常数定义,常数发生变化,只要改一个常数值就行了。要是没有常数定义,一旦发生变化,你在几万行代码里怎么去搜索,怎么去修改?!
        同样的,成千上万个Case里,某个对象发生了变化,你要怎么在这成千上万个Case里去搜索这个对象,怎么去修改?

    2、其次的好处,是美化代码,增加可读性。
        编程里面你不用常量,直接写个数字,代码就很难看,谁知道这个数字代表什么意思啊!
        同样的,很多对象是没有标题,或者标题很长,或者标题很凌乱的(如IP地址,后三个数字的标题都是"."),你把它加进对象库后可以给它起个好名字,这样就把复杂的对象特征屏蔽在对象库里,留给脚本的是很清晰直观的对象名。

    3、还有更重要的,你不统一定义,怎么继承和共享,尤其是多人合作开发时。
        编程时你不在一个常数库里统一定义统一共享,别人怎么知道有这个定义!到时各人各写各的,标准不一,混乱不堪。
        在QTP里面,很多对象的特征不是那么简单的,不用对象库,到时各人各自在脚本里用自己的方法来定义特征!或者不要说多个人,你自己自动化大量的Case时,你自己都记不清以前是怎么定义某些对象的特征了,可能长期下来,同个对象都有好几套特征定义了,不仅费力,还标准不一,混乱不堪。

    反正你想想编程里常数的好处就好了。

    其实对象库和描述性编程功能是差不多的,除了少数动态对象只能用描述性编程之外。

    在我们的自动化小团队里,多人合作一起自动化,对象仓库可是最重要的!
    各人写的脚本风格可以不同,但是对象仓库是统一共享的,决不允许你随意修改对象库。
    对象初次加入对象库,也要遵循约定好的命名规则,要做到简单、清晰、易记!

  • Description 对象用于编程描述

    2007-12-05

    将 Descrīption 对象用于编程描述
    使用 Descrīption 对象可以返回包含一组 Property 对象的 Properties 集合对象。Property 对象由属性名和值组成。然后,可以在语句中指定用返回的 Properties 集合代替对象名。(每个 property 对象都包含一个属性名和值对。)

    注意:默认情况下,添加到 Properties 集合的所有 Property 对象的值都将作为正则表达式处理。因此,如果希望输入包含特殊正则表达式字符(例如 *、? 和 +)的值,请使用 \(反斜杠)字符指示 QuickTest 将特殊字符作为文字字符处理。有关正则表达式的详细信息,请参阅了解和使用正则表达式。

    可以将 RegularExpression 属性设置为 False,以便将集合中特定 Property 对象的值指定为文字值。有关详细信息,请参阅《QuickTest Professional Object Model Reference》(英语版)的“实用程序”部分。

    要创建 Properties 集合,可以使用以下语法输入 Descrīption.Create 语句:

    Set MyDescrīption = Descrīption.Create()

    创建 Properties 对象(例如,以上示例中的 MyDescrīption)后,就可以输入语句,以便在运行会话期间在 Properties 对象中添加、编辑、删除或检索属性和值。这样,您可以在运行会话期间,使用动态方法确定哪个属性以及多少个属性应包含在对象描述中。

    在 Properties 集合中填充一组 Property 对象(属性和值)后,可以在测试语句中指定用 Properties 对象代替对象名。

    例如,您无须输入:

    Window("Error").WinButton("text:=OK", "width:=50").Click

    而可以输入:

    Set MyDescrīption = Descrīption.Create()
    MyDescrīption("text").Value = "OK"
    MyDescrīption("width").Value = 50
    Window("Error").WinButton(MyDescrīption).Click

    注意:在测试对象层次中的特定位置使用编程描述后,在相同语句中该位置的后面部分,必须继续使用编程描述。如果在层次中使用编程描述说明的其他对象的后面,您按对象库名指定了某个测试对象,则 QuickTest 将无法识别该对象。

    例如,您可以使用 Browser(Desc1).Page(Desc1).Link(desc3),因为该语句在整个测试对象层次中使用编程描述。

    您也可以使用 Browser("Index").Page(Desc1).Link(desc3),因为该语句从描述中的特定位置(从 Page 对象描述开始)开始使用编程描述。

    不过,您不能使用 Browser(Desc1).Page(Desc1).Link("Example1"),因为该语句对 Browser 和 Page 对象使用编程描述,但又试图对 Link 测试对象使用对象库名(QuickTest 尝试根据名称来查找 Link 对象,但无法在库中找到该对象,因为父对象是使用编程描述指定的)。

    使用 Properties 对象时,可以将变量名用于属性或值,以便根据运行会话期间检索的属性和值来生成对象描述。

    如果希望对多个对象使用编程描述,则可以在测试或组件中创建多个 Properties 对象。

  • 如何删除Oracle

    2007-12-04

    1.停止所有的Oracle服务;

    2.卸载所有的Oracle产品;

    3.在注册表中进行删除下列项目:
     a.HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
     b.HKEY_LOCAL_MACHINE\SYSTEM\CURRENTCONTROLSET\SERVICES,删除所有Oracle入口
     c.HKEY_LOCAL_MACHINE\SYSTEM\CURRENTCONTROLSET\SERVICES\EVENTLOG\APPLICATION,
       删除所有Oracle入口

    4.删除环境变量中classpath和path中有关Oracle设定;

    5.删除操作系统盘中:Programs\Files\Oracle 目录;

    6.删除Oracle的所在目录;

    7.在Win2000中,删除C:\winnt中的Oracle.int,Oraclim73.ini,Oradim80.ini,Oraodbc.ini;

    8.将win.ini中的[oracle]标记字段删除;

    9.删除与Oracle 相关ODBC的DSN;

    10.删除Oracle相关日志

    注:如果安装时出现"symcjit not found" 错误(通信通道的文件结束)
     则可通过将安装程序中的symcjit.ini 修改为symcjit.old来解决。

  • 一位高人的QTP学习笔记

    2007-12-04

    一位高人的QTP学习笔记

    转贴一个高人的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=T;RST=T;BTD=F;BAM=IfAllSuccessful;NUM=NLS;DPM=F;MTS=T;MDI=Me;CSR=F;FWC=F;FBS=60000;TLO=O;"
    Cmd.CommandType = 1
    'sql="select  addressid from address_list t where name ='"&xname&"'"
    'sql="select  

  • QTP User-Defined Function 学习经验汇总

    2007-12-04

            1. 可以通过Function Definition Generator方便的定制自定义函数(Function)
            2. Built-in Function优先级高于User-Defined Function。因此若存在同名的话,QTP会优先调用内置的Function
            3. 通过RegisterUserFunc可以将自定义的函数注册为特定对象的方法,甚至可以覆盖原有对象的方法(Method)。通过UnRegisterUserFunc取消注册
            注册方式:RegisterUserFunc TOClass, MethodName, FunctionName, True
            反注册方式:UnRegisterUserFunc TOClass, MethodName
            4. 定义在Action中的Function以及注册的Method只能在当前Action中使用,若需要供全局使用则定义到Function Library中
            5. 如果Method在Action中注册并且被其他Action调用时,该Method定义也适用于调用Action(Calling Action)。但如果Function定义在被调用Action中(Called Action),则Calling Action会因为找不到Function定义而失败。这种情况的话,需要将Function 定义在Function Library中
            6. QTP在测试执行前会清除所有的Method Register
            7. 默认情况下,User-Defined Function的运行结果不会出现在Test Result中,可以自己用Reporter.ReportEvent添加log
            8. QTP在打开Test时加载了关联的Function Library,因此,若其他人或者你用其他编辑器修改了对应的Function Library,只有在QTP重新打开该Test后才生效
            9. QTP搜索Function的顺序是先Test在Function Library。另外,同名的Function存在于多个Function Library时,后一个被使用
            10. 对于同一个Method先后注册了两个不同的Function,后面的Method注册会覆盖前面的。当用UnRegisterUserFunc反注册时,会将该Method返回到原始状态,而不会回到前一个注册
            11. 在某Action中使用ExecuteFile后,该Function只能在当前Action中使用
            12. 对于存储在QC中的外部资源,如Function Library,QTP打开时为其创建了一个本地副本。因此若其他人修改了QC上的外部资源,或你使用其他编辑器进行修改时,该修改只有在QTP重新打开该Test才生效。但对于存储在本地的外部资源,不存在该问题
            13. 在Test Settings中设置了Default Function Library列表后,新建Test时这些Library即被集成到新创建的Test中。以后对Default Function Library列表的修改对已有Test不产生任何影响。
  • QTP中Wait与同步点的区别[转]

    2007-12-04

    2007-11-21 16:37:08 / 个人分类:QTP

    先说wait函数,当脚本走到wait函数时,就开始执行这个函数.如:wait(10),就等待10秒种后再继续执行下面的语句.wait函数的这个等待的时间,那相对来说是比较固定的.如上例子,一定要等待完10秒后再执行.所以写脚本的时候要自己估算一下时间.不然可能造成时间的浪费,或者等待时间的不足.

    那同步点呢.等待时间就比较灵活了,它的等待时间是不固定的.设置同步点后,当脚本执行到这句话后,脚本就开始执行等待.脚本会在规定时间内不断的去检查,所同步的对象有没有出现,一但出现,脚本就继续往下执行.不需要等完所有规定时间.如果在规定的时间内,所要同步对象还没有出现,那就提示超时的错误信息.51testing软件测试
    例如:
    Window("Flight Reservation").ActiveX("Threed Panel Control").WaitProperty "text", "Insert Done...", 10000
    当脚本执行到这句话时,就开始执行同步等待时间.这里设置超时时间为10000.在这个时间内,脚本会不断去查看该对象的text属性的属性值Insert Done...,有没有出现.一但同步到这个属性值,就开始执行下面的脚本了.而不需要再继续等待,直到1000秒结束为止.那这样的话,这个等待时间不用自己去控制,设置好后由程序自己去判断,就比较灵活,也不会出现浪费时间的情况.能提高脚本的执行率.


Open Toolbar