发布新日志

  • 函数

    2007-09-14 11:04:11

    再贴一个,这是我自己写的.....
    Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

    '向目标计算机发送消息
    '例如:sendmsg "rsgui","test complete!"
    Declare Function SendMsg(computer as string,txt as string)
    Function SendMsg(computer as string,txt as string)
    dim operate as string
    operate="/c net send " & computer & " " & txt
    shellexecute 0,"open","cmd.exe",operate,"c:\",0
    End Function
     
     
     
     
     
    '得到控件的属性,并保留到文件中
    function SaveAllPropertyValues (ObjectRec As String, Filename As String)
    Dim Result As Integer
    Dim Properties() As String
    Dim Value As Variant
    Dim n As Integer
    Open Filename For Output As #1
    Result = SQAGetPropertyNames(ObjectRec, Properties)
    If Result <> sqaSuccess Then
    SQALogMessage sqaWarning, "Unable to capture """ + ObjectRec + """ properties", "Error" + Str$(Result) + ": " + Error$(Result)
    Exit function
    End If
    For n = 0 to UBound(Properties)
    Result = SQAGetPropertyAsString(ObjectRec, Properties(n), Value)
    If Result = sqaSuccess Then
    Write #1, Properties(n), Value
    End If
        Next n
        Close #1
    SQALogMessage sqaNone, "Properties of " + ObjectRec + " saved in " + Filename, ""
    End function
     
     
     
     
     
     
     
    我不觉得,楼主 所写的 获得控件属性值 ,并写入文件 有什么太大用处,就我个人使用而言, 我觉得,大家 多用用
    SQAgetPropertyValue 和 SQAWaitforPropertyValue ,SQAlogMessage以及 Msgbox这几个常用函数就构了, 第一个函数,我们常用来获取一些对象 某个属性值,用它进行判断,或者于预期值进行比较.

    我们不需要得到控件的所有属性值,事实上,某些没有太大的用处,所以用第一个函数,就构了.

    第二个函数,主要用来判断某个对象(控件)存不存在,或者说在指定时间内存在时,作者希望 作些什么其它操作.

    第三个函数,常用来,将作者认为 有必要的信息,写进 结果日志里.(当一个脚本很长的时候,通常可以判断脚本执行到何处)

    最后一个函数, 常用来调试脚本,当对脚本进行参数化后,希望运行时得到某些参数值的时候,经常用到.

     
     
     
     
     
  • Rational Robot SQABasic数据库操作相关命令 13

    2007-09-14 10:07:22

    Rational Robot SQABasic数据库操作相关命令  


    SQLClose 功能函数
    断开由SQLOpen确定的与ODBC数据源连接。
    SQLClose ( connection& )
    语法: 参数 解释
    connection& 由SQLOpen返回的一个长整型的名称参数。
    注解:
    返回的是一个变量。成功返回0并连接随后关闭或断开。如果连接不正常,返回-1。

    This example opens the data source named "SblTest," gets the names in the ODBC data sources, and closes the connection.
    Sub main
    ' Declarations
    '
    Dim outputStr As String
    Dim connection As Long
    Dim prompt As Integer
    Dim datasources(1 To 50) As Variant
    Dim retcode As Variant
    Dim action1 as Integer
    Dim qualifier as String

    prompt = 5
    ' Open the datasource "SblTest"
    connection = SQLOpen("DSN=SblTest", outputStr, prompt:=5)

    action1 = 1 ' Get the names of the ODBC datasources
    retcode = SQLGetSchema(connection:=connection,action:=1, qualifier:=qualifier, ref:=datasources())
    ' Close the datasource connection
    retcode = SQLClose(connection)

    End Sub

    SQLError功能函数
    可以用来接收做ODBC函数调用时发生的多条错误的详细信息。为最近ODBC函数调用和连接返回错误信息。
    SQLError ( destination() )
    语法: 参数 解释
    destination() 两维数组的每行包含一个错误。名称参数是必要的,必须是变量的数组。

    注解
    没有返回值。域: 1) 表示ODBC错误类型/下级分类的字符串, 2)表示数据源错误编码的数字值, 3)表示错误的文本信息。

    如果没有错误从先前的ODBC函数调用发生,则0被返回到调用者数组的(1,1)里。如果数组不是2维的或不支持上面提到的三个域,则一个错误信息被返回到调用者数组的(1,1)里。

    SQLError Example
    This example forces an error to test SQLError function.
    sub main
    ' Declarations
    Dim connection As long
    Dim prompt as integer
    Dim retcode as long
    Dim errors(1 To 3, 1 To 10) as Variant
    Dim outputStr as String
    ' Open the datasource
    connection = SQLOpen("DSN=SBLTESTW;UID=DBA;PWD=SQL",outputStr,prompt:=3)
    ' force an error to test SQLError select a nonexistent table
    retcode = SQLExecQuery(connection:=connection,query:="select * from notable ")
    ' Retrieve the detailed error message information into the errors array
    SQLError destination:=errors
    retcode = SQLClose(connection)
    end sub


    SQLExecQuery Function
    在SQLOpen确定的连接上执行一个SQL语句。
    SQLExecQuery ( connection& , query$ )
    语法: 参数 解释
    connection& 指定参数、必须。长整形、由SQLOpen返回。
    query$ 包含一个有效SQL语句的字符串,返回值是个变量。
    注解:
    对于SQL SELECT返回结果集的栏数目;对于UPDATE, INSERT, 或 DELETE返回受语句作用的行的数目。任何其它SQL语句返回0。如果函数在指定数据源不能执行此查询,或如果连接不可用,则返回为负的错误编码。

    如果SQLExecQuery被调用但连接上还有一些未处理结果,则这些等待结果被新的结果所代替。

    SQLExecQuery Example
    This example performs a query on the data source.
    Sub main
    ' Declarations
    '
    Dim connection As Long
    Dim destination(1 To 50, 1 To 125) As Variant
    Dim retcode As long
    Dim outputStr as String
    Dim query as String
    ' open the connection
    connection = SQLOpen("DSN=SblTest",outputStr,prompt:=3)
    '
    ' Execute the query
    query = "select * from customer"
    retcode = SQLExecQuery(connection,query)
    '
    ' retrieve the first 50 rows with the first 6 columns of each row into
    ' the array destination, omit row numbers and put column names in the
    ' first row of the array
    '
    retcode = SQLRetrieve(connection:=connection,destination:=destination,columnNames:=1,rowNumbers:=0,maxRows:=50, maxColumns:=6,fetchFirst:=0)

    ' Get the next 50 rows of from the result set
    retcode = SQLRetrieve(connection:=connection,destination:=destination,columnNames:=1,rowNumbers:=0,maxRows:=50, maxColumns:=6)
    ' Close the connection
    retcode = SQLClose(connection)
    End Sub


    SQLGetSchema功能函数
    返回各类信息,包括数据源可用的信息,当前用户ID、表格名称、表格列的名称和类型、及其它数据源/数据库相关信息。
    SQLGetSchema (connection& , action% , qualifier$ , ref() )
    语法: 参数 解释
    connection& 由SQLOpen返回的一个长整形。
    action% 必需项。
    qualifier$ 必需项。
    ref() 动作请求的对应的结果的变量数组,必须有一个数组即使仅一个参数的一维数组。返回值是一个变量。

    注解:
    返回一个负数表示一个错误。如果请求信息不能被访问或连接不能用,将返回-1。目标数组必须适当地定制以支持动作或错误返回。动作2和3不是普遍被支持的。动作4返回所有表格并不支持权限使用。不是所有数据库产品和ODBC驱动支持所有动作。
    动作对应解释表:
    动作 具体注释说明
    1 现有可用数据源列表(dimension of ref() is one)
    2 当前连接上的数据库列表(不支持)
    3 当前连接上数据库的所有者列表(不支持)
    4 指定连接上的表格列表
    5 由合法用户指定表格的栏列的列表(ref() 必须2维)。返回列栏名称和SQL数据类型。
    6 当前连接使用者的用户ID
    7 当前数据库的名称
    8 当前连接的数据源的名称。
    9 数据源使用的DBMS的名称(例如Oracle)。
    10 数据源的服务器名称
    11 数据源表示拥有者的术语
    12 数据源表示表格的术语
    13 数据源表示合法用户的术语
    14 数据源表示过程的术语


    SQLGetSchema Example
    This example opens the data source named "SblTest," gets the names in the ODBC data sources, and closes the connection.
    Sub main
    ' Declarations
    '
    Dim outputStr As String
    Dim connection As Long
    Dim prompt As Integer
    Dim datasources(1 To 50) As Variant
    Dim retcode As Variant
    Dim action1 as Integer
    Dim qualifier as String

    prompt = 5
    ' Open the datasource "SblTest"
    connection = SQLOpen("DSN=SblTest", outputStr, prompt:=5)

    action1 = 1 ' Get the names of the ODBC datasources
    retcode = SQLGetSchema(connection:=connection,action:=1, qualifier:=qualifier, ref:=datasources())
    ' Close the datasource connection
    retcode = SQLClose(connection)

    End Sub

    SQLOpen 功能函数
    建立一个到在connectStr里指定的ODBC数据源的连接并返回一个连接ID,并将完全的连接字符串赋予outputStr变量。如果连接不可用,返回ODBC错误的负数。
    SQLOpen ( connectStr$ [ , outputStr$] [ , prompt%] )
    语法: 参数 解释
    connectStr$ 指定参数,必须参数。
    outputStr$ 可选
    prompt% 可选。Prompt指定何时驱动对话框出现。可选项:
    1 对话框永远出现
    2 说明不够充分以建立连接时打开驱动对话框
    3 同2,对话框内容为灰色,不能修改
    4 对话框不出现,连接不成功,则返回一个错误
    注解:
    关于connectStr的内容描述在ODBC微软程序员参考手册。典型字符串形式为"DSN=datasourcename; UID=myid; PWD=mypassword"。返回长型long型。
    当prompt缺省时,SQLOpen使用2作为默认值。

    SQLOpen Example
    This example opens the data source named "SblTest," gets the names in the ODBC data sources, and closes the connection.
    Sub main
    ' Declarations
    '
    Dim outputStr As String
    Dim connection As Long
    Dim prompt As Integer
    Dim datasources(1 To 50) As Variant
    Dim retcode As Variant
    Dim action1 as Integer
    Dim qualifier as String

    prompt = 5
    ' Open the datasource "SblTest"
    connection = SQLOpen("DSN=SblTest", outputStr, prompt:=5)

    action1 = 1 ' Get the names of the ODBC datasources
    retcode = SQLGetSchema(connection:=connection,action:=1, qualifier:=qualifier, ref:=datasources())
    ' Close the datasource connection
    retcode = SQLClose(connection)

    End Sub


    SQLRequest功能函数
    建立一个由connectionStr指定数据源的连接,执行包含在query内的SQL语句,返回请求的结果到ref()数组里,并关闭连接。
    SQLRequest( connectionStr$ , query$ , outputStr$ , prompt% , columnNames% , ref() )
    语法: 参数 解释
    connectionStr$ 必需项。
    query$ 必需项
    outputStr$ 包含完整连接字符串。
    prompt% Prompt指定何时驱动对话框出现。一个整数。(查看SQLOpen).
    columnNames% 0或非0的一个整数。当columnNames为非0,栏列名称作为ref()数组的第一行被返回。如果columnNames缺省,默认值为0。
    ref() 必需项,2维变量数组。
    注解:
    在连接不能被建立、查询不能用、或其它错误的情况下,返回一个负数。在请求成功情况下返回正数或受影响的行数。其它SQL语句返回0。
    参数是必需的参数。结果为变量。

    SQLRequest Example
    This example will open the datasource SBLTESTW and execute the query specified by query and return the results in destination
    Sub main
    ' Declarations
    '
    Dim destination(1 To 50, 1 To 125) As Variant
    Dim prompt As integer
    Dim retcode as Variant
    Dim query as String
    Dim outputStr as String

    ' The following will open the datasource SBLTESTW and execute the query
    ' specified by query and return the results in destination
    '
    query = "select * from class"
    retcode = SQLRequest("DSN=SBLTESTW;UID=DBA;PWD=SQL",query,outputStr,prompt,0,destination())
    End Sub

    SQLRetrieve 功能函数
    在由connection指定的连接上获取待定查询结果并将结果返回到destination()数组里。
    SQLRetrieve( connection& , destination() , maxColumns% , maxRows% , columnNames% , rowNumbers% , fetchFirst% )
    语法:
    参 数 解 释
    connection& 长型long
    destination() 2维变量数组
    maxColumns% 整形,可选参数,用来指定在查询中取回的栏列数目
    maxRows% 整形,可选参数,用来指定在查询中取回的行的数目
    columnNames% 整形,可选参数,默认为0
    rowNumbers% 整形,可选参数,默认为0
    fetchFirst% 整形,可选参数,默认为0
    注解:
    返回值是结果集的行的数目或请求的最大行。如果函数不能在指定连接上获得结果,返回-1。如果没有发现数据,函数返回0。
    参数是必需参数。返回变量。
    如果maxColumns或maxRows被缺省,数组大小被用来确定获得的行列的最大数目,并返回整个结果集是一个尝试。通过再次使用SQLRetrieve和把fetchFirst设置为0,额外行可以被获得。如果maxColumns指定比结果中可用的更少的列,SQLRetrieve抛弃右边结果列只到结果与指定大小相适合。
    当columnNames是非0,数组的第1行将放置数据库计划(database schema)指定的列名称。 当 rowNumbers是非0,行数目返回到destination()的第1列。SQLRetrieve将清空用户的数组来获得结果。
    当fetchFirst 是非0,它将结果重新配置到第一行,前提是如果数据库支持此功能。如果数据库不支持此功能,结果设置 –1错误被返回。
    如果结果集有比可以被destination()数组包含还多的行或比用maxRows请求还多的行,用户可以重复调用SQLRetrieve只到返回值为0为止。

    SQLRetrieve Example
    This example retrieves information from a data source.
    Sub main
    ' Declarations
    '
    Dim connection As Long
    Dim destination(1 To 50, 1 To 125) As Variant
    Dim retcode As long
    Dim query as String
    Dim outputStr as String
    connection = SQLOpen("DSN=SblTest",outputStr,prompt:=3)
    '
    ' Execute the query
    query = "select * from customer"
    retcode = SQLExecQuery(connection,query)

    ' retrieve the first 50 rows with the first 6 columns of each row into
    ' the array destination, omit row numbers and put column names in the
    ' first row of the array

    retcode = SQLRetrieve(connection:=connection,destination:=destination, columnNames:=1,rowNumbers:=0,maxRows:=50, maxColumns:=6,fetchFirst:=0)

    ' Get the next 50 rows of from the result set
    retcode = SQLRetrieve(connection:=connection,destination:=destination,columnNames:=1,rowNumbers:=0,maxRows:=50, maxColumns:=6)
    ' Close the connection
    retcode = SQLClose(connection)
    End Sub


    SQLRetrieveToFile 功能函数
    在connection指定的连接上获取待定查询结果并存储到destination指定的文件。
    SQLRetrieveToFile( connection& , destination$ , columnNames% , columnDelimiter$ )
    语法: 参数 解释
    connection& 必需项,long
    destination$ 必需项,包含用来存储结果的文件和路径的字符串。
    columnNames% 整型,非0时,文件首行将存储数据库计划指定的栏列名称。如果缺省,默认为0。
    columnDelimiter$ 每行内界定域用的字符串。如果缺省,tab键用来分隔域。
    注解:
    成功完成操作情况下,返回值是结果集的行数目。如果函数不能在指定连接上获得结果,返回-1。
    参数是必需参数。返回变量。

    SQLRetrieveToFile Example
    This example opens a connection to a data source and retrieves information to a file.
    Sub main
    ' Declarations
    '
    Dim connection As Long
    Dim destination As String
    Dim retcode As Long
    Dim query as String
    Dim outputStr as String
    Dim filename as String
    Dim columnDelimiter as String
    '
    ' Open the connection
    connection = SQLOpen("DSN=SblTest",outputStr,prompt:=3)
    ' Execute the query
    '
    query = "select * from customer"
    retcode = SQLExecQuery(connection,query)
    ' Place the results of the previous query in the file named by
    ' filename and put the column names in the file as the first row.
    ' The field delimiter is %
    '
    filename = "c:\myfile.txt"
    columnDelimiter = "%"
    retcode = SQLRetrieveToFile(connection:=connection,destination:=filename, columnNames:=1,columnDelimiter:=columnDelimiter)

    retcode = SQLClose(connection)
    End Sub

  • Rational Robot如何测试12

    2007-09-14 10:06:03

    Rational Robot如何测试帮助c++程序员识别自定义或则第三方控件

    大家都知道Rational Robot利用Delphi Enabler支持识别Delphi第三方控件和自定义控件,但是识别C++程序中遇到的第三方控件呢?我将在下边介绍识别他的方法,希望对大家有所帮助。

    SQA Object Testing Control

    如果你测试软件是vb编写的,那么利用SQA Object Testing Control: (SQAOTE32.ocx)来获得控件信息很对你来说很熟悉,通过它可以获取到软件运行时候的控件信息和方法。Robot可以根据提供的信息建立强壮的脚本,验证那些方法或功能是否正确,也就是最后的验证点。
    如果你的c或则c++程序中包含自定义或者第三方的ActiveX(ocx)控件,你可以同样把这个控件放到每一个包含第三方控件或者用到自定义控件的窗体上。
    安装Rational TeamTest或者Robot,Object Testing Control (SQAOTE32.ocx)会默认安装到系统目录system32中:C:\WINNT\system32\sqaote32.ocx.。

    添加Rational ActiveX Test Control

      如果想让ActiveX Test Control起作用,需要在VC中设置ActiveX可用。以下用MFC举例
    第一.        建立工程,设置ActiveX控件可用
          
    第二.        在有第三方控件的地方添加Rational ActiveX Test Control
    有一个窗体中包含MSTreeView,运行Rational Robot利用object properties来抓取MSTreeView属性,Rational Robot无法识别该对象(对象为UNKNOW)。添加SQA Object Testing Control(右键插入ActiveX控件,出现下图窗体)。

    添加Rational ActiveX Test Control后窗体上出现一个robot的图标,你不用在代码中做任何处理就可以使用他。SQA Object Testing Control是个不可见控件,运行软件后他不会显示在窗体上。

         
          
    再没有添加SQA Object Testing Control的时候Robot只能识别这个控件的通用属性,添加后Robot可以识别自定义控件或者插件的大部分属性。


    注意
    如果用到得自定义控件继承自MFC或者用APIS实现,即使添加SQA Object Testing Control控件Robot也无法有效的工作。那么定义该对象继承相近的类别。
    方法1:运行的时候当用Object properties识别对象为unknow的时候,在出现的对话框中定义无法识别控件到相近的基类中。
    方法2:打开robot,Tools->General Options,切换到object mapping页面。选择基类,然后添加无法是别的控件到该类中。
    这样做可以识别该控件的通用类别属性。

    总结:针对无法识别自定义和第三方控件建议添加Rational ActiveX Test Control,通过他能使Robot识别对象的大多数属性,帮助Robot建立强壮的脚本。
  • 数据池(DATAPOOL)应用技巧11

    2007-09-14 10:05:21

    数据池(DATAPOOL)应用技巧――如何生成定制数据

    数据池可以按一定的规则生成测试数据列,但是它不能直接生成定制的数据。下面介绍使用数据池生成定制数据的一种方法:

        测试数据要求:数据由用户和产品数据组成,依次为用户名、用户密码、产品ID、产品价格。用户名和用户密码一一对应,产品ID和产品价格一一对应。要求用户数据和产品数据随机组合,生成大量测试数据。
    数据生成过程:
    1、从数据库中用Select语句分别从用户表和产品表中检索出用户数据和产品数据,检索结果分别存为CSV文件,文件名为user.csv和product.csv;

    2、在Testmanager中新建DATAPOOL,命名为testdata,插入两个字段,TYPE选择“Read from File”,分别选择上一步生成的CSV文件,Sequense按需要选择;

    3、按“Generate Data”按钮生成数据,close关闭窗口;

    4、“Edit Datapool Data”查看生成的数据,可以看到只有两列数据,关闭窗口;

    5、Manage Datapools窗口上点击“Import”按钮,选择测试项目目录中的..\TestDatastore\DefaultTestscrīptDatastore\TMS_Datapools\ testdata.csv(上一步生成的数据池的CSV文件),输入新的DATAPOOL名afterdata,按“确定”按钮;

    6、打开afterdata查看生成的数据,数据为4列,数据成功生成。

  • 用Excel做Datapool10

    2007-09-14 10:04:49

    用Excel做Datapool实现Rational Robot 功能测试的一个实例
    Rational Robot是一个比较通用的软件测试工具。她主要通过录制(自动或手工)脚本用于功能测试和性能测试。

    在手工修改Robot录制的GUI脚本时,经常用到Datapool这一概念,由于Rational自带的Datapool工具只能支持2000行的数据池纪录,而且编辑不是很方便。现用比较方便的Excel作为数据源,实现自动测试的功能。

    前提条件:OS系统中已经安装Office。

    [源码]

    '$include "sqautil.sbh"
    Sub Main
        Dim Result As Integer
        dim excel as Object
        dim book as Object
        dim worksheet as Object
        dim s_name as String
        dim s_pass as String
        dim count as Integer

        'Initially Recorded: 2004-4-2  :16:55
        'scrīpt Name: AUT_1_Login
       
        Window SetContext, "Caption=Program Manager", ""
        StartBrowser "C:\Program Files\Internet Explorer\IEXPLORE.EXE", "WindowTag=WEBBrowser"
       
       
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        'Initiliaze excel
        on error resume next
        Set excel = GetObject(,"excel.application")
        if(excel Is Nothing) then
            Set excel = CreateObject("excel.application")
            if(excel Is Nothing) then
                MsgBox "Couldn't find Excel!"
                Exit Sub
            End if
        End if
       
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

        Set book = excel.Workbooks.Open("Your Book1.xls")
        Set worksheet = book.Worksheets("Your Excel sheet's name")
            
        For count=1 To 2
        s_name = worksheet.Cells(1,count).value
        s_pass = worksheet.Cells(2,count).value
        'print s_name,s_pass
       
        Window SetContext, "Caption=Web应用系统 - Microsoft Internet Explorer", ""
        Browser SetFrame,"Type=HTMLFrame;HTMLId=mainframe",""
        Browser NewPage,"HTMLTitle=Title",""
        EditBox Click, "Type=EditBox;Name=userAccount", "Coords=26,10"
        InputKeys s_name &"{TAB}"&s_pass
        PushButton Click, "Type=PushButton;HTMLText=登录"
       
        Window SetTestContext, "Caption=Web应用系统 - Microsoft Internet Explorer", ""
        Browser SetFrame,"Type=HTMLFrame;HTMLId=mainframe",""
       
        Window SetTestContext, "Caption=Microsoft Internet Explorer", ""
        Result = LabelVP (CompareProperties, "Text=输入错误,请重新输入!", "VP=Object Properties;ExpectedResult=FAIL")
        Window ResetTestContext, "", ""
          
        Next count

        'Quit Excel'''''''''''''''''''''
        excel.Quit
        Set excel = Nothing
       
        Window CloseWin, "", ""
       
    End Sub
  • 二)写文件9

    2007-09-14 10:04:02

    二)写文件
      1、 顺序文件
      写顺序文件我们可以用Write # 和Print #语句向一个已经打开的文件中写入数据.
      下面是他们的格式和说明:

      Print # 的语法格式:

      Print # 文件号,变量列表

      例如,将文本框中的文本写到文件中,代码如下:

    Open "file.txt" For Output As #filenum

    Input #filenum, text1.text

      Write # 语句的语法格式:

    Write # 文件号,变量列表

      说明:用Write # 语句写入的信息便于以后用Input #语句来读取数据,因为Write #语句自动将写入到文件中的信息用逗号分开,并为字符串数据加上双引号.例如:

    Open "student.txt" For Output As #filenum

    Write #filenum, "张三", "初一年级", 14
    Write #filenum, "李四", "职业高中", 18

      2、 随机文件

      向随机文件中写入数据,使用Put #语句.语法格式如下:

    Put [#] FileNum ,[RecNum],UserType

      说明:

      (1) FileNum 是要打开的文件号;RecNum是要写入的记录号,若省略,则再上一次用Get 和Put语句所读写过的记录的后一条记录中写入,如果没有执行过Get 和Put语句,就从第一条记录开始

      (2)UserType 是包含要写入数据的用户自定义的数据类型变量.例如:我们向前面的student.txt文件中的第5个记录写入数据,可用这些语句:

    stud.No = 0301
    stud.Name = “王武”
    stud.Age =20
    Put #1 ,5,stud

      如果要插入的数据不只一两条的话,首先要确定文件和每条记录的长度,这样就可以计算出文件中究竟有多少条记录.我们可以用Lof()函数返回文件的长度,Len()函数返回每个记录的长度,计算文件中的记录个数可以用文件的长度除以给个记录的长度.示例如下:

    Nextrec= (Lof(1)\Len(UserType))+1

    Put #1,Nextrec,UserType

      3、二进制文件

      下面是以二进制方式写入文件的语句格式及其说明:

      格式:

    Put [#]fileNumber ,[Pos], Var

      功能: 用二进制方式,从文件的中指定的位置开始写入,所给变量长度的数据

      说明:

      (1)FileNumber是以二进制方式打开的文件号.

      (2)Pos用来指定写操作发生时的字节位置,若省略,则使用当前文件指针位置.

      (3)Var是用来存放写入的数据的变量.该语句会自动根据var变量包含的字节长度写入文件,如果Var是一个可变长度的字符串变量,则传送的字节数等于Var中目前的字节数.

      使用方法可参考二进制文件的读操作.
  • Rational Robot8

    2007-09-14 10:03:05

    Rational Robot中提供了一个文件操作命令,语法如下:
    Open filename$ [For mode] [Access access] [lock] As [#] filenumber% [Len = reclen]
    这里我们把它的语法分为两部分,因为这个文件操作命令有两种文件操作模式,一种是顺序文件,一种是随机文件。

    下边是对顺序文件操作的语法:
    Open filename$ [??For [Input |Output |Append] As [#]filenumber [Len = buffersize]
    参数说明:
    说明:

      (1)参数filename$表示要打开的文件名,文件名可以包含有驱动器和目录

      (2)Input Output 和Append用于设置顺序文件的打开方式。其中,Input表示从打开的文件中读取数据。以这种方式打开文件时,文件必须存在,否则会产生错误。Output表示向打开的文件中写入数据。以这种方式打开文件时,文件中原有的数据将被覆盖,新的数据将从文件开始写入。如果文件不存在,则创建一个新文件。Append表示向打开的文件中添加数据。以这种方式打开时,文件中原有的数据将被保留,新的数据将从文件为开始添加。如果文件不存在,则创建一个新文件。

      (3)As[#]filenumber 子句用于为打开的文件指定文件号.对文件进行读写操作时,要用文件号表示该文件.文件号是介于1~511之间的整数,既可以是数字,又可以是变量.也可以省略不用.

      (4)当在文件与程序之间拷贝数据时,Len=buffersize子句指定缓冲区的字符数.

    例子:
    Open “c:\test.dat" For Output As 1
    Open “c:\test.dat" For Output As 1
      这两句代码在c盘所在目录下创建了一个名为test.dat的文本文件,分配文件号为1.
    Open “c:\test.dat"??For Input As [#]filenumber  这条语句是从文本文件中读取数据.
    Open App.Path + "\test.dat" For Append As [#]filenumber?? 这条语句则是向文本文件中添加数据
    随机文件的操作:
      操作随机文件之前,首先必须定义用于保存数据项的记录类型.该记录是用户自定义数据类型,他们是随机文件中存储数据的基本结构.例如:

    Type Student
     No As Integer
     Name As String * 20
     age As Integer
    End Type

    Dim Stud As Student ‘定义一个可以存放学生材料的变量
      随机文件中,所有的数据都将保存到若干个结构为Student类型的记录中, 而从随机文件中读出的数据则可以存放到变量Stud中.之后我们就可以打开并读写文件了.

    随机文件的操作语法格式:
    Open filename For Random as [#]filenumber Len = Reclength
      说明:
      (1)参数filename 和filenumber 分别表示文件名或文件号.
      (2)关键字Random 表示打开的是随机文件
      (3)Len子句用于设置记录长度,长度由参数Reclength指定.Reclength的值必须大于0,而且必须与定义的记录结构的长度一致.计算记录长度的方法是将记录结构中每个元素的长度相加.例如前面声明的Student的长度应该是2+20+2=24字节.
    打开一个记录类型为Student 的随机文件的方法是:
    Open "c:\Student.txt " For Random As #1 Len = 25

    这里还有一种文件操作方式二进制文件,下边是他的语法格式:
    Open pathname For Binary As [#]filenumber
      说明:
      (1) 参数filename 和filenumber 分别表示文件名或文件号.
      (2)关键字Binary 表示打开的是二进制文件
      (3)对于二进制文件,不能指定字节长度.每个打开的二进制文件都有一个自己的指针,文件指针是一个数字值,指向下一次读写操作的文件中的位置.二进制文件中的每个”位置”对应一个数据字节,因此,有n个字节的文件,就有1到n个位置.

      我们可以用Seek()函数返回当前的文件指针位置(即下一个要读写的字节 );用Loc()函数返回上一次读写的字节位置,除非用Seek语句移动了指针,Loc()返回值总比Seek()的小1.我们来看下面的例子:
    Open “路径:\student.txt” for Binary as #1? ? 该语句用二进制的方式打开了student.txt文件.
  • SQABasic头文件7

    2007-09-14 10:02:11

    SQABasic头文件包含一系列的声明,头文件可以应用到

    一.声明共有或则全局常量,变量和用户定义类型

    二.声明自定义sub,procedures和function

    头文件中的声明可以应用到任何模块(脚本或者类库文件)。用’$include关键字,放在模块开始的地方-例如:

         ’$include “global.sbh”

    SQABasic头文件类型

    Sqabasic支持两种头文件类型:

    一. 头文件保存在sqabasic路径。不用指定任何路径信息就可以在本工程或者其他工程中应用他们

    二. 工程头文件可以保存在TMS_scrīpt文件夹中。不用指定任何路径信息就可以在同一个工程中处理。

    这两种SQABasic头文件都有同样的扩展名- .sbh

    库文件


    库文件包含一个或者更多供procedure从其它文件调用的sub,procedure和function。

    一.SQABasic库文件(扩展名为.sbl或则.rec)

    注意,.rec文件可以作为脚本文件或者库文件,但是.sbl只能被用作库文件。

    二.动态连接库文件(扩展名.dll)

    下边的表格这几种类库文件不同的总结:


    .sbl
    .rec
    .dll

    位置
    SQABasic路径
    当前工程文件中Datastore(文件夹 TMS_scrīpt)
    TMS_scrīpt/dll文家夹或则其他位置

    范围
    在SQABasic路径中,对所有工程文件都可用
    对同一个工程所有脚本可用
    依靠位置

    验证点
    不支持
    支持标准的robot验证点
    支持自定义验证点


    任何.rec文件都能作为库文件。不管怎样,如果一个.rec文件作为脚本(可以从robot中直接运行或者用callscrīpt命令),他必须有一个main过程。

    在SQABasic库文件中声明过程


    如果在SQABasic过程中有一个自定义的过程,你声明类文件的方法同样适用声明过程。

    下边的例子是在sqabasic库文件中(mylib.sbl)声明一个自定义过程(mysub):

         Declare Sub MySub Basiclib “MyLib”( arg1 as string,arg2 as integer)

    一.关键字basiclib,表示过程mysub在一个sqabasic库文件中

    二.库文件的名字“mylib”,这里不需要写扩展名(.sbl或者.rec)

    备注:basiclib关键字特指.sbx库文件的声明(和.dll库文件相对),这里不需要也不推荐带有.sbx扩展名的声明。


    什么地方声明SQABasic库文件

    可以在任何位置声明SQABasic库文件

    一.在脚本或者其他库文件,仅在模块中应用过程

    二.头文件中,用道的模块

    库文件包含不需要指定的例程或者’include头文件

    在dll文件声明过程文件


    如果在dll文件的自定义过程,声明过程同样可以声明dll文件。

    下边是dll文件中(mydll.dll)声明自定义过程(mysub)的例子:

           declare sub mysub lib “mydll”(byval arg1 as string,Byval arg2 as integer)

    一.声明中加入Lib关键字,表示声明的过程在dll文件中(相对于.sbl或者.rec sqabasic库文件)

    二.库文件名字(mydll),跟随库指定的名称

    三.参数声明通常包括关键字byval(参数声明包括任何关键字)


    如果编译位置在sqabas32路径或在系统路径的库文件(.dll),你不用特别声明路径。如果库文件不再sqabas32或者在系统路径,你需要制定路径,比如

           Declare Sub MySub Lib “E:MyDll”  (byval arg1 as string,Byval arg2 as integer)

    在什么地方声明dll文件


    你可以声在任何为指声明dll文件:

    1.         脚本或者sqabasic库文件,要用过程的模块

    2.         头文件,任何模块指定的头文件

    SQABasic路径


    Sqabasic路径是robot保存和寻找sbl库文件和头文件的地方,用户在robot中也可以定义。

    一旦你在robot中指定sqabasic路径,这个路径是固定的。不管怎样,robot自动设置sqabasic路径,当下列条件是真的时候:

               i.              仍没有明确在robot中定义sqabasic

             ii.              已经在rational Aministrator建立新的工程和数据仓库

            iii.              打开最近创建的工程和数据仓库

    当上边所有条件为真的时候,robot自动在新工程和数据仓库中设置sqabasic路径到下列位置:

    [NewProject][NewDatastore]DefaultTestscrīptDatastoreTMS_scrīptSQABas32

    设置步骤:

    1)        点Tools->General Options

    2)        点Preferences页面

    3)        在SQABasic路径中输入路径

    Rational test早期版本没有提供菜单选项来设置sqabasic路径 – 参阅sqa common directory片断

    指导使用头文件和库文件


    推荐下边使用库文件方法:

    a)         自定义函数或者过程应该使用有同样文件名字的头文件(.sbh)和库文件(.sbl),比如DataFunctions.sbh和DataFunctions.sbl。这个过程和函数在头文件中定义(指定声明头文件)和在库文件中定义。看下边的例子

    b)        分离头文件(参阅常量头文件)用于包含常量,变量和用户定义类型用于脚本或者库文件调用。头文件用同样的文件名字后边附加_x或则_C(附加是早期命名规定)。注意包含常量和变量的头文件必须加入到声明头文件和库文件之前。(DataFunctions.sbh和DataFunctions.sbl),比如’include “DateFunctions_c.sbh”。这样做很容易维护。

    c)         通过分类或者程序把相关的函数放在同一个库里,例如,把所有日期相关的函数放到DataFunctions.sbh/sbl,或者把所有的函数加入为特定程序开发的函数库中(比如AppName.SBH/SBL)


    d)       函数是在库文件中子程序的的首选方式,处分过程的结果对于调用脚本是不相关的。函数应该返回一个值,或者适当的,数据可以通过变量或者数组返回。在后边的例子中,函数返回的结果表示成果或者失败。


    e)       库文件中的所有得函数和子程序必须有“注释“,包含这个过程的目的和用途::

    请看下边的例子。


    f)         库文件的注释有合理的解释,通过读注释可以知道过程的逻辑


    g)        如果开发和维护robot库文件是集中管理的方式,那么你可以加入到’$include 所有库文件到global.sbh头文件中,这样做对所有头文件都有用。这可以加入缺省的脚本模板。作为选择,测试人员在每个脚本中可以选择或者包含需要的库文件。

    Rational Robot测试指导

    Paul Downes (Paul_Downes@providian.com)

    Carl Nagle (Carl.Nagle@sas.com)

    7 December 20, 2001


    头文件和库文件的例子

    (NB. 这只是个例子.)

    ___________________ Declarations Header: Excel.sbh ___________________


    '##############################################################################


    '# Excel Function Library v4.0 Library Header File


    '# ===========================


    '#


    '# DEscrīptION:


    '# Contains functions that utilize Excel's COM Automation interface to use


    '# spreadsheets. See Excel.sbl for library details.


    '#


    '# PACKAGE:


    '# Excel.sbh Library Header File


    '# Excel.sbl Source Code and Documentation


    '# Excel_X.sbh Library Include File


    '#


    '# HISTORY:


    '# Orig Author: Andy Tinkham <andy@tinkham.org>


    '# Orig Date : 12-10-98


    '#


    '# Error Handling Code by Mark Butler (MKButler@russell.com) and Andy Tinkham


    '#


    '# CHANGES:


    '# 00/00/00 Author Change details


    '#


    '# COPYRIGHT:


    '# This code is copyright 1998-2002 by Andy Tinkham <andy@tinkham.org>.


    '# except where otherwise indicated. Permission is given for use by the


    '# Rational TeamTest community. Redistribution is allowed as long as no charge


    '# is made for this code and all authorship credits remain intact.


    '##############################################################################


    '# CONSTANTS, VARIABLES, DATATYPES
  • Robot手工编写GUI脚本6

    2007-09-14 10:01:05

    Robot手工编写GUI脚本如何获取对象识别方法和属性

    以计算器为例,下面的脚本是键盘输入“1+1=”,然后关闭计算器。
    Sub Main
        Dim Result As Integer

        StartApplication "C:\WINNT\system32\calc.exe"
       
        Window SetContext, "Caption=计算器", ""
        InputKeys "1{+}1{ENTER}"
        Window CloseWin, "", ""

    End Sub
       
        Robot提供了获取对象识别方法和属性的利器――Inspector。通过Robot tools-Inspector..打开。现在使用SQAGetProperty命令获取1+1的结果值,并通过msgbox显示该值。
        鼠标左键按住Inspectot工具栏上的“Select Objcet”按钮,然后选择计算器的结果放开鼠标左键。Inspectot中显示出对象的识别方法,鼠标左键点击工具栏上的“Copy recognition String”按钮拷贝识别方法,属性值通过选择Inspector左下角窗口中的Text属性,然后鼠标左键点击工具栏上的“Copy”按钮拷贝属性。修改后的脚本如下:
    Sub Main
        Dim Result As Integer
        Dim sum as Variant

        StartApplication "C:\WINNT\system32\calc.exe"
       
        Window SetContext, "Caption=计算器", ""
        InputKeys "1{+}1{ENTER}"
       
        Result = SQAGetProperty ("Type=Label;ObjectIndex=1", "Text", sum)
        msgbox sum
       
        Window CloseWin, "", ""

    End Sub

        VU脚本是类C语言,区分大小写。所以在获取识别方法和属性值时最好的方法就是使用Inspector。
        自己编写脚本时,还有一个要注意的问题是窗口上下文,窗口上下文不正确会导致回放时找不到对象。上面的脚本中Window SetContext, "Caption=计算器", ""下面的操作都是在这个窗口上进行的。编写脚本时一定注意看一下窗口上下文是否正确。
        也可以在识别方法中指定窗口上下文,如Result = SQAGetProperty ("Type=Label;ObjectIndex=1", "Text", sum)可以改成Result = SQAGetProperty ("\;Type=Window;Caption=计算器;\;Type=Label;ObjectIndex=1", "Text", sum),第一个“\”代表桌面,“Type=Window;Caption=计算器”是计算器窗口,第二个“\”代表“Type=Window;Caption=计算器”和“Type=Label;ObjectIndex=1”是父子关系。这两个命令的效果完全一样。
  • 识别控件5

    2007-09-14 10:00:18

    识别控件
    需要相应的enabler,你现在测试的程序是delphi开发的应用软件,那么就要加载相应的delphi enabler!

    extension manager里边加入了delphi enabler,但是这个还是不能识别出delphi开发中用到的第三方控件或则其他控件!其实这里选择只是个打开使用真正的delphi enabler的开关,真正的delphi其实是一个sqasrvr.pas的单元文件,这个单元文件是识别控件的核心。

    ratitonal 2003里边的test enabler安装选项中包含delphi enabler,但是它需要你本机上安装delphi,才会把delphi enabler安装到你的机器上。否则不会出现。

    假如安装成功后,会在开始菜单中rational菜单下,rational test菜单下出现个delphi enabler(具体什么名字忘记了)的菜单项,通过它可以调用一个执行文件。
    执行文件的功能就是把sqasrvr.pas自动放到工程文件的头。

    delphi 工程文件只有加载了这个delphi enabler(核心 sqasrvr.pas)才会让robot识别,当然前提是你的extension manager中delphi选择了。

  • Rational Robot4

    2007-09-14 09:59:37

    使用Rational Robot录制自动测试GUI脚本,在点击一个按钮以后,出现的结果可能有多种,可能会出现一个含“确定”按钮的对话框,也可能出现一个标题为”Title abcd”的窗体,可以使用SQAWaitForPropertyvalue方法来判断出现的属性,或者使用SQAWaitForObject来判断出现何种窗体,下面是两个对可能出现的属性进行判断的例子。

    1).2秒内假若出现确定对话框,点击确定按钮,否则打印"确定按钮未出现" :
    '等待2秒直到确定按钮出现.
    Result = SQAWaitForPropertyvalue("Text=(O)确定", "Enabled",TRUE, 2000)
    If Result <> sqaSuccess Then
    print "确定按钮未出现"
    Else   
        PushButton Click, "Text=(O)确定"   
    End If

    2).2秒内假若出现标题为"Title abcd" 的窗体,打印"出现标题为Title abcd的窗体" ,否则打印"未出现标题为Title abcd的窗体" :
    '等待2秒直到标题为Title abcd的窗体出现.
    Result = SQAWaitForPropertyvalue("Caption=Title abcd", "Enabled",TRUE, 2000)
    If Result <> sqaSuccess Then
    PushButton Click, "Text=(O)确定"
    print "出现标题为Title abcd的窗体"
    Else   
        print "未出现标题为Title abcd的窗体"
    End If


    说明:
    1).Result是一个Integer型变量;

    2).SQAWaitForPropertyvalue:顾名思义,指的是等待一个属性被指定值之前暂停执行。SQAWaitForPropertyvalue("Text=(O)确定", "Enabled",TRUE, 2000)表示等待2秒直到确定按钮出现,如果2秒内未出现,则返回sqlfalse,出现则返回sqlsuccess;

    3).SQA Basic中<>表示不等于;

    4).另外,可以用SQAWaitForObject来判断出现出现的对象类型:
    Result = SQAWaitForObject("Type=PushButton;Text=OK", 2000)
    If Result = sqaSuccess Then
         ...          ' add the rest of the actions/tests here
    End If
  • Rational Robot3

    2007-09-14 09:58:49

    Rational Robot中自动进行100次操作
    Rational Robot中的SQA Basic与Basic语言极为类似,下面是一个for循环的例子,其中cstri()函数把整数转换成字符串。
    Sub Main
        Dim Result As Integer
        Dim i As Integer
        ……
       
         'begin of for loop
         for i=1 to 100 step 1
         ……
         InputKeys cstr(i*3) '这个地方设置输入值为I*3.
         ……
        next
        'end of for loop
        ……
    End Sub
  • 关于Recognition2

    2007-09-14 09:58:05


    一共分为Recognition, ParentRecognition, FullRecognition
    1. To find the recognition method of the currently active window:
    Result=SQAGetProperty(".\","Recognition",value)
    Returned value:
    Type=Window;Name=frmMain
    抓出来的是当前窗口的一些信息

    2. To find the immediate parent of the tree view item Bach:
    Result=SQAGetProperty("Name=treMain;\;ItemText=Bach","ParentRecognition",value)
    Returned value:
    Type=TreeView;Name=treMain
    抓出来的是树型结构的父结点的信息

    3. To find the complete object path of the tree view item Bach, beginning with the desktop and ending with the target object itself:
    Result=SQAGetProperty("Name=treMain;\;ItemText=Bach","FullRecognition",value)
    Returned value:
    Type=Window;Name=frmMain;\;Type=TreeView;Name=treMain;\;Type=TVItem;ItemText=Bach
    抓出来的是树型结构中指向该控件的全部路径

  • robot函数实例讲解1

    2007-09-14 09:57:17






    功能说明:出现一个提示对话框,N秒后消失,比如说:提示等待一个窗口阿,有时候这个窗口没了,我也不知道脚本运行到什么地方了,提示一下挺好,也方便其他的测试员修改,而且,也不影响无人值守的操作

    例子:SQAMsgbox "test","title",5

    Global iTime as Integer

    Declare Function TimedDlgFunc(id As String, Action As Integer, Suppvalue As Long) As Integer

    Declare Function SQAMsgBox(sMsgText as String, Optional vMsgCaption as Variant, Optional vTimeOut as Variant) as Integer


    Function TimedDlgFunc(id As String, Action As Integer, Suppvalue As Long) As Integer
        Static StartTime
        Dim EndTime
        Dim vTimeoutvalue as Variant

        Select Case Action
            Case 1      'Dialog box Initialization
                    StartTime = Timer

                    If StartTime + iTime >= 86400 Then
                            StartTime = 86400 - StartTime - iTime
                    End If
                    TimedDlgFunc = 1

            Case 2      'Button pushed or any control changed (except typing in text or combo box)
                Select Case Suppvalue
                    Case 1
                        DlgEnd -1
                    Case 2
                        DlgEnd 0
                    Case Else
                        TimedDlgFunc = 0
                End Select

            Case 3      'Change in text or combo box contents
                    TimedDlgFunc = 1

            Case 4      'Change of control focus
                    TimedDlgFunc = 1

            Case 5      'Idle state (return 0 to prevent this being continually called)
                    EndTime = Timer
                    If (EndTime - StartTime) >= iTime Then
                            DlgEnd -1
                    End If
                    vTimeoutvalue = Format(iTime - (EndTime - StartTime), "#.#")
                    DlgText DlgControlID("txtTimevalue"), CStr(vTimeoutvalue)
                    TimedDlgFunc = 1
        End Select

    End Function


    Function SQAMsgBox(sMsgText as String, Optional vMsgCaption as Variant, Optional vTimeOut as Variant) as Integer
        Dim Result as Integer
        Dim TotalTime As Integer
        Dim sCmdText as String   
        Dim sTimeoutText as String
        Dim vvalue as Variant

       
        If IsMissing(vMsgCaption) Then
            vMsgCaption = "SQAMsgBox"
        End If
        If IsMissing(vTimeOut) Then
            vTimeOut = 20       'seconds
        End If

        sTimeoutText = "Timeout: "
       
    '-----
        Begin Dialog dlgMsgBox 200, 80, vMsgCaption, .TimedDlgFunc
            GroupBox 5, 2, 190, 40, "", .grpMsgTxt
            Text 15, 11, 175, 25, sMsgText, .txtMsgText
            Text 15, 47, 180, 20, sCmdText, .txtCmdText
    '--------------
            Button 20, 60, 40, 14, "&OK", .btnOK
            Button 140, 60, 40, 14, "&Cancel", .btnCancel
            Text 78, 63, 30, 10, sTimeoutText, .txtTimeText
            Text 108, 63, 20, 10, vTimeout, .txtTimevalue
        End Dialog
    '-----

        Dim TimedDlg As dlgMsgBox
        iTime = CInt(vTimeOut)
        Result = Dialog(TimedDlg)
       
        If Result = 2 Then
            SQAMsgBox = sqaFail
        Else
            SQAMsgBox = sqaPass
        End If   
       
    End Function
  • 人有女朋友之后不要做十九条

    2007-09-14 09:28:05

     
     
     
         第一:不要问女人以前的事,毕竟过去的事了,说的详细你又受不了,说的简单你就心里老是打问号。 
      第二:同样,你也不要和她说太多以前的事,特别是你以前如何如何的深情,如何如何的不要自尊去爱另一个女人。 
      第三:不要有***情结,虽然现在这社会,有***情结的人不会很多,但终究是男人,多多少少会介意,记得摆正自己的心态。 
      第四:不要太大男人主义,现在的新时代女性,再也不是以前的那些唯命是从的小女子了,过于大男人主义,会让人受不了。 
      第五:不要把工作情绪带给她,你可以向她倾诉,但不要因为工作的问题 向她发脾气。 
      第六:不要当面去夸别人的女人漂亮,女人嘛,永远都觉得自己是最美的,你可以夸别的女人另一些,比如她的内在美,这样令她觉 得自己的不足之余,又懂得努力去改正自己。 
      第七:不要拿你以前的女友与她相比,说以前那个如何如何的好,那是不公平的,不同的人如何去比较呢。 
      第八:不要在朋友面前,不拉她的手,或不抱抱她,那样她会很伤心,觉得你并不在乎她,也令她没面子,适当的在别人面前表现恩 爱是必要的,(特别不能在朋友面前对她呼呼喝喝)。 
      第九:不要在大街上小眼不停盯着某一个女人,或者牵着她手的时候,不停的望身边的经过的女人,那是对她最大的屈辱。(你可以 在她不在的时候瞧瞧无所谓) 
      第十:不要坦白自己的xxx,无论是之前的还是现在的,都不要让她知道,女人的死穴,永远不接受男人的身体出轨。 
         第十一:不要不懂得说情话,甜言密语是爱情的润滑剂,但过多,就显得虚假。 
      第十二:不要轻易去怀疑另一半,过度的不信任让人觉得你没自信之余,又心胸狭窄。 
      第十三:不要试图去绑住一个女人,要坚信你温暖的怀抱是她一生的依靠,过多的举动则会吓跑对方。 
      第十四:不要不懂得体贴另一半,累了发个短信打个电话安慰一下,那比买任何礼物来得贴心 
      第十五:不要对不懂的事装懂,现在的女人可不是草包,很容易一眼就看穿你的肤浅,不懂就说出来,有什么大不了。 
      第十六:不要在气跑女朋友之后也不追,甚至一个短信也不发,那样很容易让女人心灰意冷。 
      第十七:不要在谈恋爱的时候,就把以后的事说的太现实化,那样会吓得她不敢和你走进婚姻的礼堂(结婚需要冲动,经营婚姻需要 智慧,离婚需要勇气) 
      第十八:不要在开始的谈恋爱的时候,就急着说性,那样会让人觉得你只用下半身和她谈恋爱。 
      第十九:不要睡在她身边的时候喊的是别人的名字,切记切记切……
  • Loadrunner中web_reg_save_param的使用详解

    2007-09-13 16:05:04

    字体:        | 上一篇 下一篇 | 打印  | 我要投稿

    【摘要】利用实际案例说明如何使用Mercury LoadRunner提取包含在 HTML 页内的动态信息并创建参数。

    【关键词】性能测试,压力测试,Mercury LoadRunner

    • 应用范围

    在使用Loadrunner进行性能测试时,经常遇到一种情况,需要通过web页面修改某事务的状态。于是需要首先读出当前的事务的状态,再进行修改,此时便可以使用到web_reg_save_param了。可以通过它先将事务的状态读出写入一个自定义的变量中,根据变量的值来决定下一步的动作。

    • 简要说明

    语法:

    int web_reg_save_param(const char *ParamName, <list of Attributes>, LAST);

    参数说明:

    • ParamName: 存放得到的动态内容的参数名称
    • list of Attributes: 其它属性,包括:Notfound, LB, RB, RelFrameID, Search, ORD, SaveOffset, Convert, SaveLen。属性值不分大小写
      • Notfound: 当在返回信息中找不到要找的内容时应该怎么处理
      • Notfound=error: 当在返回信息中找不到要找的内容时,发出一个错误讯息。这是缺省值。
      • Notfound=warning: 当在返回信息中找不到要找的内容时,只发出警告,脚本也会继续执行下去不会中断。
      • LB( Left Boundary ) : 返回信息的左边界字串。该属性必须有,并且区分大小写。
      • RB( Right Boundary ): 返回信息的右边界字串。该属性必须有,并且区分大小写。
      • RelFrameID: 相对于URL而言,欲查找的网页的Frame。此属性质可以是All或是数字,该属性可有可无。
      • Search : 返回信息的查找范围。可以是Headers,Body,Noresource,All(缺省)。该属性质可有可无。
      • ORD : 说明第几次出现的左边界子串的匹配项才是需要的内容。该属性可有可无,缺省值是1。如为All,则将所有找到的内容储存起来。
      • SaveOffset : 当找到匹配项后,从第几个字元开始存储到参数中。该属性不能为负数,缺省值为0。
      • SaveLen :当找到匹配项后,偏移量之后的几个字元存储到参数中。缺省值是-1,表示一直到结尾的整个字串都存入参数。
      • Convert : 可取的值有以下两种:

    HTML_TO_URL : 将 HTML-encoded 资料转成 URL-encoded 资料格式

    HTML_TO_TEXT : 将 HTML-encoded 资料转成纯文字资料格式

    • 实例讲解

    目的:取得页面中的商品状态,如果状态是正常态就改为注销态,否则改为正常态。

    录制脚本使用的是URL based scrīpt

    将返回的数据记录到日志

    • 直接手工访问页面,检查URL

    该页面上点击右键,选择属性

    看到URL,对照录制下的脚本中有:
    web_url("modifyOfferingStatePage.do",
    "URL={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
    282172&offeringSpecId=1&offeringSpecName=普通宽带(ADSL/LAN)&customerName=
    {clientname}&nodeId=260000&pos1=定购管理&pos2=修改商品状态",

    "Resource=0",
    "RecContentType=text/html",
    "Referer={url}/web/businessAccept/order/orderMenu.do",
    "Snapshot=t23.inf",
    "Mode=HTTP",
    LAST);
    于是在这段代码前添加注册函数:
    web_reg_save_param("oldstate",
    "LB/IC=原有商品状态:</td>",
    "RB/IC=</td>",
    "Search=body",
    "Ord=1",
    "RelFrameId=1",
    "SaveOffset=57",
    "SaveLen=4",
    LAST);
    web_url("modifyOfferingStatePage.do",
    "URL={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
    282172&offeringSpecId=1&offeringSpecName=
    普通宽带(ADSL/LAN)&customerName={clientname}&nodeId=
    260000&pos1=定购管理&pos2=修改商品状态",

    "Resource=0",
    "RecContentType=text/html",
    "Referer={url}/web/businessAccept/order/orderMenu.do",
    "Snapshot=t23.inf",
    "Mode=HTTP",
    LAST);
    ...............
    //将得到的内容存入日志用于检查
    lr_log_message("getvalue : %s",lr_eval_string ("{oldstate}"));

    if ( lr_eval_string ("{oldstate}") == "正常"){
    web_submit_data("modifyOfferingState.do",
    "Action={url}/web/businessAccept/order/modifyOfferingState.do",
    "Method=POST",
    "RecContentType=text/html",
    "Referer={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
    282172&offeringSpecId=1&offeringSpecName=普通宽带(ADSL/LAN)&customerName=
    {clientname}&nodeId=260000&pos1=定购管理&pos2=修改商品状态",

    "Snapshot=t24.inf",
    "Mode=HTTP",
    ITEMDATA,
    "Name=offering.state", "Value=1", ENDITEM,
    "Name=offering.recentModifyReason", "Value=修改原因", ENDITEM,
    "Name=offering.customerId", "Value=281218", ENDITEM,
    "Name=offering.offeringId", "Value=282172", ENDITEM,
    "Name=offering.offeringSpecId", "Value=1", ENDITEM,
    "Name=offering.recentMender", "Value=root", ENDITEM,
    "Name=offering.recentModifyDatetime", "Value=2005-01-16", ENDITEM,
    "Name=nodeId", "Value=260000", ENDITEM,
    "Name=customerName", "Value={clientname}", ENDITEM,
    "Name=offeringSpecName", "Value=普通宽带(ADSL/LAN)", ENDITEM,
    "Name=submit.x", "Value=33", ENDITEM,
    "Name=submit.y", "Value=13", ENDITEM,
    LAST);
    }
    Else
    {
    web_submit_data("modifyOfferingState.do",
    "Action={url}/web/businessAccept/order/modifyOfferingState.do",
    "Method=POST",
    "RecContentType=text/html",
    "Referer={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
    282172&offeringSpecId=1&offeringSpecName=普通宽带(ADSL/LAN)&customerName=
    {clientname}&nodeId=260000&pos1=定购管理&pos2=修改商品状态",

    "Snapshot=t24.inf",
    "Mode=HTTP",
    ITEMDATA,
    "Name=offering.state", "Value=0", ENDITEM,
    "Name=offering.recentModifyReason", "Value=修改原因", ENDITEM,
    "Name=offering.customerId", "Value=281218", ENDITEM,
    "Name=offering.offeringId", "Value=282172", ENDITEM,
    "Name=offering.offeringSpecId", "Value=1", ENDITEM,
    "Name=offering.recentMender", "Value=root", ENDITEM,
    "Name=offering.recentModifyDatetime", "Value=2005-01-16", ENDITEM,
    "Name=nodeId", "Value=260000", ENDITEM,
    "Name=customerName", "Value={clientname}", ENDITEM,
    "Name=offeringSpecName", "Value=普通宽带(ADSL/LAN)", ENDITEM,
    "Name=submit.x", "Value=33", ENDITEM,
    "Name=submit.y", "Value=13", ENDITEM,
    LAST);
    }
    从日志中截取的真实的返回内容为:
    vuser_init.c(689): <tr bgcolor="#F6F6F6">\r\n
    vuser_init.c(689): <td width="30%" height="23" align="right">\r\n
    vuser_init.c(689): 原有商品状态:</td>\r\n
    vuser_init.c(689): <td width="70%" height="23"> 正常 </td>\r\n
    vuser_init.c(689): </tr>\r\n
    vuser_init.c(689): <tr bgcolor="#F4FBFE">\r\n
    vuser_init.c(689): <td width="30%" height="23" align="right">\r\n
    vuser_init.c(689): 修改后的状态:</td>\r\n
    vuser_init.c(689): <td width="70%" height="23">\r\n
    vuser_init.c(689): \r\n
    vuser_init.c(689): \r\n
    vuser_init.c(689): \r\n
    vuser_init.c(689): <input type="radio" name='offering.state' value='4' checked>
    可以看到左边界是:原有商品状态:</td>,
    右边界是:</td>,偏移量为:57(包括了空格),
    长度为:4(因为一个汉字长度为2),最后存入变量的值是:正常

    4.经验总结
    1)为了便于脚本的调试,将返回的数据都写入日志是个好办法;
    2)为了验证取得的数据是否是自己期望的,可以将取得的数据写入日志中进行验证,
    例:lr_log_message("getvalue : %s",lr_eval_string ("{oldstate}"));
    3)因为它是一个注册函数,必须在返回信息前使用,所以注册的位置必须正确,否则很可能得到类似如下错误:
    4)vuser_init.c(734): Error -27190: No match found for the requested parameter "oldstate".
    Check whether the requested boundaries exist in the response data. Also,
    if the data you want to save exceeds 1024 bytes,
    use web_set_max_html_param_len to increase the parameter size [MsgId: MERR-27190]
    5)vuser_init.c(734): Error -27187: The above "not found"
    error(s) may be explained by header and body byte counts being 0 and 0,
    respectively. [MsgId: MERR-27187]
    6)vuser_init.c(734):
    web_concurrent_end highest severity level was "ERROR" [MsgId: MMSG-27181]
    7)所以使用手工方法,右键页面确定在代码中哪个位置之前注册函数至关重要
    8)如果脚本中中文为乱码,可能是因为源文件的字符集和操作系统字符集不匹配。试试:

    祝各位好运

  • 一个测试新手与mercury认证的不解情结

    2007-09-13 15:57:59

    字体:        | 上一篇 下一篇 | 打印  | 我要投稿

        2005年9月26日,不知天高地厚的我,参加了上海51testing组织的Mercury认证考试,因为感觉性能测试软件测试行业中待遇比较高的职位,为此本人也在这种拜金主义心理的作祟下,报考了loadrunner这款工具。10月19日,51testing的朴老师电话通知我考试成绩——74分,哈哈,顺利通过!谢天谢地,俺这样的新手第一次参加这样的考试,竟然通过了!感谢51testing老师们的辛勤培训,应该说,他们提供的考前辅导还是相当有效的;当然也要感谢自己,三个星期来的日夜兼程,把loadrunner这款工具的使用搞的死去活来,挥洒自如(有点自夸哦)。

        据51testing的老师讲,本季度考试通过率不错,在50%左右,尤其上个季度没有通过的考生,这次通过了很多。为此,本人笔兴大发,决定总结一下自己的考试经历,哈哈,大家给点面子,别乱拍砖,照顾下俺这个测试新手吧!

        从哪说起呢?既然想总结下自己这1年多来的工作生涯,干脆从毕业说起吧!我是个北方人,毕业于西安某三流的大学;北方人一直对北京都有个莫名的情结,所以2004年毕业后只身闯京城,拿着计算机本科毕业证,在举目无亲的都市里漫无目的的穿梭于各大招聘会。一个月下来,没有任何单位有要我的意思;唉,都要工作经验,而且我又不是名校毕业,眼瞅着和几个清华、北工大的家伙一起去投简历,都不好意思和面试官打招呼,唉,可怜的我!没办法,只好想办法钻点空子!经历了十来场招聘会,总算摸清这些单位的用人需求,不就是java么?不就是数据库么?不就是unix么?好,咱学!于是在北京7平米的小茅屋里寒窗苦读,把这些上学时候学的稀里糊涂的东东搞定,于是迎来了某软件公司的初试——做题!(如果大家有过类似经历,我会和你报头痛哭;如果没有,ggjj们,你们是不知道现在的用人单位招人多严苛,上来啥也不说,先做2小时的卷子再谈!)还好,这次准备充分,而且几个月来做的卷子不少(当然都被“莫需有”的理由拒了),别的能耐咱没有,笔头子功夫练出来啦!结果笔势完毕,在门口外和一个北邮的家伙一起抽烟等待通知。这哥们和我有着相同的被拒经历和被拒次数,因此马上情趣相投起来,我手上的烟也是他派的,一看,是我讨厌的“中南海”!没办法,不抽白不抽!这哥们和我一样来应聘程序员,看着他饱含沧桑的眼角,我深深体会到:1)这年头,和我一样的毕业生,找工作难哪!2)这小子抽烟手势不端正,因此经常呛到眼睛,哈哈!

        半小时后,一个打扮比较风骚但是一点都不漂亮的中年女人(之所以把她先拉开帏幕,因为她就是我日后的上司),和另外一个大汉(他是日后我们项目的开发经理)出来,叫我俩进去一下,对其他来笔试的人又说了点漂亮的拒绝言辞;这时候,我又深深意识到两点:1)我和北邮兄有戏 2)那些被拒的弟兄将会继续走完我走过的路…

        第二轮面试时,我和北邮兄只是在一个小屋里被不漂亮女人和大汉简单的蹂躏下;最后的结果是:北邮兄由于java基础好,去做了程序员;我呢,去做测试!在离开小屋的那一刻,我下意识的悄声问了下北邮兄:啥叫测试啊?北邮兄:好像是测试程序吧!前边的大汉似乎听到了我们的对白,回头用极其鄙视的眼神看了我一眼,那眼神锐利得直刺我的胸口,好像对我说:小样,——新来的吧!

        日后的岁月里,我在这个小公司极其混乱的测试流程里煎熬着。虽然本人不聪明,但是咱笨鸟先飞,在7平米的小屋里,无数个黑夜里,俺懂得了软件工程,俺了解了RUP,俺知道了测试应该按阶段来实施,不是想测什么就测什么,俺还知道测试用例的非常重要,但是不知道为什么公司里做测试不按照测试来执行呢?于是俺上网找资料,希望把自己的想法说给女人听,俺想让她知道:俺不想一直拿1800的试用期工资,俺想改进公司的测试流程,俺想离开7平米的没有暖气的茅屋,因为冬天来了,俺不想被冻死…3个月后的年底转正,我写了一份“热气腾腾”的工作总结递交给女人,想好好表现一把。但是俺失败了,在女人威严的慑服力下,俺屈服了!因为后来我和北邮兄讲,他告诉我:如果要采纳你的意见,这个公司的老板该回家当奶爸了!

        此后是我3个月的人生低潮期,因为俺的转正工资只有2300,扣了社保不到2000;因为俺依然要在茅屋里蹲过这个冬天,因为除了填饱肚子,所有的积蓄都要还给北邮兄,买个破手机要我还3个月,唉!黑夜里,仰望夜空,很美;唱着杜甫的《茅屋为秋风所破歌》,很凄凉!我不知道这样的日子要持续多久,不知道是公司不容我还是我容不下公司,不知道自己该何去何从!

        这次应该感谢51testing的sincky!为什么呢?因为他的一篇文章把我从这段低谷里挽救了出来。年后的某日,在网上偶然看见一篇文章《借刘德华演唱会小喻测试人生》,开始看着感觉写的挺诙谐的,后来深思了一下,感觉说的很有道理:原来没有人可以一步登天,原来要成就大事就要从小事做起,原来这么浅显的道理却被很多人忽视,竟然不能化为实践!在他的blog里,我学习到很多,也因此在这个时候和他在msn里结识,原来每个成功的背后都隐藏了几多心酸和挣扎,因为在很多经历里,我们竟然有几分的相似。于是,我意识到自己是时候该奋起直追了,蹉跎了岁月,伤透了年华,既然国内的软件测试行业如此的不成熟,是不是说明我有很多成功的机会呢?在网上结识了几个测试领域的高手以后,我又一次认识到自己的不足,因为:从前我懂的测试理论、测试流程是一种标准化的东西,对于国内很多软件公司来说,还仅仅是一个方向而已!这么说来,我没有能力改进公司的测试流程,但是我有能力改进自己的测试技能!相信很多同行朋友从前或目前一定有和类似的心境,那么在你读到这里的时候,你一定该立刻振作起来,从自身出发!换句话说,如果每个测试从业者个人的能力都提高了,整个软件测试行业就自然的进步了。

        这时候,就不得不提自动化测试了。应该说,刚工作的时候,我就搜索各大软件测试的网站、论坛,发觉自动化测试是每个论坛里讨论最多的话题。开始由于自己没有软件,而且感觉学自动化测试的朋友们总有那么多问题,所以感觉这东西可望而不可及。但是有几次和北京业内的测试朋友见面聊天的时候,他们都一致认为自动化测试是测试行业发展的方向,而且这东西可以自己掌握,不需要改变公司的任何规章,哈哈!于是,从朋友那里拷来一份mercury的winrunner、loadrunner,还有个rational robot(好像一提到自动化测试工具,想到的基本就是这几个,看来我知道的都晚了!),趁下班的时候,在自己的机器上玩命的摆弄。开始也没想太多,反正别人用了,自己也不甘落后,不然总觉得别人一谈自动化测试,自己没的说,感觉不爽!起初,学习的时候,有问题到论坛查资料,后来发现51testing的论坛资料还是非常全的,于是统统下载来,成天研究手册,然后在机器上练习,把自己的机器搞的乌烟瘴气,不过从来没有让女人发现过,强吧!

        开始,有问题我会到各大论坛去提问,但是后来发觉51testing的提问响应时间是最快的,这是让我第一次佩服51testing的做事效率,后来干脆就不去别的论坛了。由于自己有点java编程基础,加上java和c语言差不多,我就从winrunner开始学起;于是花了2个来月,我把winrunner学完了,怎么叫学完了呢?因为2个月后,我已经从原来的提问问题请求别人回答,过渡到后来的看别人问题给别人回答了!其实大家不要拍砖,因为此时虽然我能给别人解决一些论坛里的问题,那是因为大家学习的时候,遇到的问题和我遇到的都差不多,所以自己多思考一下就成了;其实那时候我的工具使用水平还很差,直到后来我参加51testing的远程培训才真正意识到这种差距还不是一点点。

        那个时候,我和一些论坛的朋友一起学习使用winrunner,那种攻破一个个技术难关后的成就感,是我们很多搞技术的朋友们经常会有的,很满足,很兴奋!winrunner学罢,自然而然的就想学loadrunner;为什么呢?因为他们是一个公司的东东,而且脚本方式基本类似,另外,我也渐渐知道loadrunner作为全球市场占有率最大的性能测试工具的强大优势,加上经常浏览51job上的测试工程师招聘信息,让我更加坚信这一点:如果我能把winrunner、loadrunner都学好,那么离开眼下的这个公司是迟早的事。私下问了一些朋友,在北京做自动化测试的职位月薪有多少,统计了一下,在3500到6000左右,如果是外企或者用友、神码这样的公司,做好了会更多;另外一个值得庆幸的是,性能测试工程师有的企业标价在一万以上,呵呵,这不,有奋斗目标了不是!但是自己清楚目前资力还很低,很多东西还是学习阶段,没有真正在企业里实践过,所以还是放住脚跟,把现有的知识学扎实了。

        3个月后,loadrunner基本使用搞定了;下班的时候,试着给公司的服务器加压,哈哈,有一次真的把数据库搞down机了,第二天公司的系统工程师查到是我的ip搞的,于是来质问我究竟想干什么;我说做性能测试啊!它听说是用loadrunner,结果反倒跟我请教问题,哈哈!这小子总认为自己做网管不爽,反倒羡慕我们做测试的,说这是一个长期的饭碗;网管么,青春饭(这是他的原话,诸位网管朋友别拍我)!

        这个时候发生在今年夏天,由于自己能力的飞跃增涨,这种压抑的物质欲望也愈加膨胀;加上在北京认识了很多业内的高手,他们开始建议我跳槽了…怎么办呢?说到要离开,还有点舍不得这里的弟兄们,北邮兄仍然风雨兼程的闷头苦编程序,偶尔一起抽烟吃饭;但是他是北京人,工资问题不是他的最大问题(顺便提下,他的最大心愿是想拥有一份超过3个月的完整恋情,哈哈;因为每个女朋友都是莫名其妙的一个电话、一个短信就提出分手了!)。但是网管哥们劝我跳槽要谨慎,要跳就跳个像样的公司,如果只为了几百块钱,去熟悉一个全新的公司,有点划不来。他说的不无道理,但是想让自己的待遇翻倍谈何容易?再征求多方朋友的意见下,最后决心努力做好学好loadrunner使用,在性能测试领域寻找突破口。要做性能测试,光有工具的使用远远不够,要把这款工具真正的用到实际软件的性能测试中,要对软件架构、数据库、操作系统、网络都要了解;好,说干咱就干!孤家寡人一个,没有别的夜生活,没有别的娱乐活动,除了学习就是拿公司的软件练习(感谢我原来的公司,真的,虽然女人、大汉也许都不知道此事,这里还是要感谢他们的默许和睁只眼闭只眼)。

        7月份,我偷偷的面试了一个北京某外包公司,在问到性能计数器的添加方面,我哑口无言;8月份,被问到模拟一个真实网站性能测试的场景设计有什么注意事项时候,我又无言以对…唉!怎么办?我所学习的仍然很基础,实践性的东西我还很欠缺!要找一份性能测试工程师的理想职位,还真是难啊!

        这个时候,不得不重提51testing;因为此时我得知51testing推出了mercury工具的国际认证,而且提供工具使用培训和考前培训。开始我对认证并无兴趣,只是想参加他们所说的CPE工具培训,来多学点东西,从而弥补自身摸索阶段的不足。于是我报名参加了51testing的loadrunner CPE培训,这时,是我第二次佩服51testing老师的能力过人之处;原来在CPE培训里,我曾经遇到过的一些困惑和疑难,经过老师的讲解,真有豁然开朗之感,而且从他们那里获取的一些资料,让我对性能计数器的使用有了更加清晰的认识。

        之前因为sincky的那篇《漫谈测试工程师与mercury认证》的文章,和他交流过;但是当时觉得国内的认证做的太烂了,而且自己一向认为能力不是靠证书来证明的,是良马终究会遇到伯乐的!但是在经过CPE培训后,自己由衷感觉到他们的培训实力还是相当强的,毕竟是给企业做培训的老师,讲出来的东西确有高人之处;可能是自己被他们的人格魅力折服了吧,呵呵!于是心里暗暗打算,将来有钱了,是不是也去考一个SP或者CPC啊,哈哈!

        一个偶然的机会,在51job上发现一条某公司的招聘信息,性能测试工程师,月薪12000,再看招聘条件的最后一项写着“mercury认证者优先”。我赶忙瞪大眼睛,再看是一个外企,不错、不错!看来我这条路算是选对了,自动化测试——有搞头!于是重新温习了sincky的那篇《漫谈测试工程师与mercury认证》,起初认为文章说的比较有道理,但是依然认为有一些商业宣传的味道,但是现在想来,文章说的还是相当有道理的:

        1)“觉得国内的认证做的太烂了”:和51testing的人接触过后,特别是在后来我去上海参加SP的认证考试,和51testing的老师们面谈后,发觉他们是真真正正的在做软件测试的培训,真真实实的想把MECRURY认证做好;有这样精干、高效、强劲的团队,从我个人角度讲,这个认证的价值我相信!

        2)“认为能力不是靠证书来证明的”:这话到现在我也不否认,个人能力不是一张纸能体现出来的,即便是纯金的,即便是比尔.盖茨亲笔签名的;但是证书却是获得高薪工作的敲门砖,尤其在这个证书还没有普及到人手一份的时候,它更能体现你在众多竞争对手时候的优势!为什么呢?因为我有证书,所以我有自信!因为我有证书,在心理暗示上,我认为我对工具的使用熟练度上要比别人强!从另一个角度来说,国内学习自动化工具的人成千上万,但是真正能熟练使用的人又有多少呢?也许这话不该出自我这个新手之口,但是在我后来到上海面试某大型软件公司的性能测试工程师时,深刻体会到我身边的那边朋友与我的差距(如果那位朋友看到此文,在此非常抱歉,不过我没有任何贬低你的意思,呵呵),所以我觉得如果能通过认证考试的人,起码对工具的使用是非常熟练了,从mercury认证的考试范围你会发觉它考的方面相当广泛,不是轻易就能通过的。

        3)“是良马终究会遇到伯乐的”:这话也不假,不过从现在严峻的就业行情来看,“酒香不怕巷子深”的岁月已经不复存在了,想找一份理想的高薪的工作,不是自己努力争取,没有人会送上门来找你;即便是猎头公司上门来拉你,那也是因为个人能力到达一定境界。但是想要达到这个境界,突破个人职业生涯的瓶颈,就要付出很多的,当然包括这种类似的智力投资啦!

        哈哈,不分析这个啦,拙见、拙见!于是我联系了51testing,准备报名所谓的loadrunner的SP认证考试,当然在价格上,他们也给我打了折扣;虽然花去了5个月的积蓄,但是我知道迟早有一天,我会翻倍的赚回来。9月底在51testing的远程培训站点上,俺认真研究了每个模拟题,了解了考试的难度和题型,之后在9月24日抵达上海,参加26日的考试。其实这时候,我已经电话联系好一个上海的那个大型软件公司,27号参加面试。该公司购买了loadrunner工具,并招聘性能测试工程师,准备组建自动化测试团队对公司开发的软件产品进行性能测试。面试期间没有什么特别剧情要说给大家,只是他们听说我参加了mercury认证考试,加上我回答loadrunner使用问题上的自信表情,所以同意录用了我;非常欣慰,因为我即将告别北京的那所7平米茅屋,因为我的薪水翻了2倍多,哈哈!

        十.一七天就这样结束了!明天我就要背上行囊,踏上上海的征程了。独自走在灯火璀璨的京城长街上,回想起1年来的生活片断,那种百感交集的感觉是无法用文字来形容的;就要离开了,虽然那里是另一个物欲横流的社会、另一个繁华喧闹的城市,但是我仍然怀念你:北京——这个城市,还有更重要的是这个城市里的好朋友们,包括女人和大汉;女人,其实你的妆不化那么浓,还是比较漂亮地;大汉哥,我的项目经理,其实你该经常刮下胡子;还有北邮兄,感谢你经常派给我不爱抽的“中南海”,不如尝尝“白沙”;网管兄,希望早日在测试行业里见到你,不过怕是见不到你了,因为你都36啦!…

        我的文笔并不好。本来由于刚刚获悉认证考试的结果,兴奋过了头,所以想写点东西总结下自己;因为对我而言,这次认证考试的经历过后,让我进入了一个全新的职业生涯里程,所以想和大家分享一下;结果话说多了,把这1年多来的经历都流水帐的记录出来了,没办法,本人爱罗嗦是出了名的!既然本文标题是关于mercury认证的,那么最后请允许我再给将要报考mercury认证的朋友一点经验分享:1)SP等级的考试一点都不难,但是考的内容很细,它是真正的考核我们的工具使用熟练度;所以一定要在考前多多的实践,练习它的每个功能点的操作 2)考试题目虽然是英文,但是都是很简单的英文,连我这样的新手都能一次通过,大家该更有信心才对 3)外国人出题很单一,绝对没有怪僻的题目,甚至它在题设里就告诉你,应该有几个答案,所以没有什么迷惑性 4)题目难度不大,但是题量比较大,而且是总分的70%算及格,所以答题时候要谨慎哦,使遍浑身解数也要争取把题目做对哦 5)51testing.com" target="_blank">51testing组织的mercury认证考试,每个考生都可以有2次考试的机会,所以我觉得即便第一次失误没有通过,有了一次经验,在第二次肯定可以通过的,只要你用心去学习它 6)也是最重要的,就是要珍惜51testing提供的考前培训,虽然培训里没有原题,但是这是初次应考者唯一的考前辅导,价值不可忽视

        自动化测试的职位,在网上火的大红大紫,希望这个势头多持续几年,哈哈,来日等我考取CPC认证,就可以去应聘那些高级的性能测试工程职位喽,起码让自己的投资有所回报,也尝尝月薪过万的感觉!朋友们,让我们互相祝福吧!

        就这样吧,做为一个新手,很多话讲出来怕同行笑话,不过俺也不怕啦,自己的道路自己选择,同意我的说法的、不同意我的说法的,都可以抽空来和俺畅谈;初到上海,正缺朋友聊天呢,呵呵!联系qq 411469763,不过刚刚来到新公司,不能经常在线,见谅啦!

    转载请注明文章来源51testing

  • 一封让老板看后一夜没睡的辞职信

    2007-09-13 15:20:35

    2006-07-28 13:53:09 / 个人分类:转贴好文

    [转贴--搞笑趣文] 
    3~#V dP`(zTt140627 51Testing软件测试网jsl!x9O$k7j%u
      这是我两年前写的。老板看过之后告诉我:一夜没睡,刺激很大!
    XO v;{w$T140627
    V;l _I3v?~140627   两年间,我跳槽九次,从作WAP开发到作网管,最短11天,最长是这次。那时我找不准究竟要干什么,跳槽是我获取新知识的手段,跳槽使我心浮气躁。 51Testing软件测试网nyT;xA5v"L(m~`K'Nv"_
    51Testing软件测试网Hvr3nZL.v
      来到这个新环境,开始感觉还不错,真是想好好干下去。事实上也是如此,我很久没在一个公司干过这么长时间。我原来有很多项目,本想拉到公司来做。但是公司很多事情和你的行为让我感到失望。我以为,跟随一个英明果断、有人格魅力的领导打工,我才有发展和前(钱)途。 51Testing软件测试网c1R/{(LXq#m
    51Testing软件测试网 ZO `'OOS8QL
      在私企干了这么久,我非常了解老板之辛苦,老板也很难,所以我有利益上的不满很少说。当我无法忍受的时候,就辞职。但我觉得有些事情不得不说给你听(我不说没有人会说给你,这也是我要辞职的一个原因):
    hK Qb}140627 51Testing软件测试网5B7q5o(m9W'D/h L
      1、作为老总,有些琐碎之事,你不该过问。老总就应该做一些比较大、有水平的事情,整天盯着下边的员工毕竟让人不舒服。例如,哪台计算机给谁使用,怎么又迟到早退啦,关于报销之类的事等等。小事虽小,却使老总形象毁于一旦。
    'dg1vV7t^*LV140627
    k;t/d%x@\140627   我从没有见过老总亲力亲为计算每个员工的年薪,并亲自发到每个员工的手中。51Testing软件测试网 ~;~8] @.h;uQk

    pwda9|140627   这也太平易近人了吧?
    j{r%|:x$sS;^f140627
    6jAq4Ms$hZL.]Rn140627   2、纠偏过正。办公开支是应该节省,网是不能无限制地上,车是不能随便地打,话费是不能随便地报,出差费用是不能太高……但是不要太过,否则员工会怨声载道的。
    s8NZ8[xn140627 51Testing软件测试网0b^(D5C\l0\o$L]#Z
      3、要讲公平。迟到扣钱,那么加班呢?工作要讲效率,而不能光看工作时间,能不能完成工作要看自觉性,何必非要上下班打卡呢?准时上班我却打瞌睡,有个屁用!比如你自己,迟到多少回了,能说你上班没努力吗?
    zj.YT\t#rD3\"g140627
    {&U'zfEo140627   你给我上保险,我很高兴,但这件事情你干得没水平。为什么每个人的待遇不一样,有的人上,有的人却没有(也许我是不知好歹)?这对别人是不公平的,你怎么能够留住人心呢?这种小把戏完全是个人行为,而不是公司行为。
    dfoe$a,Ew v140627
    "fF$i0VH2^140627   4、说话要算数。我来的时候,阿毛明确说过:今年年薪按照一年算。但阿毛走了,也无据可循,你记得不记得我就更不知道了。我来公司已经卖了力气,交给我的工作我都完成了,而且×××的项目我已给公司赚回了我的年薪,而且今年会有更多的项目(但你也许认为很小)。公司网络和布线方面没什么利润,和我没有任何关系。居然年终没有双薪和奖励,而且扣钱,这使我决定走人。 51Testing软件测试网 a)D7X3N:h
    51Testing软件测试网n&Z(p7_6rnU j;u
      5、用个人行为来管理公司,认为公司是我的,管理公司可以说是随心所欲,公司管理得一塌糊涂,全凭一个人说了算,狭隘的私有财产心理在作怪,典型的小农经济思维方式。 51Testing软件测试网5X,sd]-Z-P1P(D

    }mvtMh"i140627   6、我比较喜欢自由的工作,没有束缚,喜欢有施展自己能力的空间,公司不适合我。51Testing软件测试网"ZCCr4t_ w]z

    lT/d7FZ)f)]hR7d140627   我与西北人的工作方法(喝酒、请三陪、揣钱)和思考问题的方式(用户太至上,尊严何在?)基本无法沟通,我不想再去西北做项目,因此我在公司无用武之地。 51Testing软件测试网9^;A e&vI7`$}
    51Testing软件测试网-[(x,K)R \
      九个月来,我像个打杂的,一会儿去兰州十几天(本来也就需要一两天),一会儿去东单电话局做本来无法完成的调试(不可完成的任务),或对用户说一些不着边际的谎话,做了很多没有意义和受累不讨好的工作,也没学着什么东西(倒是敲了几万字的方案)。浪费了不少时间,却没有完成工作的满足感和成就感。
    '?mu J"]Uu;qG,\M;g140627
    Fd7O"y(OY:W K140627   我所做的工作与我来公司预期想象的完全不一样。我想你至今也不知道我擅长的是什么,我喜欢什么工作、厌恶什么工作。
    )f%h.^'GY-T4BG140627
    -u-m9_jj:m*e`&S#A140627   7、公司像个小作坊,当一天和尚撞一天钟,没有安全感,大家在一起有混的感觉。无论公司以前怎么辉煌,至少现在公司缺少大气。而且我们拿项目靠的不是技术实力。换句话说,公司舍得在搞关系上挥金如土,而在技术上却一毛不拔,一年了,没有任何技术资金投入。这也许就是作技术的与商人的区别。
    /s!D7b;{ w(?#Xm y140627
    `!_ F9] d6kDS140627   8.公司问题太多,不写了,你也不一定爱看。 51Testing软件测试网sI(w ? f{MM!\
    51Testing软件测试网:M rh.ccg,I~D
      总之,今次,我之所以在公司做了不足一年便提出辞职,是因为公司给我的发展空间有限,而且自己表现出的能力,老板不懂得欣赏。我多年跳槽的准则是:既然老板不给自己发展机会,自己也不会给老板机会,辞职走人。51Testing软件测试网~0t1U OCj,R
    51Testing软件测试网9L ~5I[7p7\_Y
      10万年薪,你也许能够找到比我好的职员,但你千万不要以为仅仅靠这10万年薪就可以留住一个技术人员的心。本来现在就是一个双向选择、互炒鱿鱼的时代,少了谁公司都照样运转。我对公司实心实意,公司也要对得起我。
    .b8I;z e/[ a8K140627 51Testing软件测试网SeE;mh
      我辞职对公司不会有任何影响,高手有的是,祝愿公司兴旺发达!
  • 单元测试的基本方法

    2007-09-12 16:18:06


    单元测试的对象是软件设计的最小单位——模块。单元测试的依据是详细设描述,单元测试应对模块内所有重要的控制路径设计测试用例,以便发现模块内部的错误。单元测试多采用白盒测试技术,系统内多个模块可以并行地进行测试。
        单元测试任务
      单元测试任务包括:1 模块接口测试;2 模块局部数据结构测试;3 模块边界条件测试;4 模块中所有独立执行通路测试;5 模块的各条错误处理通路测试。
      模块接口测试是单元测试的基础。只有在数据能正确流入、流出模块的前提下,其他测试才有意义。测试接口正确与否应该考虑下列因素:
      1 输入的实际参数与形式参数的个数是否相同;
      2 输入的实际参数与形式参数的属性是否匹配;
      3 输入的实际参数与形式参数的量纲是否一致;
      4 调用其他模块时所给实际参数的个数是否与被调模块的形参个数相同;
      5 调用其他模块时所给实际参数的属性是否与被调模块的形参属性匹配;
      6调用其他模块时所给实际参数的量纲是否与被调模块的形参量纲一致;
      7 调用预定义函数时所用参数的个数、属性和次序是否正确;
      8 是否存在与当前入口点无关的参数引用;
      9 是否修改了只读型参数;
      10 对全程变量的定义各模块是否一致;
      11是否把某些约束作为参数传递。
      如果模块内包括外部输入输出,还应该考虑下列因素:
      1 文件属性是否正确;
      2 OPEN/CLOSE语句是否正确;
      3 格式说明与输入输出语句是否匹配;
      4缓冲区大小与记录长度是否匹配;
      5文件使用前是否已经打开;
      6是否处理了文件尾;
      7是否处理了输入/输出错误;
      8输出信息中是否有文字性错误;
      检查局部数据结构是为了保证临时存储在模块内的数据在程序执行过程中完整、正确。局部数据结构往往是错误的根源,应仔细设计测试用例,力求发现下面几类错误:
      1 不合适或不相容的类型说明;
      2变量无初值;
      3变量初始化或省缺值有错;
      4不正确的变量名(拼错或不正确地截断);
      5出现上溢、下溢和地址异常。
      除了局部数据结构外,如果可能,单元测试时还应该查清全局数据(例如FORTRAN的公用区)对模块的影响。
      在模块中应对每一条独立执行路径进行测试,单元测试的基本任务是保证模块中每条语句至少执行一次。此时设计测试用例是为了发现因错误计算、不正确的比较和不适当的控制流造成的错误。此时基本路径测试和循环测试是最常用且最有效的测试技术。计算中常见的错误包括:
      1 误解或用错了算符优先级;
      2混合类型运算;
      3变量初值错;
      4精度不够;
      5表达式符号错。
      比较判断与控制流常常紧密相关,测试用例还应致力于发现下列错误:
      1不同数据类型的对象之间进行比较;
      2错误地使用逻辑运算符或优先级;
      3因计算机表示的局限性,期望理论上相等而实际上不相等的两个量相等;
      4比较运算或变量出错;
      5循环终止条件或不可能出现;
      6迭代发散时不能退出;
      7错误地修改了循环变量。
      一个好的设计应能预见各种出错条件,并预设各种出错处理通路,出错处理通路同样需要认真测试,测试应着重检查下列问题:
      1输出的出错信息难以理解;
      2记录的错误与实际遇到的错误不相符;
      3在程序自定义的出错处理段运行之前,系统已介入;
      4异常处理不当;
      5错误陈述中未能提供足够的定位出错信息。
      边界条件测试是单元测试中最后,也是最重要的一项任务。众的周知,软件经常在边界上失效,采用边界值分析技术,针对边界值及其左、右设计测试用例,很有可能发现新的错误。
  • 界面测试

    2007-09-12 14:39:37

    1.应验证界面显示内容的完整性:

    a)        报表显示时应考虑数据显示宽度的自适应或自动换行。

    b)        所有有数据展现的界面(如统计、查询、编辑录入、打印预览、打印等),必须使测试数据的记录数超过一屏/一页,以验证满屏/页时其窗体是否有横向、纵向滚动条或换页打印,界面显示是否正常;

    2.应验证界面显示内容的一致性:

    a)        如有多个系统展现同一数据源时,应保证其一致性;

    3.应验证界面显示内容的准确性:

    a)        对于报表中的所有字段值都应该有明确的定义,对于无意义的字段值,不应该显示空,应显示“--”或“/”,表示该字段值无意义。

    4.应验证界面显示内容的友好性:

    a)        对统计的数据应按用户习惯进行分类、排序。

    b)        某些重要信息在输入、修改、删除时应有“确认”提示信息;

    c)        界面内容更新后系统应提供刷新功能。

    d)        用户在退出系统后重新登陆时应考虑是否需要自动返回到上次退出系统时的界面;

    5.应验证界面提示信息的指导性:

    a)        在多个业务功能组成的一个业务流程中,如果各个功能之间的执行顺序有一定的制约条件,应通过界面提示用户。

    b)        用户提示信息应具有一定的指导性,在应用程序正在进行关键业务的处理时,应考虑在前台界面提示用户应用程序正在进行的处理,以及相应的处理过程,在处理结束后再提示用户处理完毕。

    c)        在某些数据输入界面,如果要求输入的数据符合某项规则,应在输入界面提供相应的规则描述;当输入数据不符合规则时应提示用户是否继续。

    d)        在对任何配置信息修改后,都应该在用户退出该界面时提示用户保存(如果用户没有主动保存的情况下);

    6.应验证界面显示内容的合理性:

    a)        在对某些查询功能进行测试时,应考虑查询条件的设置的合理性以及查询结果的互补性。如某些后台处理时间不应该作为查询条件。

    b)        界面测试时,应考虑某一界面上按钮先后使用的顺序问题,以免用户对此产生迷惑。例如只能在查询成功后显示执行按钮。

    c)        界面测试时,应验证窗口与窗口之间、字段与字段之间的浏览顺序是否正确;

    7.界面测试时,应考虑用户使用的方便性:

    a)        在某些对数据进行处理的操作界面,应考虑用户可能对数据进行处理的频繁程度和工作量,考虑是否可以进行批量操作。

    8.界面测试时,应考虑界面显示及处理的正确性:

    a)        界面测试时应验证所有窗体中的对象状态是否正常,是否符合相关的业务规则需要。

    b)        应验证各种对象访问方法(Tab 健、鼠标移动和快捷键)是否可正常使用,并且在一个激活界面中快捷键无重复;

    c)        界面测试不光要考虑合理的键盘输入,还应考虑是否可以通过鼠标拷贝粘贴输入。

    d)        对于统计查询功能的查询结果应验证其是否只能通过界面上的查询或刷新按键人工触发,应避免其他形式的触发。

    e)        对界面上的任何对象进行拖拉,然后进行查询、打印,应保证查询打印结果不变;

    9.界面测试时,应考虑数据显示的规范性:

    a)        确保数据精度显示的统一:如单价0元,应显示为0.00元;

    b)        确保时间及日期显示格式的统一;

    c)        确保相同含义属性/字段名的统一;

         d)        对所有可能产生的提示信息界面内容和位置进行验证,确保所有的提示信息界面应居中。
261/212>

我的存档

数据统计

  • 访问量: 10059
  • 日志数: 28
  • 图片数: 1
  • 建立时间: 2007-09-11
  • 更新时间: 2007-09-14

RSS订阅

Open Toolbar