我的地盘我做主! 博客:http://tester2test.cnblogs.com/   msn:win_soft@163.com

发布新日志

  • LoadRunner中添加weblogic监视器(JMX)

    2007-04-09 07:27:14

                                     作者:jimmytest

    LR8.0+weblogic7.1

    1。拷贝weblogic安装目录的lib文件夹下的weblogic.jar到LR根目录classer文件夹下;

    2。删除该文件夹下的jmxri.jar

    3.在LR的dat/monitors下的weblogiMon.ini中JVM的路径和版本,指向当前系统的最新虚拟机,推荐1.4.2

    在LR8.1和7.8的帮助中关于JVM的路径设置中的文字的最后缺少了一个下引号。算是一个bug;

    4.在weblogic控制台的安全性的user处新建一个user,name设置为weblogic.admin.mbeam,密码随便设置;

    5。将当前用户的group根据需要添加;

    6。LR中添加监视器,name写上IP:端口。如192.168.1.127:7001

    7.确认后输入之前在console中新建的用户名和密码,确认后就可以打开BEA的监视器选择界面了。

    Pass。

    根据需要选择监视器吧。。。。



    测试者家园 2006-10-22 21:27 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/10/22/536675.html
  • 老外写的一个测试用例

    2007-04-09 07:27:14

     

    Test case example:

    Test Case ID: CUST.01

    Function: Add a new Customer

    Data Assumptions: Customer database has been restored

    General Description:

    Add a new customer, via the Customer Add screen, and validate that new Customer was displayed corrected on the All Customer Screen.

    Action

    Initial State or Screen

    Data

    Expected Results

    (Response)

    1. Bring up Sales application via the Windows Icon

    Program Manager

    None

    Main Sales Application Menu displayed

     

    2. From Views Menu Select Customer.

    Main Sales Screen

    None

    Customer Views Screen Displayed.

     

    3. Click on All Customers

    Customer View

    None

    Customer window is displayed with title "All Customers".

    4. Click on Add Button

    Customer - All Customer

    None

    Add Customer Screen is displayed.

     

    5. Enter data to add a new customer and single click the add button.

    Add Customer

    Name: John Doe

    Addr: 123 Main st.

    City: San Francisco

    (Or refer to data sheet:

    Data Sheet - #105)

    Data display in indicated fields.

     

    (Or: as defined by data sheet.)

    Benefits:

    1. Easier to automated - all have same structure

    2. Data requirements are clearly defined

    3. Navigation is precise

    4. Expected results for each action is specific - no guess work involved

     



    测试者家园 2006-10-23 11:13 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/10/23/537087.html
  • winrunner事务概念的代码应用(毫秒级)

    2007-04-09 07:27:14

  • 牛人是怎样用函数实现本地化测试的

    2007-04-09 07:27:14

    通过几个函数就可以对软件本地化进行测试,真牛,佩服!




    ############################################################
    # Function:
    #       translate_get_value()
    #
    # Description:
    #       Looks up a given value and gets the translated value.
    #
    # Parameters:
    #       translate_from - What to translate from (column heading 1)
    #       translate_to - What to translate to (column heading 2)
    #       from_value - Value to translated
    #       to_value - Translated value
    #
    # Returns:
    #       0 on success, or standard WinRunner error code on failure.
    #       
    # Syntax:
    #       rc = translate_get_value(in translate_from, in translate_to, in from_value, out to_value);
    #
    # Examples:
    # pause(translate_get_value("English", "Spanish", "Yes", value) &" " & value);
    # pause(translate_get_value("Spanish", "English", "Uno", value) & " " & value);
    ############################################################
    function translate_get_value(in translate_from, in translate_to, in from_value, out to_value)
    {
            auto rc;                       #Used to store the return code
            auto table;            #Used to store the translation table
            auto temp_value;       #Used to read the from_value from translation table
     
            # Set the value for the translation table, and open it
            table = getvar("testname") & "\\default.xls";
            rc = ddt_open (table);
            if (rc != E_OK)
            {
                   to_value = "ERROR: Table could not be opened!";
                   return (rc);
            }
     
            # Check to see if the translate_from is a column in the transation table
            rc=ddt_is_parameter(table, translate_from);
            if (rc!=E_OK)
            {
                   to_value = "ERROR: Invalid column header [" & translate_from & "]!";
                   ddt_close(table);
                   return (rc);
            }
     
            # Check to see if the translation_to is a column in the transation table
            rc=ddt_is_parameter(table, translate_to);
            if (rc!=E_OK)
            {
                   to_value = "ERROR: Invalid column header [" & translate_to & "]!";
                   ddt_close(table);
                   return (rc);
            }
     
            # Assume that the from_value is not found
            to_value = "ERROR: Value is not found [" & from_value & "]!";
            rc = E_STR_NOT_FOUND;
     
            # Search the translation table for the from_value
            do
            {
                   temp_value=ddt_val(table,translate_from);
                   if (temp_value == from_value)
                   {
                           # Return the translated value
                           to_value=ddt_val(table, translate_to);
                           rc = E_OK;                     
                   }
            } while (ddt_next_row(table)==E_OK);
     
            # Close the translation table and exit
            ddt_close(table);
            return (rc);
    }
     
    ############################################################
    # Function:
    #       translate()
    #
    # Description:
    #       Returns the translated value given a lookup value.
    #
    # Parameters:
    #       translate_from - What to translate from (column heading 1)
    #       translate_to - What to translate to (column heading 2)
    #       from_value - Value to translated
    #
    # Returns:
    #       translated value, or empty string on error.
    #       
    # Syntax:
    #       rc = translate(in translate_from, in translate_to, in from_value);
    #
    # Examples:
    # pause(translate("English", "Spanish", "Yes"));
    # pause(translate("Spanish", "English", "Uno"));
    ############################################################
    function translate(in translate_from, in translate_to, in from_value)
    {
            auto to_value;
            auto rc;
     
            rc = translate_get_value(translate_from, translate_to, from_value, to_value);
     
            if (rc == E_OK) 
                   return (to_value);
            else
                   return ("");
    }
            
     


    测试者家园 2006-10-26 12:18 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/10/26/540517.html
  • LoadRunner监视的性能计数器

    2007-04-09 07:27:14

     

    LoadRunner监视的性能计数器

    来自http://www.51testing.com论坛 作者不祥

    大家好,今后,我们将以专题的方式展开对LR监视的性能计数器及LR的场景设计设计的讨论,欢迎大家涌跃发言。
    今天,我先把我整理的一些计数器及其阈值要求等贴出来,这些计数器是针对我对windows操作系统,C/S结构的sql server数据库及WEB平台.net产品测试时的一些计数器;大家可以继续补充,作过unix平台上oracle数据库测试及J2EE架构及WEBLOGIC方面测试的朋友,也希望把自己使用的计数器贴出来,让大家分享。
    好了,先说这些了,希望通过这个专题,最终能让大家对自己的测试结果进行分析。

    Memory: 内存使用情况可能是系统性能中最重要的因素。如果系统页交换频繁,说明内存不足。页交换是使用称为页面的单位,将固定大小的代码和数据块从 RAM 移动到磁盘的过程,其目的是为了释放内存空间。尽管某些页交换使 Windows 2000 能够使用比实际更多的内存,也是可以接受的,但频繁的页交换将降低系统性能。减少页交换将显著提高系统响应速度。要监视内存不足的状况,请从以下的对象计数器开始:
    Available Mbytes:
    可用物理内存数. 如果Available Mbytes的值很小(4 MB 或更小),则说明计算机上总的内存可能不足,或某程序没有释放内存。


    page/sec: 表明由于硬件页面错误而从磁盘取出的页面数,或由于页面错误而写入磁盘以释放工作集空间的页面数。一般如果pages/sec持续高于几百,那么您应该进一步研究页交换活动。有可能需要增加内存,以减少换页的需求(你可以把这个数字乘以4k就得到由此引起的硬盘数据流量)。Pages/sec 的值很大不一定表明内存有问题,而可能是运行使用内存映射文件的程序所致。


    page read/sec:页的硬故障,page/sec的子集,为了解析对内存的引用,必须读取页文件的次数。阈值为>5. 越低越好。大数值表示磁盘读而不是缓存读。
    由于过多的页交换要使用大量的硬盘空间,因此有可能将导致将页交换内存不足与导致页交换的磁盘瓶径混淆。因此,在研究内存不足不太明显的页交换的原因时,您必须跟踪如下的磁盘使用情况计数器和内存计数器:
    Physical Disk\ % Disk Time
    Physical Disk\ Avg.Disk Queue Length
    例如,包括 Page Reads/sec % Disk Time Avg.Disk Queue Length。如果页面读取操作速率很低,同时 % Disk Time Avg.Disk Queue Length的值很高,则可能有磁盘瓶径。但是,如果队列长度增加的同时页面读取速率并未降低,则内存不足。
    要确定过多的页交换对磁盘活动的影响,请将 Physical Disk\ Avg.Disk sec/Transfer Memory\ Pages/sec 计数器的值增大数倍。如果这些计数器的计数结果超过了 0.1,那么页交换将花费百分之十以上的磁盘访问时间。如果长时间发生这种情况,那么您可能需要更多的内存。


    Page Faults/sec:每秒软性页面失效的数目(包括有些可以直接在内存中满足而有些需要从硬盘读取)较page/sec只表明数据不能在内存的指定工作集中立即使用。
    Cache Bytes
    :文件系统缓存(File System Cache),默认情况下为50%的可用物理内存。如IIS5.0 运行内存不够时,它会自动整理缓存。需要关注该计数器的趋势变化
    如果您怀疑有内存泄露,请监视 Memory\ Available Bytes Memory\ Committed Bytes,以观察内存行为,并监视您认为可能在泄露内存的进程的 Process\Private BytesProcess\Working Set Process\Handle Count。如果您怀疑是内核模式进程导致了泄露,则还应该监视 Memory\Pool Nonpaged BytesMemory\ Pool Nonpaged Allocs Process(process_name)\ Pool Nonpaged Bytes


    Pages per second :每秒钟检索的页数。该数字应少于每秒一页。

    Process
    %Processor Time:
    被处理器消耗的处理器时间数量。如果服务器专用于sql server,可接受的最大上限是80-85%
    Page Faults/sec:
    将进程产生的页故障与系统产生的相比较,以判断这个进程对系统页故障产生的影响。
    Work set:
    处理线程最近使用的内存页,反映了每一个进程使用的内存页的数量。如果服务器有足够的空闲内存,页就会被留在工作集中,当自由内存少于一个特定的阈值时,页就会被清除出工作集。
    Inetinfo:Private Bytes:
    此进程所分配的无法与其它进程共享的当前字节数量。如果系统性能随着时间而降低,则此计数器可以是内存泄漏的最佳指示器。

    Processor监视处理器系统对象计数器可以提供关于处理器使用的有价值的信息,帮助您决定是否存在瓶颈。
    %Processor Time:
    如果该值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。
    %User Time:
    表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。
    %Privileged Time
    :(CPU内核时间)是在特权模式下处理线程执行代码所花时间的百分比。如果该参数值和"Physical Disk"参数值一直很高,表明I/O有问题。可考虑更换更快的硬盘系统。另外设置Tempdb in RAM,减低"max async IO""max lazy writer IO"等措施都会降低该值。
    此外,跟踪计算机的服务器工作队列当前长度的 Server Work Queues\ Queue Length 计数器会显示出处理器瓶颈。队列长度持续大于 4 则表示可能出现处理器拥塞。此计数器是特定时间的值,而不是一段时间的平均值。
    % DPC Time:
    越低越好。在多处理器系统中,如果这个值大于50%并且Processor:% Processor Time非常高,加入一个网卡可能会提高性能,提供的网络已经不饱和。

    Thread
    ContextSwitches/sec: (
    实例化inetinfo dllhost 进程) 如果你决定要增加线程字节池的大小,你应该监视这三个计数器(包括上面的一个)。增加线程数可能会增加上下文切换次数,这样性能不会上升反而会下降。如果十个实例的上下文切换值非常高,就应该减小线程字节池的大小。

    Physical Disk:
    %Disk Time %:
    指所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。如果三个计数器都比较大,那么硬盘不是瓶颈。如果只有%Disk Time比较大,另外两个都比较适中,硬盘可能会是瓶颈。在记录该计数器之前,请在Windows 2000 的命令行窗口中运行diskperf -yD。若数值持续超过80%,则可能是内存泄漏。
    Avg.Disk Queue Length:
    指读取和写入请求(为所选磁盘在实例间隔中列队的)的平均数。该值应不超过磁盘数的1.5~2 倍。要提高性能,可增加磁盘。注意:一个Raid Disk实际有多个磁盘。
    Average Disk Read/Write Queue Length:
    指读取(写入)请求(列队)的平均数。
    Disk Reads(Writes)/s:
    物理磁盘上每秒钟磁盘读、写的次数。两者相加,应小于磁盘设备最大容量。
    Average Disksec/Read:
    指以秒计算的在此盘上读取数据的所需平均时间。
    Average Disk sec/Transfer:
    指以秒计算的在此盘上写入数据的所需平均时间。
    Network Interface

    Bytes Total/sec :
    为发送和接收字节的速率,包括帧字符在内。判断网络连接速度是否是瓶颈,可以用该计数器的值和目前网络的带宽比较

    SQLServer性能计数器:
    Access Methods(
    访问方法) 用于监视访问数据库中的逻辑页的方法。
    . Full Scans/sec(
    全表扫描/) 每秒不受限的完全扫描数。可以是基本表扫描或全索引扫描。如果这个计数器显示的值比12高,应该分析你的查询以确定是否确实需要全表扫描,以及S Q L查询是否可以被优化。
    . Page splits/sec(
    页分割/)由于数据更新操作引起的每秒页分割的数量。
    Buffer Manager(
    缓冲器管理器):监视 Microsoft® SQL Server? 如何使用: 内存存储数据页、内部数据结构和过程高速缓存;计数器在 SQL Server 从磁盘读取数据库页和将数据库页写入磁盘时监视物理 I/O 监视 SQL Server 所使用的内存和计数器有助于确定: 是否由于缺少可用物理内存存储高速缓存中经常访问的数据而导致瓶颈存在。如果是这样,SQL Server 必须从磁盘检索数据。 是否可通过添加更多内存或使更多内存可用于数据高速缓存或 SQL Server 内部结构来提高查询性能。
    SQL Server
    需要从磁盘读取数据的频率。与其它操作相比,例如内存访问,物理 I/O 会耗费大量时间。尽可能减少物理 I/O 可以提高查询性能。
    .Page Reads/sec
    :每秒发出的物理数据库页读取数。这一统计信息显示的是在所有数据库间的物理页读取总数。由于物理 I/O 的开销大,可以通过使用更大的数据高速缓存、智能索引、更高效的查询或者改变数据库设计等方法,使开销减到最小。
    .Page Writes/sec (.
    写的页/) 每秒执行的物理数据库写的页数。
    .Buffer Cache Hit Ratio.
    缓冲池Buffer Cache/Buffer Pool)中没有被读过的页占整个缓冲池中所有页的比率。可在高速缓存中找到而不需要从磁盘中读取的页的百分比。这一比率是高速缓存命中总数除以自 SQL Server 实例启动后对高速缓存的查找总数。经过很长时间后,这一比率的变化很小。由于从高速缓存中读数据比从磁盘中读数据的开销要小得多,一般希望这一数值高一些。通常,可以通过增加 SQL Server 可用的内存数量来提高高速缓存命中率。计数器值依应用程序而定,但比率最好为90% 或更高。增加内存直到这一数值持续高于90%,表示90% 以上的数据请求可以从数据缓冲区中获得所需数据。
    . Lazy Writes/sec(
    惰性写/)惰性写进程每秒写的缓冲区的数量。值最好为0
    Cache Manager(
    高速缓存管理器) 对象提供计数器,用于监视 Microsoft® SQL Server? 如何使用内存存储对象,如存储过程、特殊和准备好的 Transact-SQL 语句以及触发器。
    . Cache Hit Ratio(
    高速缓存命中率,所有Cache”的命中率。在SQL Server中,Cache可以包括Log CacheBuffer Cache以及Procedure Cache,是一个总体的比率。) 高速缓存命中次数和查找次数的比率。对于查看SQL Server高速缓存对于你的系统如何有效,这是一个非常好的计数器。如果这个值很低,持续低于80%,就需要增加更多的内存。
    Latches(
    ) 用于监视称为闩锁的内部 SQL Server 资源锁。监视闩锁以明确用户活动和资源使用情况,有助于查明性能瓶颈。
    . Average Latch Wait Ti m e ( m s ) (
    平均闩等待时间(毫秒)) 一个SQL Server线程必须等待一个闩的平均时间,以毫秒为单位。如果这个值很高,你可能正经历严重的竞争问题。
    . Latch Waits/sec (
    闩等待/) 在闩上每秒的等待数量。如果这个值很高,表明你正经历对资源的大量竞争。
    Locks(
    ) 提供有关个别资源类型上的 SQL Server 锁的信息。锁加在 SQL Server 资源上(如在一个事务中进行的行读取或修改),以防止多个事务并发使用资源。例如,如果一个排它 (X) 锁被一个事务加在某一表的某一行上,在这个锁被释放前,其它事务都不可以修改这一行。尽可能少使用锁可提高并发性,从而改善性能。可以同时监视 Locks 对象的多个实例,每个实例代表一个资源类型上的一个锁。
    . Number of Deadlocks/sec(
    死锁的数量/) 导致死锁的锁请求的数量
    . Average Wait Time(ms) (
    平均等待时间(毫秒)) 线程等待某种类型的锁的平均等待时间
    . Lock Requests/sec(
    锁请求/) 每秒钟某种类型的锁请求的数量。
    Memory manager:
    用于监视总体的服务器内存使用情况,以估计用户活动和资源使用,有助于查明性能瓶颈。监视 SQL Server 实例所使用的内存有助于确定:
    是否由于缺少可用物理内存存储高速缓存中经常访问的数据而导致瓶颈存在。如果是这样,SQL Server 必须从磁盘检索数据。
    是否可以通过添加更多内存或使更多内存可用于数据高速缓存或 SQL Server 内部结构来提高查询性能。
    Lock blocks:
    服务器上锁定块的数量,锁是在页、行或者表这样的资源上。不希望看到一个增长的值。
    Total server memory
    sql server服务器当前正在使用的动态内存总量.

    监视IIS需要的一些计数器
    Internet Information Services Global:
    File Cache Hits %
    File CacheFlushesFile Cache Hits
    File Cache Hits %
    是全部缓存请求中缓存命中次数所占的比例,反映了IIS 的文件缓存设置的工作情况。对于一个大部分是静态网页组成的网站,该值应该保持在80%左右。而File Cache Hits是文件缓存命中的具体值,File CacheFlushes 是自服务器启动之后文件缓存刷新次数,如果刷新太慢,会浪费内存;如果刷新太快,缓存中的对象会太频繁的丢弃生成,起不到缓存的作用。通过比较File Cache Hits File Cache Flushes 可得出缓存命中率对缓存清空率的比率。通过观察它两个的值,可以得到一个适当的刷新值(参考IIS 的设置ObjectTTL MemCacheSize MaxCacheFileSize
    Web Service:
    Bytes Total/sec:
    显示Web服务器发送和接受的总字节数。低数值表明该IIS正在以较低的速度进行数据传输。
    Connection Refused
    :数值越低越好。高数值表明网络适配器或处理器存在瓶颈。
    Not Found Errors
    :显示由于被请求文件无法找到而无法由服务器满足的请求数(HTTP状态代码404

     



    测试者家园 2006-10-30 11:13 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/10/30/544273.html
  • Why Visual Studio Team System Isn't A LoadRunner Killer[转载]

    2007-04-09 07:27:14

    Why Visual Studio Team System Isn't A LoadRunner Killer

    by Scott Moore
    Loadtester Incorporated
    04/14/2006


    Microsoft recently posted a job for a performance engineer, and I happened to see it. It started off with the question, "Do you have experience with any of the common performance testing applications such as LoadRunner and OcraCoke?" I thought, "huh?". For those of you not familiar with OcraCoke, that was the pre-launch code name for Visual Studio Team System. This peaked my interest further. I was interested in VSTS because several people have been asking me if I think Microsoft has come up with a "LoadRunner killer". I attended a meeting held at  a Microsoft facility and watched VSTS demonstrated. I can say without a doubt, this is NOT a LoadRunner killer. I can't see that it ever will be. Microsoft is has created a competitive product for specific cases. They are offering VSTS as an alternative to the "500 pound gorillas" load testing products. Did I mention that their license model allows unlimited virtual users? When you buy the license, its per CPU. This means as many virtual users as your server can run for one price. So why am I so confident that we won't see a mass move to this product by the Global 2000 companies in the US?

    VSTS is really made with a developer's frame of reference in mind, using Visual Studio's interface to build scripts and run tests. The LAST person I want running an integrated test on a huge project is the developer. They should performance test their code components and the code layer of the product. They should engineer performance into their widgets via unit performance testing, but I don't want them touching a system right before it goes live. Why? They have a skewed view of the testing and cannot remain neutral. Developers are only worried about their code. If they cannot figure out how to optimize their code, they will throw hardware at it before spending the time to rewrite. I've seen it time and time again. Since it's usually their neck on the line if the product gets delayed due to defects (whether quality or performance related), how many developers are going to resist the temptation to tell the CIO that they found a performance issue in the code and the product roll out needs to be delayed two more weeks? How many developers want to expose themselves or their team to the client stakeholders as the originators of the performance defects. This is why a performance engineer who is a third party needs to do this. It should be a QUALIFIED engineer who can get into the guts of the system, and who doesn't have political ties to the development staff, including reporting to the same manager. I prefer a person who represents production because that's who is going to end up with the final result and have to support and maintain it. Most QA teams report to the development manager, which is a mistake. What happens is the QA team is gagged and bound from doing their job because they are seen as holding up the project. That's why having a performance engineer report to the production director gets them out of that jam. I am seeing more and more of this in the market and I like it. On the other hand, we must not forget that performance testing is a discipline of product assurance. Too far the other direction (operations) and you're not looking at code, but CPU counters and bandwidth alone. This is also a mistake.

    The biggest reason VSTS is not the LoadRunner killer is because I don't know of a single Enterprise completely encapsulated in a Microsoft world and totally compatible with a limited set of technology platforms. Once you get away from the Microsoft realm, VSTS loses most of it's potency. In fact, if you are simply using the Firefox or Opera browsers as your standard, you are out of luck. When creating web scripts, the only choices are Internet Explorer or Netscape 6. This can probably be worked around by manually modifying some headers, but that is only the beginning. What happens when you need to move into that gray area between web and "other" application (like Siebel 7.7) where there is more of a challenge because of client stuff to install and it might communicate outside of port 80? How about mySAP? Oracle financials? What if you want to test a legacy application behind Citrix? Microsoft will tell you that they have an additional feature which will allow you to expand to other protocols (and I would assume some gifted MS developers are working on this now). It's a unit testing tool, much like Nunit. The only problem is you need to be a geekazoid wedge head programmer (the kind that you leave a 6-pack of Jolt cola's for outside their door and let them work in the dark) to create the stuff needed to test against these other protocols . I don't know a lot of QA folks out there testing applications with this much time on their hands. They're already overworked and underpaid. And haven't you heard, they are the reason the projects are being held up….?!?!? It is sort of like getting LoadRunner with only the web protocol and the Winsock protocol. Everything that falls outside of pure web, is Winsock. I can hear the groans and feel the anguish even as I type this up.

    The main problem Microsoft will have in developing new protocols is not limited to the technical realm. One of the real strengths Mercury has is the strong relationships at the R&D level with SAP, ORACLE, CITRIX, and others. In fact, SAP and ORACLE have standardized internally on LoadRunner. They have provided Mercury the information they need to "hook" into these custom applications and protocols and spent the last 10 years maturing and expanding these protocols so that the scripting part gets easier with each version. Because of this, you can apply the same testing methodology across projects no matter the application, protocol, or platform. Now let's think about the fact that while its entirely possible that these kinds of protocols can be developed, who's going to bet me that Oracle and SAP are going to play nice with Billy Gates and hand over the hooks into their product? Anyone? Bueller? Bueller?...

    Now that I've spent the entire time whining and standing on my soapbox (again), let me say that I think VSTS has some great qualities. Just the fact that it gets all those developers THINKING about testing is a good thing. The ability to create a simple web script directly in their tool of choice and run a test against their code - this is a VERY good thing. Being able to put a transaction around multiple page returns, adding think time, modifying in a script view, creating parameters, and real time performance monitors are all great things. There are lots of graphs to look at an analyze after the test is completed. If you have a development shop that is COMPLETELY Microsoft centric and you are only messing with web and web services in .NET, then this could be a way for you to validate the performance of your product. It will still take a solid testing methodology to make sure you are truly eliminating the risk of production deployment. That is something Microsoft won't bring to the table either, and best left to folks like us at Loadtester. We'd love to help. On the other hand, I'm not putting away my LoadRunner skills just yet. When Oracle standardizes on VSTS, I'll gladly close my laptop and open a BBQ restaurant….on the beach!!!



    测试者家园 2006-11-23 15:59 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/11/23/569966.html
  • 一段Winrunner的样例脚本

    2007-04-09 07:27:14

    #########################################################################################################
    #
    # Test Name     : Date Boundary
    # Subject          : Open Order Form
    #
    # Description    : Checks that the input of illegal values in the Flight Date is blocked and that error messages
    #    appear.  The following input should be tested:
    #     1. Flight Date Edit field is disabled when button is unchecked
    #     2. Characters (not accepted)
    #     3. More than six numbers (not accepted)
    #     4. Less than six numbers (OK is disabled)
    #     5. Invalid Month
    #     6. Invalid date of the month
    #     7. No entry
    #
    #
    #########################################################################################################

    #static variables:
    static ret_val,date_str,i;
    # Constant declaration
    static const DISABLED = FALSE;

    # Variable declaration.  Can be anything the user wants.
    static date_string_of_chars  = "as/cd/ef";     # Used in STEP 2.  Characters (Not accepted).
    static date_seven_numbers = "12/34/567"; # Used in STEP 3.  More than six numbers not accepted.
    static date_invalid_month    = "13/20/95";   # Used in STEP 5.  Invalid month.
    static date_invalid_day        = "12/32/95";   # Used in STEP 6.  Invalid date of month.

    static lib_path = getvar("testname") & "\\..\\flt_lib";

    # Static function reinitialize ().  Reinitializes Flight Date to OFF and clears the edit field.
    static function reinitialize ()
    {
     auto ret_val;
     set_window ("Open Order");
     obj_get_info ("FlightDateEdit", "enabled", ret_val);
     if (ret_val == TRUE) {
         set_window ("Open Order");
      edit_set_insert_pos ("FlightDateEdit", 0, 0);
      type ("");
     }
    }

    # Static function insert_date ().  Inserts the date into the FlightDateEdit field.
    static function insert_date (in date)
    {
     set_window ("Open Order");
     edit_set_insert_pos("FlightDateEdit",0,0);
     type(date);
    }

    reload(lib_path);

    # Open the flight application
    rc = open_flight();
    if (rc == E_GENERAL_ERROR){
      tl_step(initialization, FAIL,couldnt_open_flight);
     clean_up();
     texit;
    }

     

    # Initialization.
    open_OpenOrderForm ();


    # STEP 1.  Flight Date Edit is disabled

    set_window ("Open Order");

    # Checking to see if the edit field is disabled when button is unchecked
    obj_get_info ("FlightDateEdit", "enabled", ret_val);
    if (ret_val == DISABLED)
     tl_step (disabled, PASS, flight_date_disabled);
    else
     tl_step (disabled, FAIL, flight_date_not_disabled);
    reinitialize ();


    # STEP 2.  Characters (not accepted)

    button_set ("Flight Date", ON);

    # Inserting a date of characters using variable, "date_string_of_chars", defined above.
    insert_date (date_string_of_chars);
    edit_get_text ("FlightDateEdit", date_str);

    # Checking to see if application handled illegal open order procedure
    if (date_str == "__/__/__")
     tl_step (characters, PASS, chars_not_accepted);
    else
     tl_step (characters, FAIL, chars_accepted);
    reinitialize ();

    # STEP 3. More than six numbers (not accepted)

    button_set ("Flight Date", ON);
    # Inserting a date consisting of more than six numbers using variable, "date_seven_numbers", defined above.
    insert_date (date_seven_numbers);
    edit_get_text ("FlightDateEdit", date_str);

    # Checking to see if application handled illegal open order procedure
    if (date_str == "12/34/56")
     tl_step(more_than_six, PASS, more_than_six_not_accepted);
    else
     tl_step(more_than_six, FAIL, more_than_six_accepted);
    reinitialize ();

    # STEP 4. Less than six numbers (OK is disabled)

    edit_set_insert_pos ("FlightDateEdit", 0, 0);

    # Using for_loop to systematically check if OK button is disabled for any date with less than six numbers in it
    for (i = 1; i <= 6; i++) {
     type(i);
     if (button_check_enabled ("OK", TRUE) == E_OK)
      break;

    }

    #  The actual check to make sure that OK was disabled for date less than six numbers
    ts_msg = sprintf(ok_not_disabled, i);
    if (i < 6)
     tl_step (less_than_six, FAIL, ts_msg);
    else
     tl_step (less_than_six, PASS, ok_disabled);
    reinitialize ();

    # STEP 5. Invalid Month

    set_window ("Open Order");
    # Inserting a date with an invalid month using variable, "date_invalid_month", defined above.
    insert_date (date_invalid_month);

    # Checking to verify that unless there is a valid month, an error message will pop up when trying to press "OK"
    set_window("Open Order");
    button_press("OK");
    if(win_exists("Flight Reservation Message",10) != E_OK){
     tl_step (invalid_month, FAIL, invalid_month_msg_popup);
     clear_main_window();
     open_OpenOrderForm ();
    }
    else{
     set_window("Flight Reservation Message");
     static_get_text("Message", txt);
     if(txt !=invalid_month_entered_msg)
      tl_step (invalid_month, FAIL, invalid_month_wrong_msg);
     else
      tl_step (invalid_month, PASS, invalid_month_correct_msg);
     button_press("OK");
    }
    reinitialize ();


    # STEP 6.  Invalid day of month.

    set_window ("Open Order");
    # Inserting a date with an invalid day using variable, "date_invalid_day", defined above.
    insert_date (date_invalid_day);

    # Checking to verify that unless there is a valid day of the month the "OK" button will be disabled
    set_window("Open Order");
    button_press("OK");
    if(win_exists("Flight Reservation Message",10) != E_OK){
     tl_step (invalid_day, FAIL, invalid_day_no_err_msg);
     clear_main_window();
     open_OpenOrderForm ();
    }
    else{
     set_window("Flight Reservation Message");
     static_get_text("Message", txt);
     if(txt !=invalid_day_entered_msg)
      tl_step (invalid_day, FAIL, invalid_day_wrong_err_msg);
     else
      tl_step (invalid_day, PASS, invalid_day_not_accepted);
     button_press("OK");
    }
    reinitialize ();


    # STEP 7.  No Entry.

    set_window ("Open Order");
    # Inserting no date to see if OK is disabled.
    insert_date ("__/__/__");

    # Checking to see if OK is disabled without any date set in edit field
    if (button_check_enabled ("OK", TRUE) != E_OK)
     tl_step (no_entry, PASS, ok_button_disabled);
    else
     tl_step (no_entry, FAIL, ok_button_enabled);


    # Returning to initial state.
    button_press ("Cancel");
    clean_up();


    # End of test.



    测试者家园 2006-12-08 09:24 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/12/08/586031.html
  • 大数据量生成工具源代码(Delphi)

    2007-04-06 09:31:46

    可执行文件存放于:http://bbs.51testing.com/thread-71954-1-1.html

    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, ExtCtrls, shellapi;

    type
      TForm1 = class(TForm)
        pnl1: TPanel;
        edt1: TEdit;
        btn2: TButton;
        btn1: TButton;
        pnl2: TPanel;
        mmo2: TMemo;
        lbl1: TLabel;
        lbl2: TLabel;
        edt2: TEdit;
        ud1: TUpDown;
        lbl3: TLabel;
        edt3: TEdit;
        ud2: TUpDown;
        btn3: TButton;
        btn4: TButton;
        CheckBox1: TCheckBox;
        Memo1: TMemo;
        Button1: TButton;
        Button2: TButton;
        StatusBar1: TStatusBar;
        procedure btn1Click(Sender: TObject);
        procedure btn2Click(Sender: TObject);
        procedure btn3Click(Sender: TObject);
        procedure btn4Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.btn1Click(Sender: TObject);
    begin
      edt1.Clear;
      edt2.Clear;
      edt3.Clear;
    end;

    procedure TForm1.btn2Click(Sender: TObject);
    var
      i: integer;
    begin
      try
        strtoint(edt2.Text);
      except
        application.MessageBox('请输入整数!', '系统信息', 32);
        edt2.SetFocus;
        exit;
      end;

      try
        strtoint(edt3.Text);
      except
        application.MessageBox('请输入整数!', '系统信息', 32);
        edt3.SetFocus;
        exit;
      end;
      mmo2.Lines.Clear;
      if trim(edt2.Text) = '' then edt2.Text := '0';
      if not CheckBox1.Checked then begin
      for i := strtoint(edt2.Text) to strtoint(edt2.Text) + strtoint(edt3.Text) - 1 do
        mmo2.Lines.Add(edt1.Text + inttostr(i));
      end else begin
      for i := strtoint(edt2.Text) to strtoint(edt2.Text) + strtoint(edt3.Text) - 1 do
        mmo2.Lines.Add(edt1.Text);
      end;
      if mmo2.Lines.Count>0 then btn4.Enabled := true else btn4.Enabled := false;
    end;

    procedure TForm1.btn3Click(Sender: TObject);
    begin
      halt;
    end;

    procedure TForm1.btn4Click(Sender: TObject);
    begin
      mmo2.Lines.SaveToFile('c:\test.txt');
      ShellExecute(Handle, 'open', 'c:\test.txt', nil, nil, SW_SHOWNORMAL);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
      i :integer;
    begin
      mmo2.Lines.Clear;
      for i:=0 to memo1.Lines.Count-1 do
        begin
          mmo2.Lines.Add(edt1.Text+memo1.Lines.Strings[i]);
        end;
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    var
      i :integer;
    begin
      mmo2.Lines.Clear;
      for i:=0 to memo1.Lines.Count-1 do
        begin
          mmo2.Lines.Add(memo1.Lines.Strings[i]+edt1.Text);
        end;
    end;

    end.



    测试者家园 2007-04-04 12:52 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/04/04/699598.html
  • 我学员的一个问题及其我对之的解答,关于lr返回值问题

    2007-03-30 11:17:21

     

    问题:

      在创建和录制脚本的时候,发现在脚本vuser_initActionvuser_end三部分,都会有一条“return 0;”语句,那么我们平时在编写脚本时如何应用return语句,return不同的返回值又有什么含义呢?

    问题解答:

    Return标识一个过程的结束,在LoadRunner 中用return 不同的返回值根据脚本不同的返回值,表示脚本的成功或者失败。“return + 大于等于零的数字 ;”表示成功,反之,则表示失败。



    测试者家园 2007-01-24 11:27 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/01/24/628849.html
  • 防电脑辐射小贴士[转载]

    2007-03-30 11:17:21

    使用电脑时,最好在显示器前配备质量较好的防辐射屏。注意酌情多吃一些胡萝卜、豆芽、西红柿、瘦肉、动物肝等富含维生素A、C和蛋白质的食物,经常喝些绿茶等等。

    对于生活紧张而忙碌的人群来说,抵御电脑辐射最简单的办法就是在每天上午喝2至3杯的绿茶,吃一个橘子。茶叶中含有丰富的维生素A原,它被人体吸收后,能迅速转化为维生素A。维生素A不但能合成视紫红质,还能使眼睛在暗光下看东西更清楚,因此,绿茶不但能消除电脑辐射的危害,还能保护和提高视力。如果不习惯喝绿茶,菊花茶同样也能起着抵抗电脑辐射和调节身体功能的作用。

    电脑辐射是不可避免的,但可以减少。首先,应尽可能购买新款的电脑,一般不要使用旧电脑,旧电脑的辐射一般较厉害,在同距离、同类机型的条件下,一般是新电脑的1-2倍。操作电脑时最好在显示屏上安一块电脑专用滤色板以减轻辐射的危害,室内不要放置闲杂金属物品,以免形成电磁波的再次发射。使用电脑时,要调整好屏幕的亮度,一般来说,屏幕亮度越大,电磁辐射越强,反之越小。不过,也不能调得太暗,以免因亮度太小而影响效果,且易造成眼睛疲劳。还要注意与屏幕保持适当距离。离屏幕越近,人体所受的电磁辐射越大,因此较好的是距屏幕半米以外。

    电脑使用后,脸上会吸附不少电磁辐射的颗粒,要及时用清水洗脸,这样将使所受辐射减轻70%以上。

    仙人掌除了可以攻击坏人,还有一项好处喔!据说在计算机桌前放置一仙人掌有助于减少辐射。

    常用电脑的人会感到眼睛不适,视力下降,易有疲劳的感觉。常用电脑的人在饮食上应注意以下几方面:

    吃一些对眼睛有益的食品,如鸡蛋、鱼类、鱼肝油、胡萝卜、菠菜、地瓜、南瓜、枸杞子、菊花、芝麻、萝卜、动物肝脏等。

    多吃含钙质高的食品,如豆制品、骨头汤、鸡蛋、牛奶、瘦肉、虾等。

    注意维生素的补充:多吃含有维生素的新鲜水果、蔬菜等。

    注意增强抵抗力:多吃一些增强机体抗病能力的食物,如香菇、蜂蜜、木耳、海带、柑桔、大枣等。

    吃一些抗辐射的食品:电脑虽然对人体健康影响较小,但也应预防。饮茶能降低辐射的危害,茶叶中的脂多糖有抗辐射的作用。螺旋藻、沙棘油也具有抗辐射的作用。

    另外,用完电脑应洗脸,平时应注意锻炼身体。

    电脑摆放位置很重要。尽量别让屏幕的背面朝着有人的地方,因为电脑辐射最强的是背面,其次为左右两侧,屏幕的正面反而辐射最弱。以能看清楚字为准,至少也要50厘米到75厘米的距离,这样可以减少电磁辐射的伤害。

    注意室内通风:科学研究证实,电脑的荧屏能产生一种叫溴化二苯并呋喃的致癌物质。所以,放置电脑的房间最好能安装换气扇,倘若没有,上网时尤其要注意通风。

    面对电脑时间长了不好,那该怎么办?其实每天四杯茶,不但可以对抗辐射的侵害,还可保护眼睛。

    1.上午一杯绿茶:
    绿茶中含强效的抗氧化剂以及维生素C,不但可以清除体内的自由基,还能分泌出对抗紧张压力的荷尔蒙。绿茶中所含的少量咖啡因可以刺激中枢神经,振奋精神。不过最好在白天饮用,以免影响睡眠。

    2.下午一杯菊花茶:
    菊花有明目清肝的作用,有些人就干脆用菊花加上枸杞一起泡来喝,或是在菊花茶中加入蜂蜜,都对解郁有帮助。
    3.疲劳了一杯枸杞茶:
    枸杞子含有丰富的β胡萝卜素、维生素B1、维生素C、钙、铁,具有补肝、益肾、明目的作用。其本身具有甜味,可以泡茶也可以像葡萄干一样作零食,对解决“电脑族”眼睛涩、疲劳都有功效。
    4.晚间一杯决明茶:
    决明子有清热、明目、补脑髓、镇肝气、益筋骨的作用,若有便秘的人还可以在晚餐饭后饮用,对於治疗便秘很有效果。

    还有些最适合计算机族喝的茶饮,或是点心,不但可以帮您对抗辐射的侵害,还可保护您的眼睛,抗烦躁呢。

    绿豆薏仁汤
    绿豆可以清热解毒、利尿消肿,薏仁则可以健脾止泻,轻身益气,对於经常需要熬夜工作者或是心烦气躁、口乾舌燥、便秘、长青春痘时,除了多吃蔬菜水果与补充水份外,把绿豆薏仁汤当点心食用,对於消暑除烦非常有帮助。

    杜仲茶
    杜仲具有补血与强壮筋骨的作用,对於经常久坐,腰虽背痛很有帮助,男女都可以喝,若是女性朋友还可以在生理期的末期与四物汤一起服用。


    测试者家园 2007-02-05 13:43 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/02/05/640620.html
  • 养生之道

    2007-03-30 11:17:21

    晚上 9-11点为免疫系统(淋巴)排毒时间,此段时间应安静或听音乐

    晚间 11-凌晨 1点,肝的排毒,需在熟睡中进行。

    凌晨 1-3点,胆的排毒,亦同。

    凌晨 3-5点,肺的排毒。此即为何咳嗽的人在这段时间咳得最剧烈,因排毒动作已走到肺;不应用止咳药,以免抑制废积物的排除。

    凌晨 5-7点,大肠的排毒,应上厕所排便。

    凌晨 7-9点,小肠大量吸收营养的时段,应吃早餐。疗病者最好早吃,在
    6点半前,养生者在7点半前,不吃早餐者应改变习惯,即使拖到9、 10 点吃都比不吃好。

    半夜至凌晨4点为脊椎造血时段,必须熟睡,不宜熬夜。

    千万劳记:工作不是生活的全部!



    测试者家园 2007-03-07 16:34 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/03/07/666982.html
  • lr8.0脚本应用于VuGen 8.1设置

    2007-03-30 11:17:21

    lr8.0脚本应用于VuGen 8.1设置,需要在Vugen.ini文件中添加

    [Editor]
    OLDEDITOR=1


    测试者家园 2007-03-13 16:08 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/03/13/673234.html
  • 贴张我家养的狗狗们的照片!

    2007-03-30 11:17:21


    呵呵,看大老笨会坐着,小黑狗喜欢吃雪,三只小藏獒玩的还挺开心,你能发现第三只小藏獒在那吗?:)。

    测试者家园 2007-03-16 08:57 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/03/16/676755.html
  • LoadRunner Interview Questions

    2007-03-30 11:17:21

            摘自:网络

    1. What is load testing?

    Ans. Load testing is to test that if the application works fine with the loads that result from large number of simultaneous users, transactions and to determine weather it can handle peak usage periods.

    2. What is Performance testing?

    Ans. Timing for both read and update transactions should be gathered to determine whether system functions are being performed in an acceptable timeframe. This should be done standalone and then in a multi user environment to determine the effect of multiple transactions on the timing of a single transaction.

    3. Explain the Load testing process?

    Ans. Following are the steps involved in the Load testing process:

    Step 1: Planning the test - Here, we develop a clearly defined test plan to ensure the test scenarios we develop will accomplish load-testing objectives.

    Step 2: Creating Vusers - Here, we create Vuser scripts that contain tasks performed by each Vuser, tasks performed by Vusers as a whole, and tasks measured as transactions.

    Step 3: Creating the scenario - scenario describes the events that occur during a testing session. It includes a list of machines, scripts, and Vusers that run during the scenario. We create scenarios using LoadRunner Controller. We can create manual scenarios as well as goal-oriented scenarios. In manual scenarios, we define the number of Vusers, the load generator machines, and percentage of Vusers to be assigned to each script. For web tests, we may create a goal-oriented scenario where we define the goal that our test has to achieve. LoadRunner automatically builds a scenario for us.

    Step 4: Running the scenario - We emulate load on the server by instructing multiple Vusers to perform tasks simultaneously. Before the testing, we set the scenario configuration and scheduling. We can run the entire scenario, Vuser groups, or individual Vusers.

    Step 5: Monitoring the scenario - We monitor scenario execution using the LoadRunner online runtime, transaction, system resource, Web resource, Web server resource, Web application server resource, database server resource, network delay, streaming media resource, firewall server resource, ERP server resource, and Java performance monitors.

    Step 6: Analyzing test results - During scenario execution, LoadRunner records the performance of the application under different loads. We use LoadRunner’s graphs and reports to analyze the application’s performance.

    4. When do you do load and performance Testing?

    Ans. We perform load testing once we are done with interface (GUI) testing. Modern system architectures are large and complex. Whereas single user testing primarily on functionality and user interface of a system component, application testing focuses on performance and reliability of an entire system. For example, a typical application-testing scenario might depict 1000 users logging in simultaneously to a system. This gives rise to issues such as what is the response time of the system, does it crash, will it go with different software applications and platforms, can it hold so many hundreds and thousands of users, etc. This is when we set do load and performance testing.

    5. What are the components of LoadRunner?

    Ans. The components of LoadRunner are The Virtual User Generator, Controller, and the Agent process, LoadRunner Analysis and Monitoring, LoadRunner Books Online.



    测试者家园 2007-03-17 22:47 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/03/17/678553.html
  • C语言应用于LR中-如何得到数组长度(原创)

    2007-03-30 11:17:21

    C语言没有提供获取数组长度的函数,最起码我不知道,所以编写了一个函数取数组的长度,调试成功,大家可以试试。另外也可以用sizeof(a)/4来取得整型数组的长度,因为整型占4个字节。效果相同。

    #include "web_api.h"

    int LenofArray(int *p)
    {
            int length=0;
            for(;*p!='\0';p++)
            length++;
            return length;
    }

    Action()
    {
        int a[]={1,2,3,4,23,234,4543,565,767};
        int m=LenofArray(a);
        lr_output_message("%d",m);
     return 0;
    }



    测试者家园 2007-03-21 13:42 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/03/21/682482.html
  • 要是下次他们放手机时戴了手套怎么办?

    2007-03-30 11:17:21

        我同学在乘坐公交车时突然旁边一个乘客 A大声喧哗,说他手机丢了,并且指正是他旁边的 B偷了, B装出一幅份很无辜的样子,说手机不是我偷的,你记得你自己的手机号码么,你找一个手机打一下,不就知道是谁偷了么。这时 C主动说把手机借给他拨一下他自己的号码,当手机拨通的瞬间,我同学兜里的手机突然响了,我们都很诧异,我同学怎么可能偷手机,但当时很安静,声音确实来自他的口袋,心想这下完了,被人陷害了,百口莫辩啊。

       
    这时丢手机的 A很凶悍的打了我同学一拳,我们心里已经知道他们三个是一伙的,在诈骗,但打也打不过,说也没理。
    我同学没有还手,只是大声的吼到:现在全车人都可以作证,在事情真相没有调查清楚之前你动手打人,我要告你。

       
    这时候我同学非常冷静沉着,从另外一个口袋拿出一张餐巾纸,用餐巾纸包着手机举起来,说:我是北大法律系的,这个手机上没有我指纹,手机不是我偷的,车上有人诈骗,请司机关好车门,我要打 110报警。

       
    不到 5分钟,警察就来了,把我们带到了警察局,我同学涉嫌偷窃,被关了起来,我们只好给我同学的博士导师打电话,出面保释。

       
    导师、学校保卫科科长都来了,问清楚了事情的经过,后来进行指纹验证,结果出来了,手机上有他们三个的指纹,没有我同学的指纹,他们是一个
    诈骗团伙。他们通过把手机偷偷塞到你兜你,然后诬陷你偷手机,从而进行诈骗和勒索。

       
    最后,我同学无罪释放。警察还非常感谢我们帮他们破获了一起团队诈骗案,并不断夸赞我同学智商怎么这么高。
    我同学其实不是北大法律系的,但他的智商的确很高,也很冷静。
    但最大功劳还多亏那张餐巾纸。

       
    现在的小偷不偷手机,改送手机了,神不知鬼不觉。


    测试者家园 2007-03-26 13:06 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/03/26/688271.html
  • 一段Winrunner的样例脚本

    2007-03-13 17:02:00

    #########################################################################################################
    #
    # Test Name     : Date Boundary
    # Subject          : Open Order Form
    #
    # Description    : Checks that the input of illegal values in the Flight Date is blocked and that error messages
    #    appear.  The following input should be tested:
    #     1. Flight Date Edit field is disabled when button is unchecked
    #     2. Characters (not accepted)
    #     3. More than six numbers (not accepted)
    #     4. Less than six numbers (OK is disabled)
    #     5. Invalid Month
    #     6. Invalid date of the month
    #     7. No entry
    #
    #
    #########################################################################################################

    #static variables:
    static ret_val,date_str,i;
    # Constant declaration
    static const DISABLED = FALSE;

    # Variable declaration.  Can be anything the user wants.
    static date_string_of_chars  = "as/cd/ef";     # Used in STEP 2.  Characters (Not accepted).
    static date_seven_numbers = "12/34/567"; # Used in STEP 3.  More than six numbers not accepted.
    static date_invalid_month    = "13/20/95";   # Used in STEP 5.  Invalid month.
    static date_invalid_day        = "12/32/95";   # Used in STEP 6.  Invalid date of month.

    static lib_path = getvar("testname") & "\\..\\flt_lib";

    # Static function reinitialize ().  Reinitializes Flight Date to OFF and clears the edit field.
    static function reinitialize ()
    {
     auto ret_val;
     set_window ("Open Order");
     obj_get_info ("FlightDateEdit", "enabled", ret_val);
     if (ret_val == TRUE) {
         set_window ("Open Order");
      edit_set_insert_pos ("FlightDateEdit", 0, 0);
      type ("");
     }
    }

    # Static function insert_date ().  Inserts the date into the FlightDateEdit field.
    static function insert_date (in date)
    {
     set_window ("Open Order");
     edit_set_insert_pos("FlightDateEdit",0,0);
     type(date);
    }

    reload(lib_path);

    # Open the flight application
    rc = open_flight();
    if (rc == E_GENERAL_ERROR){
      tl_step(initialization, FAIL,couldnt_open_flight);
     clean_up();
     texit;
    }

     

    # Initialization.
    open_OpenOrderForm ();


    # STEP 1.  Flight Date Edit is disabled

    set_window ("Open Order");

    # Checking to see if the edit field is disabled when button is unchecked
    obj_get_info ("FlightDateEdit", "enabled", ret_val);
    if (ret_val == DISABLED)
     tl_step (disabled, PASS, flight_date_disabled);
    else
     tl_step (disabled, FAIL, flight_date_not_disabled);
    reinitialize ();


    # STEP 2.  Characters (not accepted)

    button_set ("Flight Date", ON);

    # Inserting a date of characters using variable, "date_string_of_chars", defined above.
    insert_date (date_string_of_chars);
    edit_get_text ("FlightDateEdit", date_str);

    # Checking to see if application handled illegal open order procedure
    if (date_str == "__/__/__")
     tl_step (characters, PASS, chars_not_accepted);
    else
     tl_step (characters, FAIL, chars_accepted);
    reinitialize ();

    # STEP 3. More than six numbers (not accepted)

    button_set ("Flight Date", ON);
    # Inserting a date consisting of more than six numbers using variable, "date_seven_numbers", defined above.
    insert_date (date_seven_numbers);
    edit_get_text ("FlightDateEdit", date_str);

    # Checking to see if application handled illegal open order procedure
    if (date_str == "12/34/56")
     tl_step(more_than_six, PASS, more_than_six_not_accepted);
    else
     tl_step(more_than_six, FAIL, more_than_six_accepted);
    reinitialize ();

    # STEP 4. Less than six numbers (OK is disabled)

    edit_set_insert_pos ("FlightDateEdit", 0, 0);

    # Using for_loop to systematically check if OK button is disabled for any date with less than six numbers in it
    for (i = 1; i <= 6; i++) {
     type(i);
     if (button_check_enabled ("OK", TRUE) == E_OK)
      break;

    }

    #  The actual check to make sure that OK was disabled for date less than six numbers
    ts_msg = sprintf(ok_not_disabled, i);
    if (i < 6)
     tl_step (less_than_six, FAIL, ts_msg);
    else
     tl_step (less_than_six, PASS, ok_disabled);
    reinitialize ();

    # STEP 5. Invalid Month

    set_window ("Open Order");
    # Inserting a date with an invalid month using variable, "date_invalid_month", defined above.
    insert_date (date_invalid_month);

    # Checking to verify that unless there is a valid month, an error message will pop up when trying to press "OK"
    set_window("Open Order");
    button_press("OK");
    if(win_exists("Flight Reservation Message",10) != E_OK){
     tl_step (invalid_month, FAIL, invalid_month_msg_popup);
     clear_main_window();
     open_OpenOrderForm ();
    }
    else{
     set_window("Flight Reservation Message");
     static_get_text("Message", txt);
     if(txt !=invalid_month_entered_msg)
      tl_step (invalid_month, FAIL, invalid_month_wrong_msg);
     else
      tl_step (invalid_month, PASS, invalid_month_correct_msg);
     button_press("OK");
    }
    reinitialize ();


    # STEP 6.  Invalid day of month.

    set_window ("Open Order");
    # Inserting a date with an invalid day using variable, "date_invalid_day", defined above.
    insert_date (date_invalid_day);

    # Checking to verify that unless there is a valid day of the month the "OK" button will be disabled
    set_window("Open Order");
    button_press("OK");
    if(win_exists("Flight Reservation Message",10) != E_OK){
     tl_step (invalid_day, FAIL, invalid_day_no_err_msg);
     clear_main_window();
     open_OpenOrderForm ();
    }
    else{
     set_window("Flight Reservation Message");
     static_get_text("Message", txt);
     if(txt !=invalid_day_entered_msg)
      tl_step (invalid_day, FAIL, invalid_day_wrong_err_msg);
     else
      tl_step (invalid_day, PASS, invalid_day_not_accepted);
     button_press("OK");
    }
    reinitialize ();


    # STEP 7.  No Entry.

    set_window ("Open Order");
    # Inserting no date to see if OK is disabled.
    insert_date ("__/__/__");

    # Checking to see if OK is disabled without any date set in edit field
    if (button_check_enabled ("OK", TRUE) != E_OK)
     tl_step (no_entry, PASS, ok_button_disabled);
    else
     tl_step (no_entry, FAIL, ok_button_enabled);


    # Returning to initial state.
    button_press ("Cancel");
    clean_up();


    # End of test.



    测试者家园 2006-12-08 09:24 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/12/08/586031.html
  • 详解loadrunner的think time(原创)

    2007-03-13 17:02:00

    lr_start_sub_transaction

    标记子事务的开始

    lr_start_transaction

    记事务的开始

    lr_end_sub_transaction

    标记子事务的结束以便进行性能分析

    lr_end_transaction

    标记 LoadRunner 事务的结束

    思考时间大于阈值时生成: 使用思考时间的阈值。如果录制思考时间小于该阈值,VuGen 将不会生成思考时间语句。您也可以指定阈值。默认值为 3 - 如果思考时间少于 3 秒,VuGen 将不会生成思考时间语句。如果禁用此选项,VuGen 将不会生成任何思考时间。(默认情况下启用)

    脚本

        lr_start_sub_transaction("think time1","t1");

        lr_think_time(10);

        lr_end_sub_transaction("think time1",LR_PASS);

        lr_start_sub_transaction("think time2","t1");

        lr_think_time(10);

        lr_end_sub_transaction("think time2",LR_PASS);

           lr_end_transaction("t1", LR_AUTO);

     

    输出:

     

    Action.c(8): Notify: Transaction "t1" started.

    Action.c(9): Notify: Transaction "think time1" started.

    Action.c(10): lr_think_time: 10.00 seconds.

    Action.c(11): Notify: Transaction "think time1" ended with "Pass" status (Duration: 9.9939 Think Time: 9.9892).

    Action.c(12): Notify: Transaction "think time2" started.

    Action.c(13): lr_think_time: 10.00 seconds.

    Action.c(14): Notify: Transaction "think time2" ended with "Pass" status (Duration: 9.9954 Think Time: 9.9906).

    Action.c(15): Notify: Transaction "t1" ended with "Pass" status (Duration: 19.9994 Think Time: 19.9798).




    测试者家园 2006-12-18 12:31 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2006/12/18/595530.html
  • WebLogic Server 性能调优(转自www.uml.org.cn)

    2007-03-13 17:02:00

    WebLogic Server 性能调优(转自www.uml.org.cn

    http://www.uml.org.cn/j2ee/200612144.htm

     

    任何在市场上成功的产品都拥有良好的性能。虽然成为象WebLogic Server这样广泛使用的产品需要具备很多特性,但性能绝对是必不可少的。

     良好的编程习惯在帮助应用运行方面起了很大的作用,但是仅有它们还是不够的。应用服务器必须能够在多种硬件和操作系统之间移植,必须具备通用性以便处理范围更广的应用类型。这就是为什么应用服务器都提供了丰富的调试“按钮”的原因,通过调整这些“按钮”,能够使服务器更适合运行环境以及应用程序。

    本文针对WebLogic讨论了其中的某些调试参数,不过并未将所有可调整的属性全部列出。此外,在将此处推荐的方法运用到产品环境之前,建议您先在测试环境中对它们测试一番。

    性能监控及瓶颈发现

    性能调试的第一步是孤立“危险区域”。性能瓶颈可以存在于整个系统的任一部分?D?D网络、数据库、客户端或应用服务器。重要的是首先确定哪个系统组件引起了性能问题,调试错了组件可能会使情况更糟。

    WebLogic Server为系统管理员提供了管理控制台和命令行工具两种方式监控系统性能。服务器端有叫作mbean的集合,用于搜集诸如线程消耗情况、资源剩余情况、缓存使用情况等信息。控制台和命令行管理器都可以从服务器将这些信息调用出来。图1的屏幕快照就显示了EJB容器中缓存的使用和剩余情况,这是控制台提供的性能监控的选项之一。

    代码分析器也是应用代码用以探测自身性能瓶颈的另一种有效的工具。有几个很好的代码分析器,如:Wily Introscope, Jprobe, Optimizelt。

    EJB 容器

    EJB容器中最昂贵的操作当然是数据库调用?D?D装载和存储实体bean。容器也因此提供了各种各样的参数以便减少数据库的访问次数。但不管怎样,除非是在特殊情况下,否则在每个bean的每次交易中,至少都得有一次装载操作和一次存储操作。这些特殊情况是:

     1. Bean是只读的。此时,bean只需在第一次访问时装载一次,从来不需要存储操作。当然,如果超出参数read-timeout-seconds的设置,bean将被再次装载。

    2. Bean 有专门的或积极的并发策略,且参数db-is-shared 设置为假。此参数在WebLogic Server 7.0中被重新命名为cache-between-transactions。参数db-is-shared 设置为假相当于参数cache-between-transactions设置为真。

    3. Bean在交易中未被修改过,此时,容器会将存储操作优化掉。

    如果不属于上述任何一种情况,则code path中的每个实体bean在每次交易时,至少会被装载和存储一次。有些特征能够减少数据库的调用或者降低数据库调用的开销,如:高速缓存技术、域(field)分组、并发策略以及紧密关联缓存(eager relationship caching)等,其中的某些特征是WebLogic Server 7.0新增的。

     高速缓存:实体bean缓存空间的大小由weblogic-ejb-jar.xml中的参数max-beans-in-cache定义。容器在交易中第一次装载bean时是从数据库调用的,此时bean也被放在缓存中。如果缓存的空间太小,有些bean就被滞留在数据库中。这样,如果不考虑前面提到的前两种特殊情况的话,这些bean在下次调用时就必须重新从数据库装载。从缓存调用bean也意味着此时不必调用setEntityContext()。如果bean的关键(主)键是组合域或者比较复杂,也能省却设置它们的时间。

    域分组:域分组是对于查找方法指定从数据库加载的域。如果实体bean与一个较大的BLOB域(比方说,一幅图像)相联系,且很少被访问,则可以定义一个将此域排除在外的域组,该域组与一个查找方法相关联,这样查找时,BLOB域即不会被装载。这种特征只对EJB2.0的bean 适用。

    并发策略:在WebLogic Server 7.0中,容器提供了四种并发控制机制。它们是独占式、数据库式、积极式和只读式。并发策略与交易进行时的隔离级别紧密相关。并发控制并不是真正意义上的提高性能的措施,它的主要目的是确保实体bean所表示的数据的一致性,该一致性由bean的部署器所强制要求。无论如何,某些控制机制使得容器处理请求的速度比其它的要快一些,但这种快速是以牺牲数据的一致性为代价的。

     最严格的并发策略是独占式,利用特殊主键对bean的访问是经过系列化的,因此每次只能有一个交易对bean进行访问。这虽然在容器内提供了很好的并发控制,但性能受到限制。在交易之间允许互为缓存的时候,这种方法很有用,但在集群环境中不能使用,此时,装载操作被优化掉,因此可能导致丧失并行性。

    数据库式的并发策略不同于数据库的并发控制。实体bean在容器中并未被锁定,允许多个交易对相同的实体bean并发操作,因此能够提高性能。当然,这样对隔离的级别也许要求较高,以便确保数据的一致性。

    积极式并发策略与数据库的并发控制也不同。不同之处在于对数据一致性的检查发生在对已设定的更新操作进行存储时而非在装载时将整行锁定。如果应用内对同一个bean访问的冲突不是很激烈的情况下,本策略比数据库式的策略要快一些,虽然两个提供了相同的数据一致性保护级别。但是在有冲突发生的时候,本策略要求调用者要重新发起调用。本特征也只对EJB 2.0 适用。

    只读式策略只能用于只读bean。Bean只在应用第一次访问时或者超出参数read-timeout-seconds所指定的值时才被装载。Bean从来不需要被存储。当基本数据改变时,也会通过read-mostly格式通知bean,从而引起重新装载。

    紧密关联缓存: 如果两个实体bean, bean A 和bean B 在CMR(容器关系管理)内关联,两个在同一个交易中被访问,且由同样的数据库调用装载,我们称为紧密关联缓存。这是WebLogic Server 7.0的新特征,同样只适用于EJB2.0。

    除了上面列出的通过优化容器内对数据库的访问从而达到性能增加的特征外,另有一些在容器之外,针对会话bean和实体bean的参数能够帮助提升性能。

    缓冲池和高速缓存是EJB容器为提高会话bean和实体bean性能所提供的主要特征。然而,这些方法并非对所有类型的bean适用。它们的消极面是对内存要求较高,虽然这不是主要的问题。缓冲池适用于无状态会话bean(SLSB),消息驱动bean(MDB)以及实体bean。一旦为SLSB和MDB设定了缓冲池的大小,这些bean的许多实例就会被创建并被放到缓冲池中,setSessionContext()/setMessageDriveContext()方法会被调用。为这些bean设置的缓冲池的大小不必超过所配置的执行线程数(事实上,要求比此数要小)。如果方法setSessionContext()要做任何开销昂贵的操作的话,此时JNDI查询已经完成,使用缓冲池中的实例方法调用将会加快速度。对实体bean来说,在完成setEntityContext()方法调用之后,缓冲池与bean的匿名实例相连(没有主键)。这些实例可以被查询操作所使用,查询方法从缓冲池中取出一个实例,为其指定一个主键,然后从数据库中装载相应的bean。

    高速缓存适用于有状态会话bean(SFSB)和实体bean。实体bean已经在前面讨论过。对于SFSB,缓存能够避免向硬盘串行化的操作。串行化到硬盘的操作非常昂贵,绝对应该避免。用于SFSB的缓存大小可以比连接到服务器的并发客户端数略微大些,这是由于仅当缓存被占用了85%以后,容器才会设法将bean滞留在数据库中待命。如果缓存大于实际所需,则容器不会通过缓存花费时间将bean待命。

    EJB容器提供了两种方法进行bean-to-bean 和 Web-tier-to-bean的调用操作:传值调用和传送地址调用。如果bean处在同一个应用之中,则缺省情况下,用的是传送地址的方法,这比传值要快一些。传送地址的方法一般不应被禁止,除非有充足的理由要强制这样做。强制使用传送地址的另一种做法是使用本地接口。在WebLogic Server 7.0中引入了另一个特征是对有状态服务使用激活(activation)。虽然这种做法在某种程度上影响了性能,但由于对内存要求较低,因此极大地改进了扩展性。如果扩展性不值得关注,可以将参数noObjectAction传送给ejbc从而关闭激活(activation)。

    JDBC

    对数据库的访问来说,调试JDBC与调试EJB容器同样重要。比方说设置连接池的大小?D?D连接池应大到足以容纳所有线程对连接的要求。如果所有对数据库的访问能够在缺省的执行队列中得以实现,则连接数应为执行队列中的线程数,比读取socket的线程(缺省执行队列中用来读取进入请求的线程)数要少。为了避免在运行期间对连接进行创建和删除,可在初始时即将连接池设置为其最大容量。如果可能的话,应确保参数TestConnectionsOnReserve被设置为假(false,这是缺省设置)。如果此参数设置为真(true),则在连接被分配给调用者之前,都要经过测试,这会额外要求与数据库的反复连接。

    另一个重要的参数是PreparedStatementCacheSize。每个连接都为宏语句设一个静态的缓存,大小由JDBC连接池配置时指定。缓存是静态的,时刻牢记这一点非常重要。这意味着如果缓存的大小是n的话,则只有放在缓存中的前n条语句得到执行。确保昂贵的SQL语句享受到缓存的方法是用一个启动类将这些语句存放到缓存中。尽管缓存技术从很大程度上改进了性能,但也不能盲目使用它。如果数据库的格式有了变化,那么在不重新启动服务器的情况下,无法使缓存中的语句失效或者是用新的进行替换。当然,缓存中的语句会使数据库中的光标得以保留。

    对于WebLogic Server 7.0来说,由于jDriver性能的改进已使其速度远远快于Oracle的?C驱动程序,尤其对于要完成大量SELECT操作的应用来说就更是如此。这可以从HP提交的利用WebLogic Server 7.0 Beta版的两份Ecperf结果得到证明(http://ecperf.theserverside.com/ecperf/index.jsp?page=results/top_ten_price_performance)。

    JMS

    JMS子系统提供了很多的调试参数。JMS消息是由称为JMSDispatcher的独立执行队列处理的。因此,JMS子系统既不会由于运行在缺省或者其它执行队列中的应用因争夺资源而导致“营养匮乏”,反过来也不会抢夺其它应用的资源。对JMS来说,大多数的调试参数都是在服务的质量上进行折衷处理。如,利用文件式持续性目的地(file-persistent destnation)禁止同步写操作(通过设置特性: -Dweblogic.JMSFileStore.SynchronousWritesEnabled =false)以后会引起性能急剧提高,但同时也会冒着丢失消息或者重复接收消息的风险。类似地,利用多点传送发送消息会提升性能,同时也会有消息半途丢失的危险。

    消息确认间隔不应设置得过短?D?D发送确认的比率越大,处理消息的速度可能会越慢。同时,如果设置得过大,则意味着系统发生故障时,消息会丢失或者被重复发送。

    一般说来,应在单个服务器上对多个JMS目的地进行配置,而不是将它们分散在多个JMS服务器,除非不再需要扩展。

    关闭消息页面调度(paging)可能会提高性能,但会影响可扩展性。如果打开消息页面调度(paging),则需要额外的I/O操作以便将消息串行化到硬盘,在必要的时候再读进来,但同时也降低了对内存的要求。

    一般来说,异步过程比同步过程更好操作,更易于调节。

    Web容器

    Web层在应用中更多的是用来生成表达逻辑。广泛使用的体系结构是从应用层读取数据,然后使用servlet和JSP生成动态内容,其中应用层一般由EJB组成。在这种结构中,servlet 和JSP保留对EJB的引用,以防它们与数据库或数据源直接对话。将这些引用保存起来是个不错的主意。如果JSP和servlet没有和EJB部署在同一台应用服务器上,则利用JNDI进行查询的费用是很昂贵的。

    JSP缓存标记符可以用于存储JSP页面内的数据。这些标记符都支持对缓存的输入和输出。对缓存的输出涉及到标记符内的代码所生成的内容,对缓存的输入涉及到标记符内的代码对变量的赋值。如果不希望Web层频繁变化,则可以通过将ServletReloadCheckSecs 设置为-1,从而关闭自动装载(auto-reloading)功能。使用这种方法以后,服务器将不再轮询Web层是否有变化,如果JSP和servlet的数量很多,则效果是非常明显的。

    这里也建议不要在HTTP会话中储存过多的信息。如果信息是必须的,可以考虑使用有状态会话bean来替代。

    JVM调试

    如今的大多数JVM具有自主调节功能,因为它们能够探测到代码中的危险区域并对它们进行优化。开发和部署人员能够考虑的调试参数大概就是堆设置了。设置这些并没有一般的规则。JVM一般堆空间,按新空间或保留空间一般设置为整个堆空间的三分之一或一半组织。整个堆空间不能指定得过大以致于无法支持并发的内存垃圾回收(GC)处理。在这种设置环境中,如果堆太大的话,垃圾回收的间隔应设为一分钟或更长。最后,需要引起注意的是这些设置在很大程度上依赖于部署在服务器上的应用使用内存的模式。有关调试JVM的其它信息可以参考:

    http://edocs.bea.com/wls/docs70/perform/JVMTuning.html1104200

    服务器调试

    除了由各个子系统提供的调试参数以外,还有适用于服务器的参数能够帮助提升性能。其中最重要的是配置线程数和执行队列数。增加线程数并非总能奏效,仅当下列情况成立时再考虑使用这种方法:预定的吞吐量没有达到;等待队列(未开始处理的请求)过长;CPU仍有剩余。当然,这样做并不一定能改善性能。CPU使用率低可能是由于对服务器的其它资源竞争所致,如,没有足够的JDBC连接。当改变线程数时应考虑到这些类似的因素。

    在WebLogic Server 7.0中,提供了配置多个执行队列的功能,并且能够在部署中定义处理特殊的EJB或JSP/servlet请求的执行队列。要做到这些,只要在运行weblogic.ejbc时将标志-dispatchPolicy <队列名称> 传送给bean 即可。对于JSP/servlet,可将设置Web应用的weblogic部署描述符中初始化参数(init-param) wl-dispatch-policy的值设为执行队列的名字即可。有时应用中的某些bean/JSP对操作的响应时间比其它的要长,此时,可以对这些bean/JSP设置单独的执行队列。至于队列的大小,要达到最好的性能,还取决于经验。

    另一个比较大的问题是决定在何种情况下应该使用WebLogic性能包(http://e-docs.bea.com/wls/docs70/perform/WLSTuning.html - 1112119)。如果socket数不太多(每个服务器上都有一个socket用于客户端JVM的远程方法调用连接),而且总是忙于读取从客户端发送过来的请求数据,那么此时使用性能包恐怕不会有明显的改进。也有可能不用性能包会导致相似或更好的结果,这取决于JVM在处理网络I/O时的具体实现。

    Socket读取线程取自缺省执行队列。在Windows 环境下,每个CPU有两个socket读取线程,在solaris环境下,共有三个socket用于本地输入输出(native I/O)。对于Java 输入输出(I/O),读取线程数由配置文件config.xml中的参数PercentSocketReaderThreads 进行设置。它的缺省值是33%, 上限是50%,这是显而易见的,因为如果没有线程用于处理请求,则同样不会有更多的读取线程啦。对于Java I/O,应使读取线程数尽量接近客户端连接数,因为在等待请求时,Java I/O会阻塞。这也是为什么当客户端的连接数增加时,线程数不能一直同等增加的原因。

    结论

    我们上面只讨论了调试服务器的部分方法。需要记住的是,一个设计蹩脚,编写欠佳的应用,通常都不会有好的性能表现,无论对服务器及其参数如何调试。贯穿应用开发周期的各个阶段?D?D从设计到部署,性能始终应该是考虑的关键因素。经常发生的情况是性能被放在了功能之后,等到发现了问题再去修改,已经很困难了。有关WebLogic Server 性能调试的其它信息可以参考:http://e-docs.bea.com/wls/docs70/perform/index.html



    测试者家园 2007-01-04 12:39 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/01/04/611225.html
  • 原创:检查点的三种加入方式

    2007-03-13 17:02:00

      前一段时间有个学员问我检查点的集中加入方式,我简单的总结了一下,希望对大家有帮助。

    检查点问题

    前提条件

    ²        必须勾选启动检查点

    使用方法


    图1

    在录制过程中选择要添加为检查点的文字,点选工具条上的红框所示图标(图1),即在脚本中加入了相应的检查点函数(文字检查点),当然你也可以通过菜单项NEW STEP加入文字或者图片检查点(图2),还有一种方式就是根据服务器的响应信息添加检查点(图3),你自己在稍微了解一下图片和文字检查点函数的内容就行了,有问题我们再联系!


    图2

     

    图3



    测试者家园 2007-01-12 09:01 发表评论


    Link URL: http://www.cnblogs.com/tester2test/archive/2007/01/12/618269.html
Open Toolbar