日历

« 2008-10-08  
   1234
567891011
12131415161718
19202122232425
262728293031 

最新来客

我的好友

统计信息

  • 访问量: 1082
  • 日志数: 14
  • 建立时间: 2007-10-16
  • 更新时间: 2008-08-26

RSS订阅

我的最新日志

  • [转载]基于实际测试的功能测试点总结

    2008-8-26

        1. 页面链接检查:每一个链接是否都有对应的页面,并且页面之间切换正确。可以使用一些工具,如LinkBotProFile-AIDCSHTML Link ValidaterXenu等工具。LinkBotPro不支持中文,中文字符显示为乱码;HTML Link Validater只能测试以Html或者htm结尾的网页链接;Xenu无需安装,支持aspdojsp等结尾的网页,xenu测试链接包括内部链接和外部链接,在使用的时候应该注意,同时能够生成html格式的测试报告。如果系统用QTP进行自动化测试,也可以使用QTP的页面检查点检查链接。

    2. 相关性检查:

    Ø         功能相关性:删除/增加一项会不会对其他项产生影响,如果产生影响,这些影响是否都正确,常见的情况是,增加某个数据记录以后,如果该数据记录某个字段内容较长,可能会在查询的时候让数据列表变形。

    Ø         数据相关性:下来列表默认值检查,下来列表值检查,如果某个列表的数据项依赖于其他模块中的数据,同样需要检查,比如,某个数据如果被禁用了,可能在引用该数据项的列表中不可见。

      3. 检查按钮的功能是否正确:如新建、编辑、删除、关闭、返回、保存、导入,上一页,下一页,页面跳转,重置等功能是否正确。常见的错误会出现在重置按钮上,表现为功能失效。

      4. 字符串长度检查: 输入超出需求所说明的字符串长度的内容, 看系统是否检查字符串长度。还要检查需求规定的字符串长度是否是正确的,有时候会出现,需求规定的字符串长度太短而无法输入业务数据。

      5. 字符类型检查: 在应该输入指定类型的内容的地方输入其他类型的内容(如在应该输入整型的地方输入其他字符类型),看系统是否检查字符类型。

      6. 标点符号检查: 输入内容包括各种标点符号,特别是空格,各种引号,回车键。看系统处理是否正确。常见的错误是系统对空格的处理,可能添加的时候,将空格当作一个字符,而在查询的时候空格被屏蔽,导致无法查询到添加的内容。

      7.特殊字符检查:输入特殊符号,如@#$%!等,看系统处理是否正确。常见的错误是出现在% ‘ \ 这几个特殊字符

      8. 中文字符处理: 在可以输入中、英文的系统输入中文,看会否出现乱码或出错。

      9. 检查信息的完整性: 在查看信息和更新信息时,查看所填写的信息是不是全部更新,更新信息和添加信息是否一致。要注意检查的时候每个字段都应该检查,有时候,会出现部分字段更新了而个别字段没有更新的情况。

      10. 信息重复: 在一些需要命名,且名字应该唯一的信息输入重复的名字或ID,看系统有没有处理,会否报错,重名包括是否区分大小写,以及在输入内容的前后输入空格,系统是否作出正确处理。

      11. 检查删除功能:在一些可以一次删除多个信息的地方,不选择任何信息,按“delete”,看系统如何处理,会否出错;然后选择一个和多个信息,进行删除,看是否正确处理。如果有多页,翻页选,看系统是否都正确删除,并且要注意,删除的时候是否有提示,让用户能够更正错误,不误删除。

      12. 检查添加和修改是否一致: 检查添加和修改信息的要求是否一致,例如添加要求必填的项,修改也应该必填;添加规定为整型的项,修改也必须为整型.

      13. 检查修改重名:修改时把不能重名的项改为已存在的内容,看会否处理,报错.同时,也要注意,会不会报和自己重名的错.

      14. 重复提交表单:一条已经成功提交的纪录,返回后再提交,看看系统是否做了处理。对于Web系统来说,可以通过浏览器返回键或者系统提供的返回功能。

      15. 检查多次使用返回键的情况: 在有返回键的地方,返回到原来页面,重复多次,看会否出错。

      16. 搜索检查: 有搜索功能的地方输入系统存在和不存在的内容,看搜索结果是否正确.如果可以输入多个搜索条件,可以同时添加合理和不合理的条件,看系统处理是否正确,搜索的时候同样要注意特殊字符,某些系统会在输入特殊字符的时候,将系统中所有的信息都搜索到。

      17. 输入信息位置: 注意在光标停留的地方输入信息时,光标和所输入的信息会否跳到别的地方。

      18. 上传下载文件检查:上传下载文件的功能是否实现,上传文件是否能打开。对上传文件的格式有何规定,系统是否有解释信息,并检查系统是否能够做到。下载文件能否打开或者保存,下载的文件是否有格式要求,如需要特殊工具才可以打开等。上传文件测试同时应该测试,如果将不能上传的文件后缀名修改为可以上传文件的后缀名,看是否能够上传成功,并且,上传文件后,重新修改,看上传的文件是否存在。

      19. 必填项检查:应该填写的项没有填写时系统是否都做了处理,对必填项是否有提示信息,如在必填项前加“*”;对必填项提示返回后,焦点是否会自动定位到必填项。

      20. 快捷键检查:是否支持常用快捷键,如Ctrl+C Ctrl+V Backspace等,对一些不允许输入信息的字段,如选人,选日期对快捷方式是否也做了限制。

      21. 回车键检查: 在输入结束后直接按回车键,看系统处理如何,会否报错。这个地方很有可能会出现错误。

      22.刷新键检查:在Web系统中,使用浏览器的刷新键,看系统处理如何,会否报错。

      23.回退键检查:在Web系统中,使用浏览器的回退键,看系统处理如何,会否报错。对于需要用户验证的系统,在退出登录后,使用回退键,看系统处理如何;多次使用回退键,多次使用前进键,看系统如何处理。

      24.直接URL链接检查:在Web系统中,直接输入各功能页面的URL地址,看系统如何处理,对于需要用户验证的系统更为重要。如果系统安全性设计的不好,直接输入各功能页面的URL地址,很有可能会正常打开页面。

      25.空格检查:在输入信息项中,输入一个或连串空格,查看系统如何处理。如对于要求输入整型、符点型变量的项中,输入空格,既不是空值,又不是标准输入。

      26.输入法半角全角检查:在输入信息项中,输入半角或全角的信息,查看系统如何处理。如对于要求输入符点型数据的项中,输入全角的小数点(“。”或“.”,如4.5);输入全角的空格等。

      27.密码检查:一些系统的加密方法采用对字符Ascii码移位的方式,处理密码加密相对较为简单,且安全性较高,对于局域网系统来说,此种方式完全可以起到加密的作用,但同时,会造成一些问题,即大于128Ascii对应的字符在解密时无法解析,尝试使用“uvwxyz”等一些码值较大的字符作为密码,同时,密码尽可能的长,如17位密码等,造成加密后的密码出现无法解析的字符。

      28.用户检查:任何一个系统,都有各类不同的用户,同样具有一个或多个管理员用户,检查各个管理员之间是否可以相互管理,编辑、删除管理员用户。同时,对于一般用户,尝试删除,并重建同名的用户,检查该用户其它信息是否重现。同样,提供注销功能的系统,此用户再次注册时,是否作为一个新的用户。而且还要检查该用户的有效日期,过了有效日期的用户是不能登录系统的。容易出现错误的情况是,可能有用户管理权限的非超级管理员,能够修改超级管理员的权限。

      29.系统数据检查:这是功能测试最重要的,如果系统数据计算不正确,那么功能测试肯定是通不过的。数据检查根据不同的系统,方法不同。对于业务管理平台,数据随业务过程、状态的变化保持正确,不能因为某个过程出现垃圾数据,也不能因为某个过程而丢失数据。

    30.系统可恢复性检查:以各种方式把系统搞瘫,测试系统是否可正常迅速恢复。

    31.确认提示检查:系统中的更新、删除操作,是否提示用户确认更新或删除,操作是否可以回退(即是否可以选择取消操作),提示信息是否准确。事前或事后提示,对于UpdateDelete操作,要求进行事前提示。

      32.数据注入检查:数据注入主要是对数据库的注入,通过输入一些特殊的字符,如“”,“/”,“-”等或字符组合,完成对SQL语句的破坏,造成系统查询、插入、删除操作的SQL因为这些字符而改变原来的意图。如select * from table where id = ‘ ’ and  name = ‘  ,通过在id输入框中输入“12’-”,会造成查询语句把name条件注释掉,而只查询id=12的记录。同样,对于updatedelete的操作,可能会造成误删除数据。当然还有其它一些SQL注入方法,具体可以参考《SQL应用高级SQL注入.doc,很多程序都是基于页面对输入字符进行控制的,可以尝试跳过界面直接向数据库中插入数据,比如用Jmeter,来完成数据注入检查。

      33.刷新检查:web系统中的WebForm控件实时刷新功能,在系统应用中有利有弊,给系统的性能带来较大的影响。测试过程中检测刷新功能对系统或应用造成的影响(白屏),检查控件是否回归默认初始值,检查是否对系统的性能产生较大影响(如每次刷新都连接数据库查询等)。

      34.事务检查:对于事务性操作,断开网络或关闭程序来中断操作,事务是否回滚。

      35.时间日期检查:时间、日期验证是每个系统都必须的,如2006-2-292006-6-31等错误日期,同时,对于管理、财务类系统,每年的1月与前一年的12月(同理,每年的第1季度与前一年的第4季度)。另外,对于日期、时间格式的验证,如20062282006-2-2820060228等。日期检查还要检查日期范围是否符合实际的业务,对于不符合时间业务的日期,系统是否会有提示或者有限制

      36.多浏览器验证:越来越多的各类浏览器的出现,用户访问Web程序不再单单依赖于Microsoft Internet Explorer,而是有了更多的选择:MaxthonFirefoxTencent Traveler等,考虑使用多种浏览器访问系统,验证效果。

      37.安装测试:对于C/S架构的系统,安装程序的测试是一个重要方面,安装程序自动化程度、安装选项和设置(验证各种方案是否都能正常安装)、安装过程中断测试、安装顺序测试(分布式系统)、修复安装及卸载测试。

      38.文档测试:主要是对用户使用手册、产品手册进行测试,校验是否描述正确、完整,是否与当前系统版本对照,是否易理解,是否二义性等。

      39.测试数据检查:事实告诉我们,测试数据比代码更有可能是错的,因此,当测试结果显示有错误发生的时候,怀疑代码错误前要先对测试数据检查一遍。

      40.请让我的机器来运行:在某些项目中,出现一个病态的问题:系统没有问题呀,它在我的机器上是能够通过的。这就说明了其中存在着和环境相关的BUG。“是否所有的一切都受到了版本控制工具的管理?”、“本机的开发环境和服务器的环境是否一样?”、“这里是否存在一个真正的BUG,只不过是在其他的机器里偶然出现?”。所有的测试必须在所有系统要求的机器上运行通过,否则的话,代码就可能存在问题。

      41Ajax技术的应用:Ajax有很多优点,但也有很多缺点,如果利用优点、避免缺点,是我们对新的Web2.0应用的一个挑战。而Ajax的应用最直接的问题就是用户体验,用户体验的效果直接关系到是否使用Ajax技术。“会做,并不意味着应该做、必须做”,这就是对Ajax技术的很重要的注解。

      42Ajax技术的应用:Ajax采用异步调用的机制实现页面的部分刷新功能,异步调用存在异常中断的可能,尝试各种方法异常中断异步的数据调用,查看是否出现问题。在这里遇到的一个问题就是对日期控件的操作,已经如果页面数据较多的时候的刷新。

      43.脚本错误:随着AjaxIFrame等异步调用技术的发展,Javascrīpt技术也越来越受到开发人员的重视,但Javascrīpt存在调试困难、各浏览器存在可能不兼容等问题,因此在Web系统中,可能会出现脚本错误。同时,脚本错误造成的后果可大、可小,不能忽视。

  • 腾迅也有BUG哦

    2008-7-25

    腾迅也有BUG哦
  • QuickTest Plus帮助文档中EXCEL相关函数

    2008-3-25

    QuickTest Plus帮助文档中EXCEL相关函数

    打开QTP,test--settings--resources,将附件文件添加进去就可以使用相关函数了

    ?
    Dim ExcelApp    'As Excel.Application
    Dim excelSheet  'As Excel.worksheet
    Dim excelBook   'As Excel.workbook
    Dim fso         'As scrīpting.FileSystemObject

    ' *********************************************************************************************
    ' 函数说明:创建一个Excel应用程序ExcelApp,并创建一个新的工作薄Workbook;
    ' 参数说明:无
    ' 调用方法:
    '           CreateExcel()
    ' *********************************************************************************************

    Function CreateExcel()
        Dim excelSheet
        Set ExcelApp = CreateObject("Excel.Application")
        ExcelApp.Workbooks.Add  
        ExcelApp.Visible = True
        Set CreateExcel = ExcelApp
    End Function

    ' *********************************************************************************************
    ' 函数说明:关闭Excel应用程序;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    ' 调用方法:
    '           CloseExcel(ExcelApp)
    ' *********************************************************************************************
    Sub CloseExcel(ExcelApp)
        Set excelSheet = ExcelApp.ActiveSheet
        Set excelBook = ExcelApp.ActiveWorkbook
        Set fso = CreateObject("scrīpting.FileSystemObject")
        On Error Resume Next
        fso.CreateFolder "C:\Temp"
        fso.DeleteFile "C:\Temp\ExcelExamples.xls"
        excelBook.SaveAs "C:\Temp\ExcelExamples.xls"
        ExcelApp.Quit
        Set ExcelApp = Nothing
        Set fso = Nothing
        Err = 0
        On Error GoTo 0
    End Sub

    ' *********************************************************************************************
    ' 函数说明:保存工作薄;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)path:保存的路径;
    ' 返回结果:
    '          (1)保存成功,返回字符串:OK
    '          (2)保存失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           ret = SaveWorkbook(ExcelApp, "Book1", "D:\Example1.xls")
    ' *********************************************************************************************
    ' 函数说明:保存工作薄;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)path:保存的路径;
    ' 返回结果:
    '          (1)保存成功,返回字符串:OK
    '          (2)保存失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           ret = SaveWorkbook(ExcelApp, "Book1", "D:\Example1.xls")
    ' *********************************************************************************************
    Function SaveWorkbook(ExcelApp, workbookIdentifier, path) 'As String
        Dim workbook
        On Error Resume Next  '启用错误处理程序
        Set workbook = ExcelApp.Workbooks(workbookIdentifier)
        On Error GoTo 0   '禁用错误处理程序
        If Not workbook Is Nothing Then
            If path = "" Or path = workbook.FullName Or path = workbook.Name Then
                workbook.Save
            Else
                Set fso = CreateObject("scrīpting.FileSystemObject")
                '判断路径中是否已添加扩展名.xls
                If InStr(path, ".") = 0 Then
                    path = path & ".xls"
                End If
                '删除路径下现有同名的文件
                On Error Resume Next
                fso.DeleteFile path
                Set fso = Nothing
                Err = 0
                On Error GoTo 0
               
                workbook.SaveAs path
            End If
            SaveWorkbook = "OK"
        Else
            SaveWorkbook = "Bad Workbook Identifier"
        End If
    End Function
    ' *********************************************************************************************
    ' 函数说明:设置工作表excelSheet单元格的值
    ' 参数说明:
    '          (1)excelSheet:工作表名称;
    '          (2)row:列的序号,第一列为1;
    '          (3)column:行的序号,第一行为1;
    '          (4)value:单元格要设置的值;
    ' 返回结果:
    '          无返回值
    ' 调用方法:
    '           SetCellValue excelSheet1, 1, 2, "test\"
    ' *********************************************************************************************
    Sub SetCellValue(excelSheet, row, column, value)
        On Error Resume Next
        excelSheet.Cells(row, column) = value
        On Error GoTo 0
    End Sub
    'The GetCellValue returns the cell's value according to its row column and sheet
    'excelSheet - the Excel Sheet in which the cell exists
    'row - the cell's row
    'column - the cell's column
    'return 0 if the cell could not be found
    ' *********************************************************************************************
    ' 函数说明:获取工作表excelSheet单元格的值
    ' 参数说明:
    '          (1)excelSheet:工作表名称;
    '          (2)row:列的序号;
    '          (3)column:行的序号;
    ' 返回结果:
    '          (1)单元格存在,返回单元格值;
    '          (2)单元格不存在,返回0;
    ' 调用方法:
    '           set CellValue = GetCellValue(excelSheet, 1, 2)
    ' *********************************************************************************************
    Function GetCellValue(excelSheet, row, column)
        value = 0
        Err = 0
        On Error Resume Next
        tempValue = excelSheet.Cells(row, column)
        If Err = 0 Then
            value = tempValue
            Err = 0
        End If
        On Error GoTo 0
        GetCellValue = value
    End Function
    ' *********************************************************************************************
    ' 函数说明:获取并返回工作表对象
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)sheetIdentifier:属于ExcelApp的工作表名称;
    ' 返回结果:
    '          (1)成功:工作表对象Excel.worksheet
    '          (1)失败:Nothing
    ' 调用方法:
    '           Set excelSheet1 = GetSheet(ExcelApp, "Sheet Name")
    ' *********************************************************************************************
    Function GetSheet(ExcelApp, sheetIdentifier)
        On Error Resume Next
        Set GetSheet = ExcelApp.Worksheets.Item(sheetIdentifier)
        On Error GoTo 0
    End Function
    ' *********************************************************************************************
    ' 函数说明:添加一张新的工作表
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (2)sheetName:要插入的工作表名称;
    ' 返回结果:
    '          (1)成功:工作表对象worksheet
    '          (1)失败:Nothing
    ' 调用方法:
    '           InsertNewWorksheet(ExcelApp, workbookIdentifier, "new sheet")
    ' *********************************************************************************************

    Function InsertNewWorksheet(ExcelApp, workbookIdentifier, sheetName)
        Dim workbook 'As Excel.workbook
        Dim worksheet 'As Excel.worksheet

        '如果指定的工作薄不存在,将在当前激活状态的工作表中添加工作表
        If workbookIdentifier = "" Then
            Set workbook = ExcelApp.ActiveWorkbook
        Else
            On Error Resume Next
            Err = 0
            Set workbook = ExcelApp.Workbooks(workbookIdentifier)
            If Err <> 0 Then
                Set InsertNewWorksheet = Nothing
                Err = 0
                Exit Function
            End If
            On Error GoTo 0
        End If

        sheetCount = workbook.Sheets.Count  '获取工作薄中工作表的数量
        workbook.Sheets.Add , sheetCount '添加工作表
        Set worksheet = workbook.Sheets(sheetCount + 1)  '初始化worksheet为新添加的工作表对象

        '设置新添加的工作表名称
        If sheetName <> "" Then
            worksheet.Name = sheetName
        End If

        Set InsertNewWorksheet = worksheet
    End Function

    ' *********************************************************************************************
    ' 函数说明:修改工作表的名称;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)worksheetIdentifier:属于workbookIdentifier工作薄的工作表名称;
    '          (4)sheetName:修改后的工作表名称;
    ' 返回结果:
    '          (1)修改成功,返回字符串:OK
    '          (2)修改失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           set ret = RenameWorksheet(ExcelApp, "Book1", "Sheet1", "Sheet Name")
    ' *********************************************************************************************

    Function RenameWorksheet(ExcelApp, workbookIdentifier, worksheetIdentifier, sheetName)
        Dim workbook
        Dim worksheet
        On Error Resume Next
        Err = 0
        Set workbook = ExcelApp.Workbooks(workbookIdentifier)
        If Err <> 0 Then
            RenameWorksheet = "Bad Workbook Identifier"
            Err = 0
            Exit Function
        End If
        Set worksheet = workbook.Sheets(worksheetIdentifier)
        If Err <> 0 Then
            RenameWorksheet = "Bad Worksheet Identifier"
            Err = 0
            Exit Function
        End If
        worksheet.Name = sheetName
        RenameWorksheet = "OK"
    End Function

    ' *********************************************************************************************
    ' 函数说明:删除工作表;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)worksheetIdentifier:属于workbookIdentifier工作薄的工作表名称;
    ' 返回结果:
    '          (1)删除成功,返回字符串:OK
    '          (2)删除失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           set ret = RemoveWorksheet(ExcelApp, "Book1", "Sheet1")
    ' *********************************************************************************************

    Function RemoveWorksheet(ExcelApp, workbookIdentifier, worksheetIdentifier)
        Dim workbook 'As Excel.workbook
        Dim worksheet 'As Excel.worksheet
        On Error Resume Next
        Err = 0
        Set workbook = ExcelApp.Workbooks(workbookIdentifier)
        If Err <> 0 Then
            RemoveWorksheet = "Bad Workbook Identifier"
            Exit Function
        End If
        Set worksheet = workbook.Sheets(worksheetIdentifier)
        If Err <> 0 Then
            RemoveWorksheet = "Bad Worksheet Identifier"
            Exit Function
        End If
        worksheet.Delete
        RemoveWorksheet = "OK"
    End Function

    ' *********************************************************************************************
    ' 函数说明:添加新的工作薄
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    ' 返回结果:
    '          (1)成功:工作表对象NewWorkbook
    '          (1)失败:Nothing
    ' 调用方法:
    '          set NewWorkbook = CreateNewWorkbook(ExcelApp)
    ' *********************************************************************************************

    Function CreateNewWorkbook(ExcelApp)
        Set NewWorkbook = ExcelApp.Workbooks.Add()
        Set CreateNewWorkbook = NewWorkbook
    End Function

    ' *********************************************************************************************
    ' 函数说明:打开工作薄
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)path:要打开的工作薄路径;
    ' 返回结果:
    '          (1)成功:工作表对象NewWorkbook
    '          (1)失败:Nothing
    ' 调用方法:
    '          set NewWorkbook = CreateNewWorkbook(ExcelApp)
    ' *********************************************************************************************

    Function OpenWorkbook(ExcelApp, path)
        On Error Resume Next
        Set NewWorkbook = ExcelApp.Workbooks.Open(path)
        Set ōpenWorkbook = NewWorkbook
        On Error GoTo 0
    End Function

    ' *********************************************************************************************
    ' 函数说明:将工作薄设置为当前工作状态
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:要设置为当前工作状态的工作薄名称;
    ' 返回结果:无返回值;
    ' 调用方法:
    '          ActivateWorkbook(ExcelApp, workbook1)
    ' *********************************************************************************************

    Sub ActivateWorkbook(ExcelApp, workbookIdentifier)
        On Error Resume Next
        ExcelApp.Workbooks(workbookIdentifier).Activate
        On Error GoTo 0
    End Sub

    ' *********************************************************************************************
    ' 函数说明:关闭Excel工作薄;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:
    ' 调用方法:
    '           CloseWorkbook(ExcelApp, workbookIdentifier)
    ' *********************************************************************************************

    Sub CloseWorkbook(ExcelApp, workbookIdentifier)
        On Error Resume Next
        ExcelApp.Workbooks(workbookIdentifier).Close
        On Error GoTo 0
    End Sub

    ' *********************************************************************************************
    ' 函数说明:判断两个工作表对应单元格内容是否相等
    ' 参数说明:
    '          (1)sheet1:工作表1的名称;
    '          (2)sheet2:工作表2的名称;
    '          (3)startColumn:开始比较的行序号;
    '          (4)numberOfColumns:要比较的行数;
    '          (5)startRow:开始比较的列序号;
    '          (6)numberOfRows:要比较的列数;
    '          (7)trimed:是否先除去字符串开始的空格和尾部空格后再进行比较,true或flase;
    ' 返回结果:
    '          (1)两工作表对应单元格内容相等:true
    '          (2)两工作表对应单元格内容不相等:flase         
    ' 调用方法:
    '           ret = CompareSheets(excelSheet1, excelSheet2, 1, 10, 1, 10, False)
    ' *********************************************************************************************

    Function CompareSheets(sheet1, sheet2, startColumn, numberOfColumns, startRow, numberOfRows, trimed)
        Dim returnVal 'As Boolean
        returnVal = True

        '判断两个工作表是否都存在,任何一个不存在停止判断,返回flase
        If sheet1 Is Nothing Or sheet2 Is Nothing Then
            CompareSheets = False
            Exit Function
        End If

        '循环判断两个工作表单元格的值是否相等
        For r = startRow to (startRow + (numberOfRows - 1))
            For c = startColumn to (startColumn + (numberOfColumns - 1))
                Value1 = sheet1.Cells(r, c)
                Value2 = sheet2.Cells(r, c)

                '如果trimed为true,去除单元格内容前面和尾部空格
                If trimed Then
                    Value1 = Trim(Value1)
                    Value2 = Trim(Value2)
                End If

                '如果单元格内容不一致,函数返回flase
                If Value1 <> Value2 Then
                    Dim cell 'As Excel.Range
                    '修改sheet2工作表中对应单元格值
                    sheet2.Cells(r, c) = "Compare conflict - Value was '" & Value2 & "', Expected value is '" & Value1 & "'."  
                    '初始化cell为sheet2中r:c单元格对象
                    Set cell = sheet2.Cells(r, c) '
                    '将sheet2工作表中对应单元格的颜色设置为红色
                    cell.Font.Color = vbRed  
                    returnVal = False
                End If
            Next
        Next
        CompareSheets = returnVal
    End Function
  • VBScript编码约定

    2008-2-13

    VBscrīpt编码约定

    编码约定是帮助您使用 Microsoft Visual Basic scrīpting Edition 编写代码的一些建议。编码约定包含以下内容:

    • 对象、变量和过程的命名约定
    • 注释约定
    • 文本格式和缩进指南

    使用一致的编码约定的主要原因是使脚本或脚本集的结构和编码样式标准化,这样代码易于阅读和理解。使用好的编码约定可以使源代码明白、易读、准确,更加直观且与其他语言约定保持一致。

    常数命名约定

    VBscrīpt 的早期版本不允许创建用户自定义常数。如果要使用常数,则常数以变量的方式实现,且全部字母大写以和其他变量区分。常数名中的多个单词用下划线 (_) 分隔。例如:

     USER_LIST_MAX
    NEW_LINE

    这种标识常数的方法依旧可行,但您还可以选择其他方案,用 Const 语句创建真正的常数。这个约定使用大小写混合的格式,并以“con”作为常数名的前缀。例如:

     conYourOwnConstant

    变量命名约定

    为提高易读和一致性,请在 VBscrīpt 代码中使用以下变量命名约定:

    子类型 前缀 示例
    Boolean bln blnFound
    Byte byt bytRasterData
    Date (Time) dtm dtmStart
    Double dbl dblTolerance
    Error err errOrderNum
    Integer int intQuantity
    Long lng lngDistance
    Object obj objCurrent
    Single sng sngAverage
    String str strFirstName

    变量作用域

    变量应定义在尽量小的作用域中。VBscrīpt 变量的作用域如下所示:

    作用域 声明变量处 可见性
    过程级 事件、函数或子过程。 在声明变量的过程中可见。
    scrīpt 级 HTML 页面的 HEAD 部分,任何过程之外。 在脚本的所有过程中可见。

    变量作用域前缀

    随着脚本代码长度的增加,有必要快速区分变量的作用域。在类型前缀前面添加一个单字符前缀可以实现这一点,而不致使变量名过长。

    作用域 前缀 示例
    过程级 dblVelocity
    scrīpt 级 s sblnCalcInProgress

    描述性变量名和过程名

    变量名或过程名的主体应使用大小写混合格式,并且尽量完整地描述其目的。另外,过程名应以动词开始,例如 InitNameArray 或 CloseDialog。

    对于经常使用的或较长的名称,推荐使用标准缩写以使名称保持在适当的长度内。通常多于 32 个字符的变量名会变得难以阅读。使用缩写时,应确保在整个脚本中保持一致。例如,在一个脚本或脚本集中随意切换 Cnt 和 Count 将造成混乱。

    对象命名约定

    下表列出了 VBscrīpt 中可能用到的对象命名约定(推荐):

    对象类型 前缀 示例
    3D 面板 pnl pnlGroup
    动画按钮 ani aniMailBox
    复选框 chk chkReadOnly
    组合框、下拉列表框 cbo cboEnglish
    命令按钮 cmd cmdExit
    公共对话框 dlg dlgFileOpen
    框架 fra fraLanguage
    水平滚动条 hsb hsbVolume
    图像 img imgIcon
    标签 lbl lblHelpMessage
    直线 lin linVertical
    列表框 lst lstPolicyCodes
    旋钮 spn spnPages
    文本框 txt txtLastName
    垂直滚动条 vsb vsbRate
    滑块 sld sldScale

    代码注释约定

    所有过程的开始部分都应有描述其功能的简要注释。这些注释并不描述细节信息(如何实现功能),这是因为细节有时要频繁更改。这样就可以避免不必要的注释维护工作以及错误的注释。细节信息由代码本身及必要的内部注释来描述。

    当传递给过程的参数的用途不明显,或过程对参数的取值范围有要求时,应加以说明。如果过程改变了函数和变量的返回值(特别是通过参数引用来改变),也应在过程的开始部分描述该返回值。

    过程开始部分的注释应包含以下区段标题。相关样例,请参阅后面的“格式化代码”部分。

    区段标题 注释内容
    目的 过程的功能(不是实现功能的方法)。
    假设 其状态影响此过程的外部变量、控件或其他元素的列表。
    效果 过程对每个外部变量、控件或其他元素的影响效果的列表。
    输入 每个目的不明显的参数的解释。每个参数都应占据单独一行并有其内部注释。
    返回 返回值的解释。

    请记住以下几点:

    • 每个重要的变量声明都应有内部注释,描述变量的用途。
    • 应清楚地命名变量、控件和过程,仅在说明复杂细节时需要内部注释。
    • 应在脚本的开始部分包含描述该脚本的概述,列举对象、过程、运算法则、对话框和其他系统从属物。有时一段描述运算法则的假码是很有用的。

    格式化代码

    应尽可能多地保留屏幕空间,但仍允许用代码格式反映逻辑结构和嵌套。以下为几点提示:

    • 标准嵌套块应缩进 4 个空格。
    • 过程的概述注释应缩进 1 个空格。
    • 概述注释后的最高层语句应缩进 4 个空格,每一层嵌套块再缩进 4 个空格。例如:
    '*********************************************************
    ' Purpose: Locates the first occurrence of a specified user
    '          in the UserList array.
    ' Inputs: strUserList(): the list of users to be searched.
    '         strTargetUser: the name of the user to search for.
    ' Returns: The index of the first occurrence of the strTargetUser
    '          in the strUserList array.
    '          If the target user is not found, return -1.
    '*********************************************************
    Function intFindUser (strUserList(), strTargetUser)
       Dim i   ' Loop counter.
       Dim blnFound   ' Target found flag
       intFindUser = -1
       i = 0   ' Initialize loop counter
       Do While i <= Ubound(strUserList) and Not blnFound
          If strUserList(i) = strTargetUser Then
             blnFound = True   ' Set flag to True
             intFindUser = i   ' Set return value to loop count
          End If
          i = i + 1   ' Increment loop counter
       Loop
    End Function
  • qtp 多种函数使用方法

    2008-1-30

    --转载

    1 生产随机数列
    第一种方法
    randomize'更新反回的数据
    funcation rand(k,n)
    n="int((k-1)*rnd+1) rand=n
    end funcation
    第二种方法
    n="randomnumber.value(1,255)

     2  当运行到表中的某一行,自动导出表中的所有数据
    row=datatable.getcurrentrow
    if row="5" then
      datatable.export("d:\data.xml")
    end if

    3 参数化密码
    webedit("txtpass").setsecure"sdsdf...."
    如果参数化密码,可以直接在数据表中写入未加密的密码,它会自动识别,即不用把setsecure改为set

    4 如果弹出对话框就获取上面提示信息并与表中的信息对比,不统一证明弹出的提示出错,主要用来验证
    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)取一部份特征提示信息进行验证,这样我想可以节省处理时间,又可以避免长度以及空格等字符的处理

    5  datatable.value("num")只在global形式下的一种省略形式;完整形式是:
    datatable.value("num",dtlocalsheet)
    -----向某一列的单元格赋值:
    datatable.value("column_name",dtlocalsheet)="nanjing"
    -----取得某一行具体值:
    datatable.setcurrentrow(n)
    msgbox(datatable.getsheet("global").getparameter("column_name").Rawvalue)
    或者kk=datatable.Rawvalue("column_name","action1")
    ----在run-time时,动态添加表格与数据
    kk=datatable.addsheet("sheet_name").addparameter("column_name","value").name;

    7   wintreeview一些操作
    选择一个条目:wintreeview.select(item)'根是0
    根的名称:wintreeview.getitem(0)

    8   数据库检查点模块:
    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;BA

    M=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

    9   换行符
    vbcr----chr(13)回车符// vblf----chr(10)换行符
        vbcrlf----chr(13)+chr(10)结合//type(chr(13)就相当于按了一上键盘上的enter

    10  Run from step有两种方式:
    在Keyword View模式会从本步骤运行到所有action结束
    在expert view模式仅会将本action运行结束

    11  由于对象属性原因,无法识别对象
    -----对于对象属性是变化的,可以参数化/或者用正则表达式
    -----报匹配多个对象错误,可以spy查看对象,添加一个该对象另一个唯一标识属性
    -----有时可以删除对象的变化的属性来解决识别问题
    ------对于多个完全相同的对象,可以采用添加index,location,createtime等特殊属性来识别
      (index:按照程序源码,绘制对象的先后标识对象,所以与其它相同对象是相互依赖,当其它对象发生
      变化后,原先的所有对象index属性要发生变化,开始是0;如index:="0;         location:根据对象的位置进行确定,从上到下,从左到右;
      CreateTime:按照对象被浏览器打开的先后标识对象)
    ------另外换一种思维方式,采取等效的方法;比如用键盘代替鼠标或用操作系统本身特性去解决问题

    12  对系统文件的操作
    -------从系统的文件中获取信息及删除文件
      get_file_infor("c:\she.mpg")
       function get_file_infor(url)
        dim fso,f
        set fso="createobject(""scrīpting.filesystemobject")
        set f="fso.getfile(url)"
        f.name:f.size:f.type:f.datacreated'///获取文件信息
        fso.deletefile(url)'/////删除文件
       end function
    --------获取文件夹里所有文件信息
    get_folder_infor("c:\kai")
    function get_folder_infor(folder)
    dim fso,f,f1,n
    set fso="createobject(""scrīpting,filesystemobject")
    set f="fso.getfolder(folder) set fc="f.files for each f1 in fc
    select case f1.name
    case"kai.mpg","she.mpg","dd.mp3"'//检查文件夹里是否含有这些文件
    end select
    next
    end function

     

    13   等待某个对象出现方法
    y="......waitproperty(""visible",true,10000)

     

    14   防程序中断方法
    On error resume next
    On error goto handle

     

    15  数组的应用:
    name="array(1,2,""aa","bb")
    name(2)="aa"

     

    16  正则表达式应用模板
    进行日期YYYY-MM-DD的格式检查 :
    Function RegExpTest(patrn, strng)
      Dim regEx, Match, Matches      ' Create variable.
      Set regEx = New RegExp         ' Create a regular expression.
      regEx.Pattern = patrn         ' Set pattern.
      regEx.IgnoreCase = True         ' Set case insensitivity.
      regEx.Global = True         ' Set global applicability.
      Set Matches = regEx.Execute(strng)   ' Execute search.
      For Each Match in Matches      ' Iterate Matches collection.
        RetStr = RetStr & "Match found at position "
        RetStr = RetStr & Match.FirstIndex & ". Match Value is '"
        RetStr = RetStr & Match.Value & "'." & vbCRLF
      Next
      RegExpTest = RetStr
    End Function
    date_pattern="^((((19|20)(([02468][048])|([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0[1-9])|(1[0-2]))-((0[1-9])|(1\d)|(2[0-8])))|((((0[13578])|(1[02]))-31)|(((01,3-9])|(1[0-2]))-(29|30)))))$"
    result_message=RegExpTest(date_pattern, inputbox("请你输入要检查的时间:"))'用其它正则表达式更改此处
    Select case result_message
    Case ""
             msgbox("你输入的日期格式与标准不匹配")
    case else  MsgBox(result_message)
    end select

     

    17   返回一个字符串在另一字符串中的位置
    instr(string1,string2)

     

    18   有时回放出现找不到对象时,可能不是由于你的代码问题,而是由于你的操作系统等设置问题;
    举例说明1:
    比如:你录制一个选择磁盘中的文件动作
    会录制为:
    .winlistview("  ").drap 46,99
    .winlistview("  ").draponitem "she.mp3"
    下次录制的时候,如果你的系统文件改为不显示扩展名,下次执行的时候,QTP就找不到she.mp3,只能找到she;
    举例说明2:
    有时由于不同操作系统以及不同的ie,导致有些窗口不能识别,比如在2000下弹出的网页对话框的标题是:
    “web对话框",而在2003上是”网页对话框"

     

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

     

    20 Action之间的参数传递
    例如:在Action1中,有如下代码:
    out_str="This is out_string"
    RunAction "Action2",oneIteration,out_str
    在Acton2中,在其step->Action Properties中的,input参数栏,加入out_str后,
    msgbox(parameter("out_str")),就能正确显示参数了 

     

    21 Wscrīpt.Shell的一些应用
    set WshShell ="CreateObject(""Wscrīpt.Shell")
    WshShell.SendKeys "{ENTER}"     '模拟键盘进行操作
    WshShell.AppActivate "Calculator"             '启动应用程序

     

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

     

    23 FireEvent的使用可以对一个对象进行更复杂的操作
    如:FireEvent("onfocus")   '使一个控件获取焦点
         FireEvent("ondblclick")  '实现双击/也可以在事件设定中针对该对象事件响应  

     

    24 模板的应用
    -----新建一个文本,输入一些新建Action时常包含的信息,然后保存为ActionTemplate.MST文件,
     并复制到QTP/dat目录下;这样每次新建action都会包含固定的信息了;
    例如:
    '-------------------脚本说明---------------
    '产品版本:      __Build(  )
    '测试员:
    '编写日期:
    '测试功能:
    '脚本类型:
    '被测试对象初始状态:
    '进展程度:
    '基本思路:
    '主要功能函数:
    '历史修改:
    '没解决的问题:
    '--------------------脚本内容-------------

     

    25 在对象库中,两个对象有时不能通过更改属性或命名来达到两个对象完全一致的替换;
    在web-mod项目中,我在对象库里添加了一个自动含有index标识属性的对象,然后每次通过SetToproperty来改变
    index值,对对象进行数据驱动,使其操作另一个对象,但脚本始终操作原先index属性值的对象;后来,把该对象
    删除掉,重新添加一个不自动含有index标识属性的该类对象,然后,手工添加,index标识属性,后来脚本能正常工作了,可见两次的对象属性完全一致,但形成方式不一样,导致的结果往往也不一样;

     

    26 childobject的应用
    childobject可以返回界面上满足条件的对象集合,而且与对象库里是否有这些对象无关,这就可以简化对象库;
    返回的对象集合的count方法可以返回对象个数,这就可以通过下标对单个对象进行操作;在出现index标识对象时
    可以进行运用
    如:Set m_WinCheck="Descrīption.Create()       m_WinCheck("nativeclass").Value="Button"
          set All_WinCheck="Window(""").Dialog("").Childobject(m_WinCheck)
          n="All_WinCheck.Count()      for i="0" to n-1
          All_WinCheck(i).Set "ON"
         next

  • qtp数据表的添加、数据导入、数据导出

    2008-1-21

    • 数据表的添加、数据导入、数据导出

      2007-03-29 15:54:26

      测试文件名:datasheet   路径为E:\TestInstance\qtp\ForexampleTest\
      要导入的数据保存在C:\NameTickets.xls 内容为
      name tickets
      aa         1
      bb        2
      cc         3
      在导入数据前E:\TestInstance\qtp\ForexampleTest\datasheet\Default.xls有两个缺省的Sheet 分别为Global Action1均无数据
      运行如下程序:

      DataTable.AddSheet("MySheet")  '在缺省的Default.xls添加一个标单MySheet      
      DataTable.ImportSheet "C:\NameTickets.xls", 1, "MySheet"                                               ' 第二行
      DataTable.ExportSheet "E:\TestInstance\qtp\ForexampleTest\datasheet\Default.xls", 3        ' 第三行
        
      '其中第二行中的1参数 是指从文件“"C:\NameTickets.xls"的第一列开始导入数据到新建的MySheet 中
      '其中第二行中的3参数 是指讲运行过程的数据导出到文件"E:\TestInstance\qtp\ForexampleTest\datasheet\Default.xls"第三个Sheet即新建的MySheet中。
      运行完毕,则在下次打开该测试时就能看见添加了表单MySheet,并且数据已经导入。
      也可以手工打开文件 E:\TestInstance\qtp\ForexampleTest\datasheet\Default.xls来查看。
    • 关于文件的操作

      2007-03-29 11:48:05

      创建文件
      dim fso, f
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      set f = fso.CreateTextFile("C:\test.txt", true) '第二个参数表示目标文件存在时是否覆盖
      f.Write("写入内容")
      f.WriteLine("写入内容并换行")
      f.WriteBlankLines(3) '写入三个空白行(相当于在文本编辑器中按三次回车)
      f.Close()
      set f = nothing
      set fso = nothing

      打开并读文件
      dim fso, f
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      set f = fso.OpenTextFile("C:\test.txt", 1, false) '第二个参数 1 表示只读打开,第三个参数表示目标文件不存在时是否创建
      f.Skip(3) '将当前位置向后移三个字符
      f.SkipLine() '将当前位置移动到下一行的第一个字符,注意:无参数
      response.Write f.Read(3) '从当前位置向后读取三个字符,并将当前位置向后移三个字符
      response.Write f.ReadLine() '从当前位置向后读取直到遇到换行符(不读取换行符),并将当前位置移动到下一行的第一个字符,注意:无参数
      response.Write f.ReadAll() '从当前位置向后读取,直到文件结束,并将当前位置移动到文件的最后
      if f.atEndOfLine then
          response.Write("一行的结尾!")
      end if
      if f.atEndOfStream then
          response.Write("文件的结尾!")
      end if
      f.Close()
      set f = nothing
      set fso = nothing

      打开并写文件
      dim fso, f
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      set f = fso.OpenTextFile("C:\test.txt", 2, false) '第二个参数 2 表示重写,如果是 8 表示追加
      f.Write("写入内容")
      f.WriteLine("写入内容并换行")
      f.WriteBlankLines(3) '写入三个空白行(相当于在文本编辑器中按三次回车)
      f.Close()
      set f = nothing
      set fso = nothing

      判断文件是否存在
      dim fso
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      if fso.FileExists("C:\test.txt") then
          response.Write("目标文件存在")
      else
          response.Write("目标文件不存在")
      end if
      set fso = nothing

      移动文件
      dim fso
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      call fso.MoveFile("C:\test.txt", "D:\test111.txt") '两个参数的文件名部分可以不同
      set fso = nothing

      复制文件
      dim fso
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      call fso.CopyFile("C:\test.txt", "D:\test111.txt") '两个参数的文件名部分可以不同
      set fso = nothing

      删除文件
      dim fso
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      fso.DeleteFile("C:\test.txt")
      set fso = nothing

      创建文件夹
      dim fso
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      fso.CreateFolder("C:\test") '目标文件夹的父文件夹必须存在
      set fso = nothing

      判断文件夹是否存在
      dim fso
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      if fso.FolderExists("C:\Windows") then
          response.Write("目标文件夹存在")
      else
          response.Write("目标文件夹不存在")
      end if
      set fso = nothing

      删除文件夹
      dim fso
      set fso = server.CreateObject("scrīpting.FileSystemObject")
      fso.DeleteFolder("C:\test") '文件夹不必为空
      set fso = nothing
    • 模板的应用

      2007-03-27 15:05:31

      新建一个文本,输入一些新建Action时常包含的信息,然后保存为ActionTemplate.MST文件,
       并复制到QTP/dat目录下;这样每次新建action都会包含固定的信息了;
      例如:
      '-------------------脚本说明---------------
      '产品版本:      __Build(  )
      '测试员:
      '编写日期:
      '测试功能:
      '脚本类型:
      '被测试对象初始状态:
      '进展程度:
      '基本思路:
      '主要功能函数:
      '历史修改:
      '没解决的问题:
      '--------------------脚本内容-------------

      当然了,脚本的说明内容可以随意修改,但必须保存到dat目录下,并且文件的名字为:ActionTemplate.MST

    • Action之间参数传递

      2007-03-27 15:02:45

      Action之间的参数传递
      例如:在Action1中,有如下代码:
      out_str="This is out_string"
      RunAction "Action2",oneIteration,out_str
      在Acton2中,在其step->Action Properties中的,input参数栏,加入out_str后,
      msgbox(parameter("out_str")),就能正确显示参数了 

      按照该方法如下:

      1.加入Action1后,输入:out_str="This is out_string"
      RunAction "Action2",oneIteration,out_str

      2.然后再加入Action2,注意:Action1和Action2是并列关系,

      在其step->Action Properties中的,input参数栏,加入out_str后,

      这是在Action2中输入:msgbox(parameter("out_str"))

      当运行的时候会出现两个msgbox,其中第一个显示内容为:"This is out_string" ;第二个msgbox显示内容为:空;

      当把和Action1并列的那个Action2去掉后就可以出现一个msgbox,其中显示内容为:"This is out_string",

      结论: Action1和Action2为父子关系时,才会出现传递的参数内容。

    • QTP识别和操作对象的原理

      2007-03-26 11:36:49

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


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

      比如操作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只是封装了部分常用的自身接口嘛。
      所以我们在需要时,可以绕过封装接口,直接调用对象的自身接口。
      不过有些自身接口不够稳定,在实践中偶尔会出现问题,但是概率很少。
      封装接口有相应功能的话,就尽量用封装接口吧!


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

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

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

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

      2007-03-26 11:30:40

      应该说TO是仓库文件里定义的仓库对象,RO是被测试软件的实际对象
      QTP要求先在仓库文件里定义仓库对象,里面存有实际对象的特征属性的值,
      运行的时候,QTP会根据仓库对象的特征属性描述,寻找到实际对象,然后操作实际对象。

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

      相关的几个函数有:

      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还支持脚本描述的方法来定义和访问对象,即不需要在仓库里定义,也能访问和操作实际对象

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

      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 检查点

    2008-1-02

    1) 理解检查点

    QuickTest enables you to add checks to your test or component.

    检查点比较指定属性的当前值与期望值,以判断当前的程序(或站点)功能是否正常。

    当你增加了一个检查点以后,在KeyWord模式下会增加一个CheckPoint,在Expert模式下会增加一条CheckPoint语句。在运行测试时,QTP比较CheckPoint的期望值与当前值,如果结果不匹配,则检查点失败,你可以在TestResults窗口中查看到检查点的结果。

    如果你想获取 checkpoint的返回值(一个布尔值,表示检查成功或失败),你必须在专家模式下将checkpoint 参数两端加上括号。如

    a = browser("MyBrowser").page("MyPage").check (checkPoint("MyProperty"))

     

    2) 向测试脚本中添加检查点

    可以在录制脚本的过程中添加,也可以在修改脚本的过程中添加。

    途径:菜单 Insertcheckpoint、或按钮;在Keywork视图中选择一个STEP,然后选右键菜单Insert Standard Checkpoint;在Active Screan中选择任意一个object,然后选右键菜单Insert Standard Checkpoint

     

    3) checkpoint的种类:

    可以在站点或应用程序中插入不同种类的checkpoint

    l         Standard Checkpoint (标准检查点)

    检查程序或网页object的属性值,检查对象如buttons, radio buttons, combo boxes, lists, 等等。

    标准检查点支持所有的add-in 环境 (see Supported Checkpoints).

    l         Image Checkpoint (图像检查点)

    检查程序或网页中图像的值,如你可以检查图像 的源文件是否正确。

    注:你也可以给图片object插入一个标准检查点,这个标准检查点也是图像检查点。

    l         Bitmap Checkpoint(图片检查点)

    将程序或网页的某个区域作为一个图片,建立检查点。如,某个站点可以展示一个城市的地图,这个地图有控制地图缩放的按钮,你点击1次“zoom in”按钮后,录制下放大了的地图快照。通过建立bitmap 检查点,可以检查“zoom in”功能是否正确。

    l         Table Checkpoint(表检查点)

    检查一个表中的信息。例如,假设被测的程序或网站包括一个table,本table中包含了所有的从New YorkSan Fransisco的有效航班。你可以通过Table检查点来检查第1个航班的时间是否正确。

    注意:你也可以通过为表Object插入标准检查点的方法创建表检查点。

    l         Text Checkpoint(文本检查点)

    检查位于程序或网站某个位置的字符串。例如,假设程序或网站显示“Flight departing from New York to San Francisco”的语句,你可以创建一个文本检查点检查"New York" 是否显示于"Flight departing from" "to San Francisco"之间。

    所有的add-in环境都支持文本检查点。

    l         Text Area Checkpoint

    l         Accessibility Checkpoint

    l         Page Checkpoint

    l         Database Checkpoint

    检查database的内容。例如,可以使用数据库检查点来检查包含航班信息的数据库的内容。

    所有环境都支持数据库检查点。

    l         XML Checkpoint

    l         下表是QTP中在不同环境下对各类检查点的支持情况。

     

    Web

    Std

    VB

    ActiveX

    Other Object

    Standard

    S

    S

    S

    S

    NA

    Image

    S

    NS

    NS

    NS

    NA

    Table

    S

    NS

    NS

    S

    NA

    Text

    S

    S

    S

    S

    NA

    Text Area

    NS

    S

    S

    S

    NA

    Bitmap

    S

    S

    S

    S

    NA

    Accessibility

    S

    NS

    NS

    NS

    NA

    XML

    S

    NS

    NS

    NS

    S (File)

    Page

    S

    NA

    NA

    NA

    NA

    Database

    NA

    NA

    NA

    NA

    S (DbTable)

    S—Supported

    NS—Not Supported

    NA—Not Applicable