人的烦恼源于记性太好 忘记过去才能重新开始

发布新日志

  • 项目总结--针对当前的工作情况进行总结

    2009-07-19 20:24:12

    很久很久没有做过总结了。
    得出的最大的结论就是,人不能懒惰,要天天总结,要月月总结,并且时时刻刻进行总结。我自知还是做不到这一点,而且是差很远,个人太懒惰了。基于这个懒惰,我已经一个月没有干活了,导致的结果就是,测试部这几个月都没什么成绩,没什么作为。
     
    项目终于向上线进军了。应该还有两个月的时间。刚刚安逸的过了一个月,这个月立马就暴露出来很多很多问题,测试做的不够,开发修改程序错误太多。于是,今天的总结会,针对开发人员的问题总结了很多,但是针对测试人员,依然还是没有目标,每次都是这样,讨论着讨论着,都是以开发人员为主了,貌似没我们测试人员什么事情。吃完饭,还是和领导讨论了一下,强行要进行测试方面工作的讨论。终于给出了目前的工作方向。让我不再迷茫混乱了。至少我知道目前该做些什么了,而不是每天素手无策的等待着问题的出现。
     
    分配问题,一定要给自己留出余地,否则,重要的问题都压在自己这边,而又无暇顾及的时候,欲哭无泪。只能重新调整一下方案,以目前的工作重心来安排工作。先集中力量,然后再测试各自负责的模块。
     
    对于之前说的,当一个开发人员的同一个功能模块,反复出现问题的时候,测试和开发其实都有问题,测试不全面,程序本身写的就有问题,所有的问题其实都只是表面的,根本的流程和业务之间的关系没有理顺的话,程序的修改永远都只是停留在表面,所以,问题就像水里的木头一样,按下这头,那头又浮起来了。
     
    要抽出时间来检查一下他们测试出来的问题,以及问题的跟踪情况。发觉张的做事方式有些问题,其实还是领导发现的,平时基本上我都只管自己。其实我自己做事的方式也很有问题,只是我还没发现问题在什么地方,我想最好能跟领导之间做个交流,看看他们觉得我的问题都在什么地方。
     
    其实相处了这么久,每个开发人员容易发生什么问题,以及个人的做事方式,差不多了解了,剩下的就是根据他们的特点去关注问题。有的开发人员,修改问题容易引进新的问题,并且解决的速度慢,不催促就不干活,不去问就永远不给你回复。有的人就很自觉,交流协作都很容易,做事积极主动,效率高。测试也就有重点了。
     
    这么大的项目,三个测试人员,我还要每天负责一些乱七八糟的事情,真正测试的时间很少。尽在进行协调和讨论了。测试技术我真的是没有一点提高,咳。张呢,工作也不积极了,工作的情商也不高,要多督促。丁,新来的,积极,有热情,但是业务不熟悉,测试效率还是不高。要想这么大的项目,没有问题,是不可能的,只能是尽量少一点,但是此起彼伏的出现同一个或者类似的问题好像也是不应该的。多督促自己,多督促他们,提高工作效率!
     
  • 项目小结。针对不规范的测试。

    2008-09-09 21:03:33

    进继续教育组已经快半年了,有些疲了,慢慢的就习惯了为了工作而工作。

    个人心得体会:

    1.测试计划一定要订,不一定执行,虽然计划总是不适合,并且总是处于变化之中,还是需要计划,大的小的,都是要订一个的。

    2.不要指望开发人员能帮你进行测试,有这个想法还不如让他们做单元测试。

    3.不同的测试阶段测试的重点是不同的。在项目最开始,主要保证流程能走通。流程走通了以后再进行功能的完整测试,包括界面,一些不影响功能使用的,以及边界等方面。

    4.测试的过程中尽量多和项目经理或者开发人员交流测试的情况,有什么问题,可以让他们出出主意想想办法。往往他们总会给你提出有建设性的意见。

    5.和开发人员之间有什么矛盾,不要憋在心里,要直接交流,虽然有一些聊天或者联系的工具,还是以直接交流比较好,前提是不影响他工作的情况,以及在不频繁的情况下。(有时对一些开发人员的做法很是恼火,但是如果心里压抑着,做事就会很郁闷,所以强迫自己去和开发人员交流 。比如,有一个开发人员,把我提交的问题,全部都以不可再现的解决方式提交,我大为恼火,哪那么多不可再现的,具体情况,你具体备注一下,什么都没有标识就全部不可再现。再加上当时和他关系有点说不清楚(总感觉他对我有意见),所以那时我很郁闷,想了好久,还是决定直接和他说说,哪些是不可再现的,哪些是不属于他的功能,哪些是不需要修改的问题。和他说的时候,其他开发人员也都在,大家在一起笑笑,然后说说,事情就这么给解决了。我重新打开这些bug,他重新提交一下问题解决的方式。后来有什么不懂或者有异议的他都直接和我交流,这样大家做事又恢复了和谐。)

    6.多进行交流。无论是和开发人员,还是和测试人员。流程这东西,交流的越多你就理解的越多。有时候交流了才知道,原来他们是这么实现的,于是你就知道自己该如何设计测试。交流的时候,一定要多听听别人的想法,不能想当然,但是也要把握自己的立场。

    处理不好的问题:

    1.有些开发人员,写出来的代码质量很差,导致修改的时候,一而再,再而三的出现问题,双方都很恼火的时候,该如何解决这样的情况,还不是很有办法。一方面,要考虑他的心情,改的次数太多,他要疯了。而我,因为每次流程走不下来,也快崩溃了。所以有的时候还是尽量以开玩笑的方式对待这些,既不让自己郁闷,也不让他觉得你是故意刁难他。结果就是,他的问题改了很多遍才勉强能使用。让项目经理或者小组组长去批评他?我感觉这样适得其反。现在的年轻人,脾气都大的很。万一不爽,走人。怕怕,得罪不起。

    2.总感觉测试受开发人员的制约太严重。有的时候,明明感觉任务很紧很重,可就是力不从心。你加班的时候,开发人员不加班。流程走不下去,根本没办法。我想还是跟公司的测试以及开发的环境有关系。记得有一个贴子说是公司测试部要先进行一个预测试,通过了才提交到测试人员手里。而我们这边是测试人员直接使用开发工具把程序弄过来进行测试,根本不存在什么版本控制以及预测试的说法。这也不是我一个人能说了算的。哎。

     

     

     

  • 今天又使用QC了。

    2008-07-14 20:31:14

    发觉测试用例很难管理。用excel管理的话,新写的和以前的能放一个里面,但是要是给别人执行的话,就比较不好管理了。每天要给他发新写的用例,又要保存以前执行的记录。于是又想起来了QC了,刚好有9.0的破解文件,于是没费什么力气就装好了。

    这里我使用jboss服务器,oracle 10g数据库,在进行数据库配置的时候,出了点小问题。一般数据库管理员的帐号 我使用的是 sys  可惜配置的过程中,默认是system,虽然密码我都是一样的,但是,还是用system才能配置成功,不知道什么问题。整个上午基本都是在研究如何使用QC,基本的用用还行,下午的时候已经开始写测试用例到QC上去,有个问题就是以前写的如何弄到QC中去呢?晚上搜索了下,可以使用excel的插件。(明天安装看看)。

    还有个问题就是测试用例的执行如何管理。

    不知道qc的bug管理如何,有待学习。。

    CVS,QTP,LR,VBS都要学习,加油,别老想着玩了。

  • QuickTestProfessional基本使用示例(转载)

    2008-06-15 22:53:05

    1          设置脚本间的间隔时间

    Wait(2),单位:秒

    2          循环语句while

    i=0

    do while(i<10)

    Window("Opera").Restore

    Window("Opera").WinObject("OperaWindowClass").Click 446,232

    Window("Opera").WinObject("OperaWindowClass").Click 461,278

    i=i+1

    loop

    3         循环语句for

    For i=1 to 3

           Window("Opera").Restore

    Window("Opera").WinObject("OperaWindowClass").Click 446,232

    Window("Opera").WinObject("OperaWindowClass").Click 461,278

    Next

    4          判断语句

    Do while(i<20)

    Browser("XX项目").Page("XX项目").Frame("wap").Link("啤酒").Click

    wait(2)

    Browser("XX项目").Page("XX项目").Frame("wap_2").Link("商铺详情").Click

    wait(2)

    i=i+1

    If i=5 Then

           Exit do

    End If

    Loop

    5          With语句

    Do while(i<20)

    With Browser("XX项目")

    .Page("XX项目").Frame("wap").Link("生活家居").Click

    .Page("XX项目").Frame("wap_5").Link("出租(火爆招租中)").Click

    .Page("XX项目").Sync

    With .Page("XX项目")

    .Frame("wap_6").Image("image").Check CheckPoint("image")'检查点

    .Frame("wap_6").Link("返回XX首页").Click

    .Sync

    .Frame("wap").Check CheckPoint("生活家居")'检查点

    End with

    End with

    i=i+1

    If i=3 Then

        i=21

    End If

    Loop

    6         检查点

    Browser("XX项目").Page("XX项目").Frame("wap").Link("生活家居").Click

    Browser("XX项目").Page("XX项目").Frame("wap_5").Link("出租(火爆招租中)").Click

    Browser("XX项目").Page("XX项目").Sync

    Browser("XX项目").Page("XX项目").Frame("wap_6").Image("image").Check CheckPoint("image")'检查点

    Browser("XX项目").Page("XX项目").Frame("wap_6").Link("返回XX首页").Click

    Browser("XX项目").Page("XX项目").Sync

    Browser("XX项目").Page("XX项目").Frame("wap").Check CheckPoint("生活家居")'检查点

    7           引用函数

    Function  hjq(i)

       msgbox("hjq")

    End Function

     

    Do while(i<20)

    '开始

    Browser("XX项目").Page("XX项目").Frame("wap").Link("啤酒").Click

    wait(2)

    Browser("XX项目").Page("XX项目").Frame("wap_2").Link("商铺详情").Click

    '详情

    i=i+1

    If i=3 Then

        i=21

    End If

    Call hjq(i)

    Loop

    8           引用action

    录制action1,在step->action properties中设置该actionreuseable action

    录制action2,在inser->call to exiting action,选择action1

    OK

    9           参数化

    keyword view中设置对象的value为参数,并设置值

    With Browser("XX项目_2").Page("XX项目")

           With .Frame("wap_2")

                  .WebEdit("key").Set "1"

                  .WebButton("").Click

           End With

           .Frame("wap_3").Link("重新搜索").Click

           With .Frame("wap")

                  .WebEdit("key").Set DataTable("p_Text", dtGlobalSheet)

                  .WebButton("").Click

           End With

           .Sync

    End With

    10       Vbs随机读取一行文本内容

    '随机读取文件中的一行

    randomize 

    set fso=createobject("scrīpting.filesystemobject")  '创建文件系统对象

    set a=createobject("scrīpting.dictionary")  '类似于二维数组

    set file=fso.opentextfile("D:\hjq.txt")  '打开文件

    do while file.atendofstream<>true 

    m=m+1  'm记录文件中文本行数

    a.add m,file.readline  'file.readline读取某行记录

    loop 

    file.close  '关闭文件

    h=int(rnd*m) 

    msgbox "" & h & ":  " & a(h) ,4096,"随机内容"

    msgbox "1:  " & a(1) ,4096,"内容"

    msgbox "2:  " & a(2) ,4096,"内容"

    msgbox "3:  " & a(3) ,4096,"内容"

    11       二维数组的使用

    set a=createobject("scrīpting.dictionary")  '类似于二维数组

    a.add 0,"返回XX首页"

    a.add 1,"返回XX首页"

    a.add 2,"返回XX首页"

    a.add 3,"返回XX首页"

     

    For i=0 to 3

     

    With Browser("XX项目").Page("XX项目")

           With .Frame("wap")

                  .WebEdit("key").Set "1"

                  .WebButton("").Click

           End With

           .Frame("wap_2").Link(a(i)).Click

           .Sync

    End With

    Next

    12       从文件读取文本,并赋予参数

    set fso=createobject("scrīpting.filesystemobject")  '创建文件系统对象

    set a=createobject("scrīpting.dictionary")  '类似于二维数组

    set file=fso.opentextfile("D:\hjq.txt")  '打开文件

    wait(2)

    do while file.atendofstream<>true

    With Browser("XX项目").Page("XX项目")

           With .Frame("wap")

                  .WebEdit("key").Set  file.readline

                  .WebButton("").Click

           End With

           .Frame("wap_2").Link("返回XX首页").Click

           .Sync

    End With

    loop 

    file.close  '关闭文件

    13       读取csv文件并分割字符串

    Dim aasplit

    set fso=createobject("scrīpting.filesystemobject")  '创建文件系统对象

    set file=fso.opentextfile("D:\hjq.csv")  '打开csv文件

    wait(2)

    Do while file.atendofstream<>true

        aasplit=split(file.readline,",")',分割字符串

     

           For i=0 to UBound(aasplit)

     

                  With Browser("XX项目").Page("XX项目")

                         With .Frame("wap")

                                .WebEdit("key").Set  aasplit(i)

                                .WebButton("").Click

                         End With

                         .Frame("wap_2").Link("返回XX首页").Click

                         .Sync

                  End With

                 

           Next

     

    loop 

    file.close  '关闭文件

    14       怎样识别弹出的web窗口和对象

    1,  进入object identification

    2,  enviroment中选择web

    3,  选择某个test object class,如browser

    4,  添加mandatory properties

    5,  确定

    6,  重新录制脚本

    7,  OK

    15       Vbs写文件

    set fs =createobject("scrīpting.filesystemobject")

    if (fs.fileexists("c:\hjq.txt")) then

    set f =fs.opentextfile("c:\hjq.txt",8)

    f.write chr(13)+chr(10)

    f.write "hello"

    f.write chr(13)+chr(10)

    f.writeline "beijing"

    f.close

    else

    set f=fs.opentextfile("c:\hjq.txt",2, true)

    f.writeblanklines 2 '写入2个空行

    f.write "china"

    f.close

    end if

     

    16       基本函数

    QTP的基本使用函数:

    1, 获取对话框相应的文字: GetVisible Text

    2, 查找相应的字符串: instr (1,查找目标字符串,所查找的字符串)

    3, 随机数的获取: Randomnumber.Value() cstr(int(Rnd*10)+1)

    4, 等待函数: Wait(秒数)

    5, 获取数组下标: UBound (数组名)

    6, 拆分数组: Split(MyString, ",", -1, 1)

    7, 可执行步骤: OptionalStep

    8, 报告信息: Reporter.ReportEvent 3, "Save Step", "Out of cycle!"

    9, 判断对话框是否存在: .exist

    10,事件过滤函数:Reporter.Filter=过滤条件(0123)0代表显示所有的errorwarning,1,显示error,2,显示waining,3,任何errorwarning都不显示。

    11,循环函数:do … loop untilfor…to… then next,while.

    12,数据表格:DataTable,向外赋值,Dim aa = DataTable.value(“CellingName”,”ActionName”).

    13,获得对象属性的三种方法GetTOPropertyGetTOProperties,GetROProperty,GetTOProperty获得程序中对象当前的属性,GetTOProperties获得当前属性所有集合,GetROProperty获得的是录制时对象所获得的属性。

    14,检查点方法check和输出指定属性值output

    15,函数Descrīption,可以获得某页面同标签的属性进行操作。

    16,函数nagative可以随便跳转页面到指定的URL

    17,函数Object可以获得当前页面同属性的控件。

    18,函数Focus可以让控件获得焦点,函数Blur则是失去焦点,click单击,dbclick双击。

    19,函数setAttribute可以设置控件属性,getAttribute可以获得属性。

  • 一、QTP识别对象的原理

    2008-05-31 00:10:09

    一、QTP识别对象的原理(by yabest, http://yabest.net)

    QTP里的对象有两个概念,一个是Test Object(简称TO),一个是Runtime Object(简称RO)。
    这两个概念从字面上不大好理解,也容易混淆。
    但从实际作用上来看,应该说TO就是是仓库文件里定义的仓库对象,RO是被测试软件的实际对象。

    QTP识别对象,一般是要求先在对象仓库文件里定义仓库对象,里面存有实际对象的特征属性的值。
    然后在运行的时候,QTP会根据脚本里的对象名字,在对象仓库里找到对应的仓库对象,
    接着根据仓库对象的特征属性描述,在被测试软件里搜索找到相匹配的实际对象,最后就可以对实际对象进行操作了。

    仓库对象TO一般在录制/编写脚本时加入仓库文件,它不仅可以在录制编写时进行修改,
    也可以在运行过程中进行动态修改,以匹配实际对象。

    和TO、RO相关的几个函数有:

    GetTOProperty():取得仓库对象的某个属性的值
    GetTOProperties():取得仓库对象的所有属性的值
    SetTOProperty():设置仓库对象的某个属性的值

    GetROProperty():取得实际对象的某个属性的值


    理解了TO的含义,你就可以自由的用SetTOProperty()定义TO,以灵活的操作RO

    比如有个测试任务,窗口上有很多待检查的记录,每条记录右边都有一个Check按钮,用来检查各条记录。
    记录个数不定,所以Check按钮个数也就不定,只有一个Edit显示记录个数。
    我们要对每条记录进行检查,也就是要点击每个Check按钮。
    但是Check按钮个数不定,不好录制,而且个数可能也很多(上百个),即使能一一录制,那也很麻烦。

    那我有一个好办法,只录制一个按钮对象,它设有两个特征属性 label=OK, index=0
    然后用下面的脚本,就可以完成测试

    buttonNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
    For buttonIndex = 0 to buttonNum - 1
      JavaWindow("Test").JavaButton("Check").SetTOProperty("index", buttonIndex)
      JavaWindow("Test").JavaButton("Check").Click
    Next


    或者窗口上有New、Modify、Delete、Check等好几个按钮,要把这几个按钮一一按过去
    我在对象仓库里只设置一个按钮对象AnyButton,label特征属性值填任意值,然后用下面脚本执行测试

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "New")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Modify")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Delete")
    JavaWindow("Test").JavaButton("AnyButton").Click

    JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Check")
    JavaWindow("Test").JavaButton("AnyButton").Click

    另外,QTP还支持脚本描述的方法来定义和访问对象,即不需要在仓库里定义,也能访问和操作实际对象
    ( Written by yabest,http://yabest.net )

    如上面两个任务,可以如下实现

    1. 不需要在仓库里定义Check按钮对象,直接用下面脚本来实现测试

    buttonNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
    For buttonIndex = 0 to buttonNum - 1
      JavaWindow("Test").JavaButton("label:=Check", "index:="+CStr(buttonIndex)).Click
    Next

    2. 不需要在仓库里定义New、Modify、Delete、Check按钮对象,直接用下面脚本来实现测试

    JavaWindow("Test").JavaButton("label:=New").Click
    JavaWindow("Test").JavaButton("label:=Modify").Click
    JavaWindow("Test").JavaButton("label:=Delete").Click
    JavaWindow("Test").JavaButton("label:=Check").Click



    二、QTP操作对象的原理(by yabest, http://yabest.net)

    QTP为用户提供了两种操作对象的接口,一种就是对象的封装接口,另一种是对象的自身接口。

    对象的自身接口是对象控件本身的接口,只要做过软件开发,使用过控件的人应该很清楚。
    对象的封装接口是QTP为对象封装的另一层接口,它是QTP通过调用对象的自身接口来实现的。


    两种接口的脚本书写格式的差别在于:
      自身接口需要在对象名后面加object再加属性名或方法名,
      封装接口就不用在对象名后面加object。

    具体格式如下:
      对实际对象的操作:
          对象.object.自身属性
          对象.object.自身方法()
          对象.GetROProperty("封装属性")
          对象.封装方法()

      对仓库对象的操作:
          对象.GetTOProperty("封装属性")
          对象.GetTOProperties()      ’获取所有封装属性的值
          对象.SetTOProperty("封装属性", "封装属性值")

    比如操作JavaEdit对象,通过QTP封装的封装接口,脚本如下:
      设置JavaEdit的内容:
         JavaDialog("Add NE").JavaEdit("NE Name").Set "NE1"
      读取JavaEdit的内容:
         msgbox JavaDialog("Add NE").JavaEdit("NE Name").GetROProperty("value")

    如果通过JavaEdit的自身接口,脚本如下:
      设置JavaEdit的内容:
         JavaDialog("Add NE").JavaEdit("NE Name").object.setText("NE1")
      读取JavaEdit的内容:
         Msgbox JavaDialog("Add NE").JavaEdit("NE Name").object.getText()

    QTP执行JavaEdit().Set语句时,是通过执行JavaEdit().object.setText()来实现的。
    QTP执行JavaEdit().GetROProperty("value"),是通过执行JavaEdit().object.getText()来实现的。
    JavaEdit对象的封装接口Set()和GetROProperty("value"),是QTP封装JavaEdit对象的自身接口setText()和getText()而得来的。

    对象的封装接口是QTP使用的缺省接口,我们录制出来的脚本都是使用封装接口,大家用的也都是封装接口。
    但是封装接口不如自身接口丰富,因为QTP只是封装了部分常用的自身接口嘛。
    所以我们在需要时,可以绕过封装接口,直接调用对象的自身接口。
    不过有些自身接口不够稳定,在实践中偶尔会出现问题,但是概率很少。
    封装接口有相应功能的话,就尽量用封装接口吧!
    ( Written by yabest,http://yabest.net )

    理解了封装接口和自身接口的原理,我们就可以更加灵活的操作对象了。

    但是我们怎么知道对象都有哪些封装接口和自身接口呢?
    其实很简单,用对象查看器(Object Spy)查看对象,在查看窗口里有列出这些接口,包括属性和方法。
    窗口中间有选择栏让你选择Run-time Object或者Test Object,
    当你选择Runtime Object时,它显示的就是对象的自身接口(自身的属性和方法)
    当你选择Test Object时,它显示的就是对象的封装接口(封装的属性和方法)

    (注意:GetROProperty访问的是实际对象的封装接口,GetTOProperty访问的是仓库对象的封装接口,
                两者访问的都是对象的封装接口,即Object Spy窗口里选Test Object时显示的属性。
                不要以为GetROProperty访问的是自身接口,即Object Spy窗口里选Run-time Object时显示的属性。
                QTP里的Test Object/Run-time Object的概念太容易让人混淆了!
                它既用来区分仓库对象和实际对象,又用来区分对象的封装接口和自身接口。



    明白了这些,你还等什么呢?快拿起对象查看器,看看对象都有哪些封装接口和自身接口,肆意的操作它,玩弄它吧!

    比如执行
      JavaDialog("Add NE").JavaEdit("NE Name").object.setVisible(false)
    哈哈,你的JavaEdit对象就当场消失不见了!!!

    你可以拿这个做恶作剧,指着这个窗口逼问开发人员,JavaEdit对象哪去了?
    开发人员肯定瞪大眼睛看着这个窗口,当场翘掉!!!
  • 空间开通一个月啦。

    2007-11-11 10:16:04

    空间开通一个月了都没写点什么,以后多写点,有什么想法和心得都该写写。
Open Toolbar