发布新日志

  • 安全测试学习笔记二(对于top 10 漏洞的分析)(转贴)

    yexu 发布于 2007-01-17 08:41:02

    1, 问题:没有被验证的输入

     测试方法:

     数据类型(字符串,整型,实数,等)
     允许的字符集
     
    最小和最大的长度
     是否允许空输入
     参数是否是必须的
     重复是否允许
     数值范围
     特定的值(枚举型)
      特定的模式(正则表达式)

    2, 问题:有问题的访问控制

     测试方法:

     主要用于需要验证用户身份以及权限的页面,复制该页面的url地址,关闭该页面以后,查看是否可以直接进入该复制好的地址
     例:从一个页面链到另一个页面的间隙可以看到URL
    地址
           直接输入该地址,可以看到自己没有权限的页面信息,

    3      错误的认证和会话管理

    分析:帐号列表:系统不应该允许用户浏览到网站所有的帐号,如果必须要一个用户列表,推荐使用某种形式的假名(屏幕名)来指向实际的帐号。

    浏览器缓存:认证和会话数据不应该作为GET的一部分来发送,应该使用POST

    4        问题:跨站脚本(XSS

     分析:攻击者使用跨站脚本来发送恶意代码给没有发觉的用户,窃取他机器上的任意资料

     测试方法:

             HTML标签:<…>…</…> 

             转义字符:&amp(&)&lt(<)&gt(>)&nbsp(空格)

             脚本语言:

          <scrīpt language=‘javascrīpt’>

           …Alert(‘’)

           </scrīpt>

             特殊字符:  ’ <  >  /

             最小和最大的长度

             是否允许空输入

      例:对GridLabelTree view类的输入框未作验证,输入的内容会按照html语法解析出来


    5,缓冲区溢出

    分析:用户使用缓冲区溢出来破坏web应用程序的栈,通过发送特别编写的代码到web程序中,攻击者可以让web应用程序来执行任意代码。

     6,注入式漏洞。
    例:
    一个验证用户登陆的页面,

     如果使用的sql语句为:

     Select *  from  table A where  username’’ + username+’’ and pass word …..

     Sql 输入  or 11 ――  就可以不输入任何password进行攻击
     

     7,不恰当的异常处理

    分析:程序在抛出异常的时候给出了比较详细的内部错误信息,暴露了不应该显示的执行细节,网站存在潜在漏洞,


     8,不安全的存储

    没有加密关键数据

    例:viewsourcehttp地址可以查看源代码

        在页面输入密码,页面显示的是 *****,  右键,查看源文件就可以看见刚才输入的密码,


    9,拒绝服务

    分析:攻击者可以从一个主机产生足够多的流量来耗尽狠多应用程序,最终使程序陷入瘫痪。需要做负载均衡来对付。


     10,不安全的配置管理

    分析:Config中的链接字符串以及用户信息,邮件,数据存储信息都需要加以保护

    程序员应该作的: 配置所有的安全机制,关掉所有不使用的服务,设置角色权限帐号,使用日志和警报。

  • 收集的一些简单的SQL面试题

    aries1979 发布于 2007-05-29 10:56:50

    1. Q. What is a join?
       A. Join is a process of retrieve pieces of data from different sets (tables) and returns them to the user or program as one joined collection of data.

    2. Q. Can a table have more than one foreign key defined?
       A. A table can have any number of foreign keys defined. It can have only
           one primary key defined.

    3. Q. List all the possible values that can be stored in a BOOLEAN data field.
       A. There are only two values that can be stored in a BOOLEAN data field:
             -1(true) and 0(false).
    4.  Q. What is a stored procedure?
        A. A procedure is a group of PL/SQL statements that can be called by
            a name. Procedures do not return values they perform tasks.

    5.  Q. What is Normalization?
        A. The process of table design is called normalization.

    6.  Q. Write a SQL SELECT sample of the concatenation operator.
        A.  SELECT LastName ||',' || FirstName, City FROM Students;

    7. Q. Is the WHERE clause must appear always before the GROUP BY clause in SQL SELECT ?

        A. Yes.
    The proper order for SQL SELECT
    clauses is: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY.
    Only the SELECT and FROM clause are mandatory.

    8. Q. Which operator do you use to return all of the rows
    from one query except rows are returned in a second query?

        A. You use the MINUS operator to return all rows from one query except
    where duplicate rows are found in a second query. The UNION operator
    returns all rows from both queries minus duplicates. The UNION ALL operator
    returns all rows from both queries including duplicates.
    The INTERSECT operator returns only those rows that exist in both queries.

    9. Q. Which of the following statements are Data Manipulation Language commands?
    A. INSERT
    B. UPDATE
    C. GRANT
    D. TRUNCATE
    E. CREATE

        A.  A and B � The INSERT and UPDATE statements are
    Data Manipulation Language (DML) commands.
    GRANT is a Data Control Language (DCL) command.
    TRUNCATE and CREATE are Data Definition Language (DDL) commands

    10.   Q.  Describe some Group Functions that you know
    A. 1) The COUNT function tells you how many rows were in the result set.
          SELECT COUNT(*) FROM TESTING.QA
        2) The AVG function tells you the average value of a numeric column.
           SELECT MAX(SALARY) FROM TESTING.QA
        3) The MAX and MIN functions tell you the maximum and minimum value of a numeric column.
           SELECT MIN(SALARY) FROM TESTING.QA 
         4) The SUM function tells you the sum value of a numeric column.
            SELECT SUM(SALARY) FROM TESTING.QA

  • 2007-01-10 | 软件测试面试题整理

    yeziqingqing 发布于 2009-02-05 22:00:59

     

    面试题目:
    01. 为什么要在一个团队中开展软件测试工作
    因为没有经过测试的软件很难在发布之前知道该软件的质量,就好比ISO质量认证一样,测试同样也需要质量的保证,这个时候就需要在团队中开展软件测试的工作。在测试的过程发现软件中存在的问题,及时让开发人员得知并修改问题,在即将发布时,从测试报告中得出软件的质量情况。


    02. 您在以往的测试工作中都曾经具体从事过哪些工作?其中最擅长哪部分工作?
    我曾经做过web测试,后台测试,客户端软件,其中包括功能测试性能测试,用户体验测试。最擅长的是功能测试


    03. 您所熟悉的软件测试类型都有哪些?请试着分别比较这些不同04. 的测试类型的区别与联系(如功能测试、性能测试……)
    测试类型有:功能测试,性能测试,界面测试。
    功能测试在测试工作中占的比例最大,功能测试也叫黑盒测试。是把测试对象看作一个黑盒子。利用黑盒测试法进行动态测试时,需要测试软件产品的功能,不需测试软件产品的内部结构和处理过程。采用黑盒技术设计测试用例的方法有:等价类划分、边界值分析、错误推测、因果图和综合策略。
    性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。负载测试和压力测试都属于性能测试,两者可以结合进行。通过负载测试,确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。
    界面测试,界面是软件与用户交互的最直接的层,界面的好坏决定用户对软件的第一印象。而且设计良好的界面能够引导用户自己完成相应的操作,起到向导的作用。同时界面如同人的面孔,具有吸引用户的直接优势。设计合理的界面能给用户带来轻松愉悦的感受和成功的感觉,相反由于界面设计的失败,让用户有挫败感,再实用强大的功能都可能在用户的畏惧与放弃中付诸东流。
    区别在于,功能测试关注产品的所有功能上,要考虑到每个细节功能,每个可能存在的功能问题。性能测试主要关注于产品整体的多用户并发下的稳定性和健壮性。界面测试更关注于用户体验上,用户使用该产品的时候是否易用,是否易懂,是否规范(快捷键之类的),是否美观(能否吸引用户的注意力),是否安全(尽量在前台避免用户无意输入无效的数据,当然考虑到体验性,不能太粗鲁的弹出警告)?做某个性能测试的时候,首先它可能是个功能点,首先要保证它的功能是没问题的,然后再考虑该功能点的性能测试


    05.  请试着比较一下黑盒测试、白盒测试、单元测试、集成测试、系统测试、验收测试的区别与联系。
    黑盒测试:已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。
    白盒测试:已知产品的内部工作过程,可以通过测试证明每种内部操作是否符合设计规格要求,所有内部成分是否以经过检查。
      软件的黑盒测试意味着测试要在软件的接口处进行。这种方法是把测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求规格说明书,检查程序的功能是否符合它的功能说明。因此黑盒测试又叫功能测试或数据驱动测试。黑盒测试主要是为了发现以下几类错误:
    1、是否有不正确或遗漏的功能?
    2、在接口上,输入是否能正确的接受?能否输出正确的结果?
    3、是否有数据结构错误或外部信息(例如数据文件)访问错误?
    4、性能上是否能够满足要求?
    5、是否有初始化或终止性错误?
      软件的白盒测试是对软件的过程性细节做细致的检查。这种方法是把测试对象看做一个打开的盒子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序状态,确定实际状态是否与预期的状态一致。因此白盒测试又称为结构测试或逻辑驱动测试。白盒测试主要是想对程序模块进行如下检查:
    1、对程序模块的所有独立的执行路径至少测试一遍。
    2、对所有的逻辑判定,取“真”与取“假”的两种情况都能至少测一遍。
    3、在循环的边界和运行的界限内执行循环体。
    4、测试内部数据结构的有效性,等等。
    单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。
          单元测试是由程序员自己来完成,最终受益的也是程序员自己。可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和我们期望的一致。
    集成测试(也叫组装测试,联合测试)是单元测试的逻辑扩展。它的最简单的形式是:两个已经测试过的单元组合成一个组件,并且测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合成程序的更大部分。方法是测试片段的组合,并最终扩展进程,将您的模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。
    系统测试是将经过测试的子系统装配成一个完整系统来测试。它是检验系统是否确实能提供系统方案说明书中指定功能的有效方法。(常见的联调测试)
           系统测试的目的是对最终软件系统进行全面的测试,确保最终软件系统满足产品需求并且遵循系统设计。
    验收测试是部署软件之前的最后一个测试操作。验收测试的目的是确保软件准备就绪,并且可以让最终用户将其用于执行软件的既定功能和任务。
    验收测试是向未来的用户表明系统能够像预定要求那样工作。经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是验收测试的任务,即软件的功能和性能如同用户所合理期待的那样。


    06. 测试计划工作的目的是什么?测试计划工作的内容都包括什么?其中哪些是最重要的?
    软件测试计划是指导测试过程的纲领性文件,包含了产品概述、测试策略、测试方法、测试区域、测试配置、测试周期、测试资源、测试交流、风险分析等内容。借助软件测试计划,参与测试的项目成员,尤其是测试管理人员,可以明确测试任务和测试方法,保持测试实施过程的顺畅沟通,跟踪和控制测试进度,应对测试过程中的各种变更。
    测试计划和测试详细规格、测试用例之间是战略和战术的关系,测试计划主要从宏观上规划测试活动的范围、方法和资源配置,而测试详细规格、测试用例是完成测试任务的具体战术。所以其中最重要的是测试测试策略和测试方法(最好是能先评审)


    07. 您认为做好测试计划工作的关键是什么?
    1. 明确测试的目标,增强测试计划的实用性
    编写软件测试计划得重要目的就是使测试过程能够发现更多的软件缺陷,因此软件测试计划的价值取决于它对帮助管理测试项目,并且找出软件潜在的缺陷。因此,软件测试计划中的测试范围必须高度覆盖功能需求,测试方法必须切实可行,测试工具并且具有较高的实用性,便于使用,生成的测试结果直观、准确
    2.坚持“5W”规则,明确内容与过程
    “5W”规则指的是“What(做什么)”、“Why(为什么做)”、“When(何时做)”、“Where(在哪里)”、“How(如何做)”。利用“5W”规则创建软件测试计划,可以帮助测试团队理解测试的目的(Why),明确测试的范围和内容(What),确定测试的开始和结束日期(When),指出测试的方法和工具(How),给出测试文档和软件的存放位置(Where)。
    3.采用评审和更新机制,保证测试计划满足实际需求
    测试计划写作完成后,如果没有经过评审,直接发送给测试团队,测试计划内容的可能不准确或遗漏测试内容,或者软件需求变更引起测试范围的增减,而测试计划的内容没有及时更新,误导测试执行人员。
    4. 分别创建测试计划与测试详细规格、测试用例
    应把详细的测试技术指标包含到独立创建的测试详细规格文档,把用于指导测试小组执行测试过程的测试用例放到独立创建的测试用例文档或测试用例管理数据库中。测试计划和测试详细规格、测试用例之间是战略和战术的关系,测试计划主要从宏观上规划测试活动的范围、方法和资源配置,而测试详细规格、测试用例是完成测试任务的具体战术。


    08. 您所熟悉的测试用例设计方法都有哪些?请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。
    1.等价类划分
    划分等价类: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类.
    2.边界值分析法
      边界值分析方法是对等价类划分方法的补充。测试工作经验告诉我,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部.因此针对各种边界情况设计测试用例,可以查出更多的错误.
      使用边界值分析方法设计测试用例,首先应确定边界情况.通常输入和输出等价类的边界,就是应着重测试的边界情况.应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据.
    3.错误推测法
      基于经验和直觉推测程序中所有可能存在的各种错误, 从而有针对性的设计测试用例的方法.
      错误推测方法的基本思想: 列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据他们选择测试用例. 例如, 在单元测试时曾列出的许多在模块中常见的错误. 以前产品测试中曾经发现的错误等, 这些就是经验的总结. 还有, 输入数据和输出数据为0的情况. 输入表格为空格或输入表格只有一行. 这些都是容易发生错误的情况. 可选择这些情况下的例子作为测试用例.
    4.因果图方法
      前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系, 相互组合等. 考虑输入条件之间的相互组合,可能会产生一些新的情况. 但要检查输入条件的组合不是一件容易的事情, 即使把所有输入条件划分成等价类,他们之间的组合情况也相当多. 因此必须考虑采用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例. 这就需要利用因果图(逻辑模型). 因果图方法最终生成的就是判定表. 它适合于检查程序输入条件的各种组合情况. 


    08.您认为做好测试用例设计工作的关键是什么?
    白盒测试用例设计的关键是以较少的用例覆盖尽可能多的内部程序逻辑结果
    黑盒法用例设计的关键同样也是以较少的用例覆盖模块输出和输入接口。不可能做到完全测试,以最少的用例在合理的时间内发现最多的问题


    09. 请以您以往的实际工作为例,

    10. 详细的描述一次测试用例设计的完整的过程。
    就说最近的这次网站功能的测试吧
    首先:得到相关文档(需求文档和设计文档),理解需求和设计设计思想后,想好测试策略(测试计划简单点就OK了),考虑到测试环境,测试用例,测试时间等问题。
    第二步:设计测试用例,测试策略是:把网站部分的功能点测试完,然后在进行系统测试(另外个模块呢有另一个测试人员负责,可以进行联调测试),网站模块的测试基本是功能测试和界面测试(用户并发的可能性很小,所以不考虑):这次的网站的输入数据呢是使用数据库中的某张表记录,如果表中某一数据记录中新加进来的(还没有被处理的,有个标志位),网站启动后会立刻去刷那张表,得到多条数据,然后在进行处理。处理过程中,会经历3个步骤,网站才算完成了它的任务。有3个步骤呢,就可以分别对这3个步骤进行测试用例的设计,尽量覆盖到各种输入情况(包括数据库中的数据,用户的输入等),得出了差不多50个用例。界面测试,也就是用户看的到的地方,包括发送的邮件和用户填写资料的页面展示。
    第三步:搭建测试环境(为什么这个时候考虑测试环境呢?因为我对网站环境已经很熟了,只有有机器能空于下来做该功能测试就可以做了),因为网站本身的环境搭建和其他的系统有点不同,它需要的测试环境比较麻烦,需要web服务器(Apache,tomcat),不过这次需求呢,网站部分只用到了tomcat,所以只要有tomcat即可
    第四步:执行测试


    11. 您以往是否曾经从事过性能测试工作?如果有,

    12. 请尽可能的详细描述您以往的性能测试工作的完整过程。
    是的,曾经做过网站方面的性能测试,虽然做的时间并不久(2个月吧),当时呢,是有位网站性能测试经验非常丰富的前辈带着我一起做。
    性能测试类型包括负载测试,强度测试,容量测试等
          负载测试:负载测试是一种性能测试指数据在超负荷环境中运行,程序是否能够承担。
          强度测试: 强度测试是一种性能测试,他在系统资源特别低的情况下软件系统运行情况。
          容量测试:确定系统可处理同时在线的最大用户数  
    在网站流量逐渐加大的情况下,开始考虑做性能测试了,首先要写好性能测试计划,根据运营数据得出流量最大的页面(如果是第一次的话,一般是首页,下载页,个人帐户页流量最大,而且以某种百分比),
    Web服务器指标指标:
    * Avg Rps: 平均每秒钟响应次数=总请求时间 / 秒数;
    * Successful Rounds:成功的请求;
    * Failed Rounds :失败的请求;
    * Successful Hits :成功的点击次数;
    * Failed Hits :失败的点击次数;
    * Hits Per Second :每秒点击次数;
    * Successful Hits Per Second :每秒成功的点击次数;
    * Failed Hits Per Second :每秒失败的点击次数;
    * Attempted Connections :尝试链接数;

    13. 您在从事性能测试工作时,14. 是否使用过一些测试工具?如果有,15. 请试述该工具的工作原理,

    16. 并以一个具体的工作中的例子描述该工具是如何在实际工作中应用的。


    17. 您认为性能测试工作的目的是什么?做好性能测试工作的关键是什么?


    18. 在您以往的工作中,19. 一条软件缺陷(或者叫Bug)记录都包含了哪些内容?如何提交高质量的软件缺陷(Bug)记录?


    20. 您以往所从事的软件测试工作中,21. 是否使用了一些工具来进行软件缺陷(Bug)的管理?如果有,

    22. 请结合该工具描述软件缺陷(Bug)跟踪管理的流程。


    23. 您认为在测试人员同24. 开发人员的沟通过程中,

    25. 如何提高沟通的效率和改善沟通的效果?维持测试人员同26. 开发团队中其他成员良好的人际关系的关键是什么?
    27. 在您以往的测试工作中,28. 最让您感到不29. 满意或者不30. 堪回首的事情是什么?您是如何来对待这些事情的?


    31. 在即将完成这次笔试前,32. 您是否愿意谈一些自己在以往的学习和工作中获得的工作经验和心得体会?(可以包括软件测试、过程改进、软件开发或者与此无关的其他方面)


    33.     你对测试最大的兴趣在哪里?为什么?
    最大的兴趣就是测试有难度,有挑战性!做测试越久越能感觉到做好测试有多难。曾经在无忧测试网上看到一篇文章,是关于如何做好一名测试工程师。一共罗列了11,12点,有部分是和人的性格有关,有部分需要后天的努力。但除了性格有关的1,2点我没有把握,其他点我都很有信心做好它。
    刚开始进入测试行业时,对测试的认识是从无忧测试网上了解到的一些资料,当时是冲着做测试需要很多技能才能做的好,虽然入门容易,但做好很难,比开发更难,虽然当时我很想做开发(学校专业课我基本上不缺席,因为我喜欢我的专业),但看到测试比开发更难更有挑战性,想做好测试的意志就更坚定了。
    不到一年半的测试工作中,当时的感动和热情没有减退一点(即使环境问题以及自身经验,技术的不足,做测试的你一定也能理解)。
    我觉得做测试整个过程中有2点让我觉得很有难度(对我来说,有难度的东西我就非常感兴趣),第一是测试用例的设计,因为测试的精华就在测试用例的设计上了,要在版本出来之前,把用例写好,用什么测试方法写?(也就是测试计划或测试策略),如果你刚测试一个新任务时,你得花一定的时间去消化业务需求和技术基础,业务需求很好理解(多和产品经理和开发人员沟通就能达到目的),而技术基础可就没那么简单了,这需要你自觉的学习能力,比如说网站吧,最基本的技术知识你要知道网站内部是怎么运作的的,后台是怎么响应用户请求的?测试环境如何搭建?这些都需要最早的学好。至少在开始测试之前能做好基本的准备,可能会遇到什么难题?需求细节是不是没有确定好?这些问题都能在设计用例的时候发现。
    第二是发现BUG的时候了,这应该是测试人员最基本的任务了,一般按测试用例开始测试就能发现大部分的bug,还有一部分bug需要测试的过程中更了解所测版本的情况获得更多信息,补充测试用例,测试出bug。还有如何发现bug?这就需要在测试用例有效的情况下,通过细心和耐心去发现bug了,每个用例都有可能发现bug,每个地方都有可能出错,所以测试过程中思维要清晰(测试过程数据流及结果都得看仔细了,bug都在里面发现的)。如何描述bug也很有讲究,bug在什么情况下会产生,如果条件变化一点点,就不会有这个bug,以哪些最少的操作步骤就能重现这个bug,这个bug产生的规律是什么?如果你够厉害的话,可以帮开发人员初步定位问题。


    34. 你的测试职业发展是什么?
    测试经验越多,测试能力越高。所以我的职业发展是需要时间累积的,一步步向着高级测试工程师奔去。而且我也有初步的职业规划,前3年累积测试经验,按如何做好测试工程师的11,12点要求自己,不断的更新自己改正自己,做好测试任务。


    35. 你自认为测试的优势在哪里?
    优势在于我对测试坚定不移的信心和热情,虽然经验还不够,但测试需要的基本技能我有信心在工作中得以发挥。


    36. 你以前工作时的测试流程是什么?
    公司对测试流程没有规定如何做,但每个测试人员都有自己的一套测试流程。我说下我1年来不断改正(自己总结,吸取同行的方法)后的流程吧。需求评审(有开发人员,产品经理,测试人员,项目经理)->需求确定(出一份确定的需求文档)->开发设计文档(开发人员在开始写代码前就能输出设计文档)->想好测试策略,写出测试用例->发给开发人员和测试经理看看(非正式的评审用例)->接到测试版本->执行测试用例(中间可能会补充用例)->提交bug(有些bug需要开发人员的确定(严重级别的,或突然发现的在测试用例范围之外的,难以重现的),有些可以直接录制进TD)->开发人员修改(可以在测试过程中快速的修改)->回归测试(可能又会发现新问题,再按流程开始跑)。


    37. 当开发人员说不是BUG时,39. 你如何应付?
    开发人员说不是bug,有2种情况,一是需求没有确定,所以我可以这么做,这个时候可以找来产品经理进行确认,需不需要改动,3方商量确定好后再看要不要改。二是这种情况不可能发生,所以不需要修改,这个时候,我可以先尽可能的说出是BUG的依据是什么?如果被用户发现或出了问题,会有什么不良结果?程序员可能会给你很多理由,你可以对他的解释进行反驳。如果还是不行,那我可以给这个问题提出来,跟开发经理和测试经理进行确认,如果要修改就改,如果不要修改就不改。其实有些真的不是bug,我也只是建议的方式写进TD中,如果开发人员不修改也没有大问题。如果确定是bug的话,一定要坚持自己的立场,让问题得到最后的确认。


    23.你为什么想离开目前的职务?
    因为公司运作情况并不理想,公司需要调整部门体系,公司考虑到缩减部门人员,所以大批量的裁员(有6,7个),这是我的第一份工作,对公司也有较深的感情,因为在这里我找到了职业理想(就是测试),所以公司需要精简人员,我自愿退出。虽然很舍不得,但我将会有新的发挥能力的舞台。


      24:你对我们公司了解有多少?

      25:你找工作时,最重要的考虑因素为何?
    工作的性质和内容是否能让我发挥所长,并不断成长。


    26:为什么我们应该录取你?
    您可以由我过去的工作表现所呈现的客观数据,明显地看出我全力以赴的工作态度。


      27:请谈谈你个人的最大特色。
    我的坚持度很高,事情没有做到一个令人满意的结果,绝不罢手。
    28.白箱测试和黑箱测试是什么?什么是回归测试?
        29。单元测试、集成测试、系统测试的侧重点是什么?
        30。设计用例的方法、依据有那些?
        31。一个测试工程师应具备那些素质和技能?
        32.集成测试通常都有那些策略?
        33.你用过的测试工具的主要功能、性能及其他?
        34.一个缺陷测试报告的组成
        35.基于WEB信息管理系统测试时应考虑的因素有哪些?
    36.软件测试项目从什么时候开始,?为什么?
         37.需求测试注意事项有哪些?
         38.简述一下缺陷的生命周期
         39.测试分析测试用例注意(事项)?
    你在你所在的公司是怎么开展测试工作的?是如何组织的?
    你认为理想的测试流程是什么样子?
    你是怎样工作的?
    软件测试活动的生命周期是什么?
    请画出软件测试活动的流程图?
    针对缺陷采取怎样管理措施?
    什么是测试评估?测试评估的范围是什么?
    如果能够执行完美的黑盒测试,还需要进行白盒测试吗?为什么?
    测试结束的标准是什么?
    软件验收测试除了alpha,beta测试以外,还有哪一种?
    做测试多久了?
    以前做过哪些项目?
    你们以前测试的流程是怎样的?
    <答:测试计划-测试用例设计-测试执行-测试分析报告>
    用过哪些测试工具?
    为什么选择测试这行?
    <答:它是一个新兴的行业,有发展潜力,而且很锻炼人,需要掌握更多的技能,比做开发要更难>
    为什么值得他们公司雇用?
    如果我雇用你,你能给部门带来什么贡献?
    如何从工作中看出你是个自动自觉的人
    你的工作通常能在时限内完成吗.(我想问一下就是她问这个问题的动机是什么)
    通常你对于别人批评你会有什么样的反应
    如果明知这样做不对,你还会依主管的指过去做吗
    如果你接到一个客户抱怨的电话,你确知无法解决他的问题,你会怎么处理
    你觉得什么样的人最难相处
    为什么值得他们公司雇用?
          帮助公司提高软件质量和测试部门的技术水平
    如果我雇用你,你能给部门带来什么贡献?
          分享我的测试经验和测试技能,提高测试部门技术水平
    如何从工作中看出你是个自动自觉的人
         自动自觉范围太广
          1. 工作成果
          2. 工作质量  
    你的工作通常能在时限内完成吗.(我想问一下就是她问这个问题的动机是什么)
          在有足够的资源和合理的工作量的情况下,完全可以按时完成,并能比一般人做的更好
    通常你对于别人批评你会有什么样的反应
      有错即改,无措勉之
    如果明知这样做不对,你还会依主管的指过去做吗
         在公司内部下级是否有申诉渠道?
    如果你接到一个客户抱怨的电话,你确知无法解决他的问题,你会怎么处理
        为什么抱怨?是怎么样的问题?
         如果是客服问题,提交客服部门解决
        如果是质量问题,分析原因,下一版本改进
    你觉得什么样的人最难相处
         自以为是的人
    什么叫单元测试?
    请就软件测试人员应该具备什么样的基本素质说说你的看法。
    请就如何在开发中进行软件质量控制说说你的看法
     简述软件测试的意义,以及软件测试的分类

    1、功能测试,性能测试,界面测试,安全测试(可以简单点,比如只涉及到COOKIES里的内容),压力测试(商业性质的网站) 等等,B/S软件也要根据其具体功能采用不同的测试策略。
    2、态度、责任心、自信、敏锐的观察力、良好的发散思维
    3、先设计后开发模式,加强单元测试,加强代码走查,有一套完整的白盒测试方法。关键是加强开发人员的质量意识,增进程序员向工程师水平发展。
    4、意义嘛,就自己想吧。软件测试的分类,这个很多人都按各种方法去分。无明确答案给你。

    对测试的理解——基本的测试知识,对测试是否认可? 75。
       3、谈一谈过去自己的工作——了解经历、提供进一步提问的素材,表达能力  
    测试技能
    测试设计的方法并举例说明——测试技术的使用
    测试工具——熟悉程度,能否与当前工作匹配?
    如何做计划?如何跟踪计划?——日常工作能力
    如果开发人员提供的版本不满足测试的条件,如何做?——与开发人员协作的能力
    熟悉unix系统、oracle数据库吗?——是否具备系统知识
    做过开发吗?写过哪些代码?——开发技能
    阅读英语文章,给出理解说明?——部分英语能力
    文档的意义——是否善于思考?(最简单的概念,不同层次的理解)
    假如进入我们公司,对我们哪些方面会有帮助?——讲讲自己的特长
    随便找一件物品,让其测试——测试的实际操作能力
    软件测试的方法有?
    软件测试的过程?
    有一个新的软件,假如你是测试工程师,该如何做?
    软件测试分哪两种方法?分别适合什么情况?

     
    2。一套完整的测试应该由哪些阶段组成?分别阐述一下各个阶段。
    3。软件测试的类型有那些?分别比较这些不同的测试类型的区别与联系。
    4。测试用例通常包括那些内容?着重阐述编制测试用例的具体做法
    5。在分别测试winform的C/S结构与测试WEB结构的软件是,应该采取什么样的方法分别测试?他们存在什么样的区别与联系?
    6。在测试winform的C/S结构软件时,发现这个软件的运行速度很慢,您会认为是什么原因?您会采取哪些方法去检查这个原因?
    7。描述使用bugzilla缺陷管理工具对软件缺陷(BUG)跟踪的管理的流程
    你在五年内的个人目标和职业目标分别是什么?
      分析这个问题是用来了解你的计划能力的,通过这个问题,面试人同时还可以知道你的目标是否符合企业对你的安排。
      错误回答我想在将来的某个时候考虑这个问题。如今企业的领导者更换频繁,我认为做太多的个人计划是荒谬可笑的,不是吗?
      评论这种回答属于令人反感的一类。首先,当有人想了解你的目标时,"将来的某个时候"这种通俗说法并不奏效。其次,认为企业很脆弱,领导者更换频繁,这种说法毫无疑问会令人反感,而且也是不合理的。最后,认为做计划可笑,看不起这个问题,而且反问面试人,这些都注定了这样的求职者最终会失败。
      正确回答从现在起的五年之内,我希望能够在一个很好的职位上待几年,而且最好有一次晋升,然后就期待着下一步。不管是向上提升,还是在企业内横向调动,对我个人来说,我希望找到一家企业——一家愿意做相互投入的企业——待上一段时间。
      评论这个问题没有回答得过分具体(那样可能会产生漏洞),而且它表明你有雄心,并且思考过在企业中的成长方式。通过表达横向调动和向上提升的愿望,表明你是一个有灵活性的人。
     问题23 你怎样做出自己的职业选择?
      分析 面试人提出这个问题是为了了解求职者的动机,看看他(她)应聘这份工作是否有什么历史渊源,是否有职业规划,是不是仅仅在漫无目的地申请很多工作。
      错误回答 我一直都想在企业界工作。自孩提时代起,我就梦想自己至少也要成为大企业的副总裁。
      评论 除了难以令人相信之外,这种回答还存在一个问题:它表明求职者会对副总裁以下的职位不感兴趣。
      正确回答 在上大学四年级前的那个夏天,我决定集中精力在某一领域谋求发展。尽管我是学商业的,但是我不知道自己最终会从事哪一行业的工作。我花了一定的时间考虑自己的目标,想清楚了自己擅长做的事情以及想从工作中得到的东西,最后我得出了一个坚定的结论,那就是这个行业是最适合我的。
      评论 这种回答表明,求职者认真地做过一些计划,缩小了自己的关注点,而且也认准了前进的方向。这种回答还表明,求职者理解个人职业规划的重要性,并且有能力做出认真的个人决策。


    1. 你都用什么测试方法
    2.怎么编写案例
    3.怎么才能够全面的测试到每一个点
    1. 你都用什么测试方法
    针对不同的产品或者系统或者模块,有不同的测试方法。总体而言有白盒测试和黑盒测试。
    2.怎么编写案例
    案例的编写与测试阶段的定义有很大的关系。系统测试和unit测试的案例可能不同。总体而言测试案例根据系统的需求而定。
    3.怎么才能够全面的测试到每一个点
    测试的全面性主要需要在设计测试计划的时候考虑,从测试策略,产品需求等等多个角度考虑从而定义全部的测试点。
    1、谈谈软件测试技术,以及如何提高
    2、谈谈软件测试职业发展,以及个人的打算
    3、谈谈软件测试在企业的地位,也可以结合软件生命周期来谈
    有可能清晰的思路比确切的答案更重要
    在这里,主要说下笔试和面试的问题,希望大家共同参考。
        1,一般公司里实际的软件测试流程是什么样的?你们公司又是怎样的?
        2,软件工程师要具有那些素质?
        3,你会哪些测试工具?怎么操作?
        4,你能不能说下你的3到5年的职业计划(规划)
        5,你觉得你来应聘有那些优势?
    其余的还好说,但就第4个问题,我感到不好说哦!希望大家给个意见
    第一关:首先要自我介绍,自己的性格怎么样,目前的工作经历积累了一些什么经验取得了些什么值得一说的成果。然后要说说对软件测试怎么看?还有对于软件测试有什么自己的想法。为什么会想到要做这行(因为我的简历上的工作经历没有关于测试方面的)。哦,还有期望薪资。
    第二关:认为软件测试人员所要具备的基本素质,如果遇到问题会怎样处理,如果得不到研发人员的配合(就是研发说这个不是问题)你又会怎么处理?然后就是一些基本概念,比如软件测试的流程有哪些?如果我上任了,首先会怎么开始自己的工作计划。
    (前两关通过了后面这个就好过多了)
    第三关:像我介绍了一下公司的情况,告诉我主要针对什么内容的测试,会不会使用数据库。告诉我大概要做哪些内容,详细的可以上岗以后慢慢熟悉。
    大概就这么多了,这对没有经过这一关的不知道有没有帮助,仅供参考吧
    我觉得就像李波说的,关键是要给对方留下好印象:)

    面试官最后会问你有什么问题要问吗。作为应聘者的你一般不要说没问题问,这会给面试官留下你不太重视这份工作的坏印象。所以如果你想得到这份工作的话应该抓住这最后的表现自己的机会:
    你可以问:
    1.        贵公司近期和远期的发展目标是什么?
    2.        贵公司的主要竞争对手有哪些?
    3.        贵公司有多少开发人员有多少测试人员?
    4.        贵公司又进一步扩充测试人员的计划吗?
    5.        如果我有幸能进入贵公司的话,我有怎么样的发展?
    6.        测试人员的沟通能力很重要,贵公司有规范的沟通渠道吗?
    7.        请介绍一下贵公司的福利情况。
    8.        请问我什么时候能知道结果?

  • QTP编码小技巧集锦

    iseedeadpeople 发布于 2009-10-20 18:17:09


    QTP编码小知识 五 “山寨”WebElement】

      随着web开发技术变得越来越复杂,使QTP在处理web对象时也变得不那么容易,但是很多时候还是能通过调整对象属性的技巧,达到正确识别我们想要的对象(Web元素)。这同时也就提出了更高的要求,要能够了解一些Web开发的知识,分析测试页面的源程序。当然光分析仍然是有些马后炮,更好的应该是在界面开发时就为以后自动化测试做准备了。

      确实在QTP的对象识别过程中,让QTP用户尤为头疼的就是对象识别。而当QTP识别不了对象时候,就不负责任的丢了一个"WebElement"给大家,而每个人都觉得这不是我想要的结果。那么如何更好的把这个WebElement做出我们想要的效果与操作呢?

      ……

      详情请查看:http://www.51testing.com/html/74/n-108374.html


    【QTP编码小知识 四 对象库与索引值】

      偏向喜欢使用对象库操作的QTP用户,在添加对象时候,会出现某几个子对象,都识别成一个对象,因为里面的所有属性几乎是一样的,很为难的不知道如何解决这个问题,借鉴与描述编程中的索引值index的使用,例如:

      dim Input_Dec
      set Input_Dec=description.create()
      Input_Dec("Html tag").value="Input"
      Input_Dec("Index").value=1
      .....

      如何把index添加进去或者如何把这些描述的东西添加进去?在这里给了大家一个小的html page,大家下载下去后,可以先试试看,然后再看看下文,如何使用Index。自然这个不会识别成一个对象,因为它们的类型有区别,只是特定或者模拟某些情况而已。

      ……

      详情请查看:http://www.51testing.com/?action-viewnews-itemid-96772


    【QTP编码小知识 三 IE内存释放】

      由于编码小知识出到第三帖,特此帖送出API手册一份,想要会自动化,还离不开Win32 API。

      先说下小编对关于Web内存的一些小看法,之前已经有讨论过关于IE内存占用居高不下,导致了QTP对Web页面的操作出现种种问题。今天和大家说下简单的内存释放方法。首先我们使用的将浏览器最小化然后再做最大化的操作来实现这个释放工作。很多人知道,IE最小化后,内存占用不到2M,最大化后,会比之前最小化前占的内存更少。

      ……

      详情请查看:http://www.51testing.com/?action-viewnews-itemid-94271


    【QTP编码小知识 二】

      大家看看下面代码,代码是运行在谷歌的主页面,如果大家要试的话,大家同样也可以试试这代码的运行结果。

         Dim LinkDes
         Set LinkDes=description.Create()
         LinkDes("html tag").value="A"

         Set LinkObj=browser("Google").Page("Google").ChildObjects(LinkDes)
         For i=0 to LinkObj.count
            LinkObj(i).click
            browser("Google").Back
         Next

      代码运行完后,你会发现,原来在循环第2次连接点击的时候,抛出了一个“General run error”。这个是为什么会这样?之前也同样有论坛的朋友问到这样的问题,所以今天就在这里提到。

      问题是出在了对第一个连接点击后,做了返回操作所导致的,在第一次back的时候,LinkObj对象就已经丢失了,失效了。所以你在做第2次操作的时候,LinkObj(i)就已经找不到了,因此它会出错。

      正确的方法,这个也是我目前想到的,或者还有其它达人能做更好的方法出来。

      ……

      详情请查看:http://www.51testing.com/html/52/n-93852.html


    【QTP编码小知识 一】

      你学习过 了编程,知道了,如果and的条件,如果有一个否,哪么就全部为否,自然是这个是逻辑条件的问题,你有学过,所以你写成2个and的方法去简略代码。但问 题往往发生在这里,就和变魔术一样,大人看不出,但小孩就可以看出里面的问题,因为成人的思想会被自己所谓的经验所左右。

      这段代码的错误地方发生在那里,估计读到这里的人大部分已经猜到了,错误会发生在第1片中的2 3行!!你会问为什么?这应该没错才对的呀?

      详情请查看:http://www.51testing.com/?action-viewnews-itemid-93797


    版权声明:以上作品均为51Testing软件测试网原创,由会员假装不在提供。

    原创作品,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明,否则将追究法律责任。


    相关阅读:

    QTP中常用的VB的函数

    使用VBScript开发自动化测试脚本

  • 国外优秀测试网址

    bingling_11 发布于 2008-08-26 16:19:27

    http://bdonline.sqe.com/ 一个关于网站测试方面的网页,对这方面感兴趣的人可以参考
    http://citeseer.nj.nec.com/ 一个丰富的电子书库,内容很多,而且提供著作的相关文档参考和下载,是作者非常推荐的一个资料参考网站
    http://groups.yahoo.com/group/LoadRunner 性能测试工具LoadRunner的一个论坛
    http://groups.yahoo.com/grorp/testing-paperannou-nce/messages 提供网站上当前发布的软件测试资料列表
    http://satc.gsfc.nasa.gov/homepage.html 软件保证中心是美国国家航天局(NASA)投资设立的一个软件可靠性和安全性研究中心,研究包括了度量、工具、风险等各个方面
    http://seg.iit.nrc.ca/English/index.html 加拿大的一个研究软件工程质量方面的组织,可以提供研究论文的下载
    http://sepo.nosc.mil/ 内容来自美国SAN DIEGO的软件工程机构(Sofrware Engineering Process Office)主页,包括软件工程知识方面的资料
    http://www.asq.org/ 是世界上最大的一个质量团体组织之一,有着比较丰富的论文资源,不过是收费的
    http://www.automated-testing.com/ 一个自动化软件测试和自然语言处理研究页面,属于个人网页,上面有些资源可供下载
    http://www.benchmarkresources.com/ 提供有关标杆方面的资料,也有一些其它软件测试方面的资料
    http://www.betasoft.com/ 包含一些流行测试工具的介绍、下载和讨论,还提供测试方面的资料
    http://www.brunel.ac.uk/~csstmmh2/vast/home.html VASTT研究组织,主要从事通过切片技术测试技术和转换技术来验证和分析系统,对这方面技术感兴趣的人是可以在这里参考一些研究的项目及相关的一些主题信息
    http://www.cc.gatech.edu/aristotle/ Aristole研究组织,研究软件系统分析、测试和维护等方面的技术,在测试方面的研究包括了回归测试、测试套最小化、面向对象软件测试等内容,该网站有丰富的论文资源可供下载
    http://www.computer.org/ IEEE是世界上最悠久,也是在最大的计算机社会团体,它的电子图书馆拥有众多计算机方面的论文资料,是研究计算机方面的一个重要资源参考来源
    http://www.cs.colostate.edu/testing/ 可靠性研究网站,有一些可靠性方面的论文资料
    http://www.cs.york.ac.uk/testsig/ 约克大学的测试专业兴趣研究组网页,有比较丰富的资料下载,内容涵盖了测试的多个方面,包括测试自动化、测试数据生成、面向对象软件测试、验证确认过程等
    http://www.csr.ncl.ac.uk/index.html 学校里面的一个软件可靠性研究中心,提供有关软件可靠性研究方面的一些信息和资料,对这方面感兴趣的人可以参考
    http://www.dcs.shef.ac.uk/research/groups/vt/ 学校里的一个验证和测试研究机构,有一些相关项目和论文可供参考
    http://www.esi.es/en/main/ ESI(欧洲软件组织),提供包括CMM评估方面的各种服务
    http://www.europeindia.org/cd02/index.htm 一个可靠性研究网站,有可靠性方面的一些资料提供参考
    http://www.fortest.org.uk/ 一个测试研究网站,研究包括了静态测试技术(如模型检查、理论证明)和动态测试(如测试自动化、特定缺陷的检查、测试有效性分析等)
    http://www.grove.co.uk/ 一个有关软件测试和咨询机构的网站,有一些测试方面的课程和资料供下载
    http://www.hq.nasa.gov/office/codeq/relpract/prcls-23.htm NASA可靠性设计实践资料
    http://www.io.com/~wazmo/ Bret Pettichord的主页,他的一个热点测试页面连接非常有价值,从中可以获得相当大的测试资料,很有价值
    http://www.iso.ch/iso/en/ISOOnline.frontpage 国际标准化组织,提供包括ISO标准系统方面的各类参考资料
    http://www.isse.gmu.edu/faculty/ofut/classes/ 821-ootest/papers.html 提供面向对象和基于构架的测试方面著作下载,对这方面感兴趣的读者可以参考该网站,肯定有价值
    http://www.ivv.nasa.gov/ NASA设立的独立验证和确认机构,该机构提出了软件开发的全面验证和确认,在此可以获得这方面的研究资料
    http://www.kaner.com/ 著名的测试专家Cem Kanner的主页,里面有许多关于测试的专题文章,相信对大家都有用。Cem Kanner关于测试的最著名的书要算Testing Software,这本书已成为一个测试人员的标准参考书
    http://www.library.cmu.edu/Re-search/Engineer- ingAndSciences/CS+ECE/index.html 卡耐基梅陇大学网上图书馆,在这里你可以获得有关计算机方面各类论文资料,内容极其庞大,是研究软件测试不可获取的资料来源之一
    http://www.loadtester.com/ 一个性能测试方面的网站,提供有关性能测试、性能监控等方面的资源,包括论文、论坛以及一些相关链接
    http://www.mareinig.ch/mt/index.html 关于软件工程和应用开发领域的各种免费的实践知识、时事信息和资料文件下载,包括了测试方面的内容
    http://www.mtsu.ceu/-storm/ 软件测试在线资源,包括提供目前有哪些人在研究测试,测试工具列表连接,测试会议,测试新闻和讨论,软件测试文学(包括各种测试杂志,测试报告),各种测试研究组织等内容
    http://www.psqtcomference.com/ 实用软件质量技术和实用软件测试技术国际学术会议宣传网站,每年都会举行两次
    http://www.qacity.com/front.htm 测试工程师资源网站,包含各种测试技术及相关资料下载
    http://www.qaforums.com/ 关于软件质量保证方面的一个论坛,需要注册
    http://www.qaiusa.com/ QAI是一个提供质量保证方面咨询的国际著名机构,提供各种质量和测试方面证书认证
    http://www.qualitytree.com/ 一个测试咨询提供商,有一些测试可供下载,有几篇关于缺陷管理方面的文章值得参考
    http://www.rational.com/ IBM Rational的官方网站,可以在这里寻找测试方面的工具信息。IBM Rational提供测试方面一系列的工具,比较全面
    http://rexblackconsulting.com/Pages/publicat-ions.htm
    Rex Black的个人主页,有一些测试和测试管理方面的资料可供下载
    http://www.riceconsulting.com/ 一个测试咨询提供商,有一些测试资料可供下载,但不多
    http://www.satisfice.com/ 包含James Bach关于软件测试和过程方面的很多论文,尤其在启发式测试策略方面值得参考
    http://www.satisfice.com/seminars.shtml 一个黑盒软件测试方面的研讨会,主要由测试专家Cem Kanar和James Bach组织,有一些值得下载的资料
    http://www.sdmagazine.com/ 软件开发杂志,经常会有一些关于测试方面好的论文资料,同时还包括了项目和过程改进方面的课题,并且定期会有一些关于质量和测试方面的问题讨论
    http://www.sei.cmu.edu/ 著名的软件工程组织,承担美国国防部众多软件工程研究项目,在这里你可以获俄各类关于工程质量和测试方面的资料。该网站提供强有力的搜索功能,可以快速检索到你想要的论文资料,并且可以免费下载
    http://www.soft.com/Institute/HotList/ 提供了网上软件质量热点连接,包括:专业团体组织连接、教育机构连接、商业咨询公司连接、质量相关技术会议连接、各类测试技术专题连接等
    http://www.soft.com/News/QTN-Online/ 质量技术时事,提供有关测试质量方面的一些时事介绍信息,对于关心测试和质量发展的人士来说是很有价值的
    http://www.softwaredioxide.com/ 包括软件工程(CMM,CMMI,项目管理)软件测试等方面的资源
    http://www.softwareqatest.com/ 软件质量/测试资源中心。该中心提供了常见的有关测试方面的FAQ资料,各质量/测试网站介绍,各质量/测试工具介绍,各质量/策划书籍介绍以及与测试相关的工作网站介绍
    http://www.softwaretestinginstitute.com/ 一个软件测试机构,提供软件质量/测试方面的调查分析,测试计划模板,测试WWW的技术,如何获得测试证书的指导,测试方面书籍介绍,并且提供了一个测试论坛
    http://www.sqatester.com/index.htm 一个包含各种测试和质量保证方面的技术网站,提供咨询和培训服务,并有一些测试人员社团组织,特色内容是缺陷处理方面的技术
    http://www.sqe.com/ 一个软件质量工程服务性网站,组织软件测试自动化、STAR-EASE、STARWEST等方面的测试学术会议,并提供一些相关信息资料和课程服务
    http://www.stickyminds.com/ 提供关于软件测试和质量保证方面的当前发展信息资料,论文等资源
    http://www.stqemagazine.com/ 软件策划和质量工程杂志,经常有一些好的论文供下载,不过数量较少,更多地需要通过订购获得,内容还是很有价值的
    http://www.tantara.ab.ca/ 软件质量方面的一个咨询网站,有过程改进方面的一些资料提供
    http://www.tcse.org/ IEEE的一个软件工程技术委员会,提供技术论文下载,并有一个功能强大的分类下载搜索功能,可以搜索到测试类型、测试管理、 测试分析等各方面资料
    http://www.testing.com/ 测试技术专家Brain Marick的主页,包含了Marick 研究的一些资料和论文,该网页提供了测试模式方面的资料,值得研究。总之,如果对测试实践感兴趣,该网站一定不能错过
    http://www.testingcenter.com/ 有一些测试方面的课程体系,有一些价值
    http://www.testingconferences.com/asiastar/home 著名的AsiaStar测试国际学术会议官方网站,感兴趣的人一定不能错过
    http://www.testingstuff.com/ Kerry Zallar的个人主页,提供一些有关培训、工具、会议、论文方面的参考信息
    http://www-sqi.cit.gu.edu.au/ 软件质量机构,有一些技术资料可以供下载,包括软件产品质量模型、再工程、软件质量改进等
  • 软件测试之常用的功能测试方法解析(转载)

    bingling_11 发布于 2007-04-04 10:41:14

    功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。常用的测试方法如下:

      1. 页面链接检查:每一个链接是否都有对应的页面,并且页面之间切换正确。

      2. 相关性检查:删除/增加一项会不会对其他项产生影响,如果产生影响,这些影响是否都正确。

      3. 检查按钮的功能是否正确:如update, cancel, delete, save等功能是否正确。

      4. 字符串长度检查: 输入超出需求所说明的字符串长度的内容, 看系统是否检查字符串长度,会不会出错.

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

      6. 标点符号检查: 输入内容包括各种标点符号,特别是空格,各种引号,回车键.看系统处理是否正确.

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

      8. 检查带出信息的完整性: 在查看信息和update信息时,查看所填写的信息是不是全部带出.,带出信息和添加的是否一致

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

      10. 检查删除功能:在一些可以一次删除多个信息的地方,不选择任何信息,按”delete”,看系统如何处理,会否出错;然后选择一个和多个信息,进行删除,看是否正确处理.

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

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

      13. 重复提交表单:一条已经成功提交的纪录,back后再提交,看看系统是否做了处理。

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

      15. search检查: 在有search功能的地方输入系统存在和不存在的内容,看search结果是否正确.如果可以输入多个search条件,可以同时添加合理和不合理的条件,看系统处理是否正确.

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

      17. 上传下载文件检查:上传下载文件的功能是否实现,上传文件是否能打开。对上传文件的格式有何规定,系统是否有解释信息,并检查系统是否能够做到。

      18. 必填项检查:应该填写的项没有填写时系统是否都做了处理,对必填项是否有提示信息,如在必填项前加*

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

      20. 回车键检查: 在输入结束后直接按回车键,看系统处理如何,会否报错。

  • LoadRunner7.8测试流程(转载)

    bingling_11 发布于 2007-09-05 14:18:39

    04 10:56:38 / 个人分类:性能测试
    Loadrunner中参数设置详细分析,相信对大家会有用的,这个版本是基于7.8的。
    做负载或者压力测试时,很多人选择使用了Loadrunner测试工具。该工具的基本流程是先将用户的实际操作录制成脚本,然后产生数千个虚拟用户运行脚本(虚拟用户可以分布在局域网中不同的PC机上),最后生成相关的报告以及分析图。但是在录制脚本的过程中会遇到很多实际的问题,比如不同的用户有不同的使用数据,这就牵涉到参数的设置问题。本文就Loadrunner中参数的设置进行说明,希望对大家有所帮助。
        在录制程序运行的过程中,VuGen(脚本生成器)自动生成了包含录制过程中实际用到的数值的脚本。如果你企图在录制的脚本中使用不同的数值执行脚本的活动(如查询、提交等等),那么你必须用参数值取代录制的数值。这个过程称为参数化脚本。
        本文主要包括如下内容:理解参数的局限性、建立参数、定义参数的属性、理解参数的类型、为局部数据类型设置参数的属性、为数据文件设置参数的属性、从已经存在的数据库中引入数据。
        除了GUI,以下的内容适合于各种类型的用户脚本。
    一、关于参数的定义
        在你录制程序运行的过程中,脚本生成器自动生成由函数组成的用户脚本。函数中参数的值就是在录制过程中输入的实际值。
        例如,你录制了一个Web应用程序的脚本。脚本生成器生成了一个声明,该声明搜索名称为“UNIX”的图书的数据库。当你用多个虚拟用户和迭代回放脚本时,也许你不想重复使用相同的值“UNIX”。那么,你就可以用参数来取代这个常量。结果就是你可以用指定的数据源的数值来取代参数值。数据源可以是一个文件,也可以是内部产生的变量。
        用参数表示用户的脚本有两个优点:
    ① 可以使脚本的长度变短。
    ② 可以使用不同的数值来测试你的脚本。例如,如果你企图搜索不同名称的图书,你仅仅需要写提交函数一次。在回放的过程中,你可以使用不同的参数值,而不只搜索一个特定名称的值。
        参数化包含以下两项任务:
    ① 在脚本中用参数取代常量值。
    ② 设置参数的属性以及数据源。
        参数化仅可以用于一个函数中的参量。你不能用参数表示非函数参数的字符串。另外,不是所有的函数都可以参数化的。
     
    二、参数的创建
        可以指定名称和类型来创建参数。不存在对脚本中参数个数的限制。在Web程序的用户脚本中,你可以使用如下过程在基于文本的脚本视图中创建参数。或者,也可以在基于图标的树形视图中创建参数。
        在基于文本的脚本视图中创建一个参数:
    1、 将光标定位在要参数化的字符上,点击右键。打开弹出菜单。
    2、 在弹出菜单中,选择“Replace with a Parameter”。选择或者创建参数的对话框弹出。
    3、 在“Parameter name”中输入参数的名称,或者选择一个在参数列表中已经存在的参数。
    4、 在“Parameter type”下拉列表中选择参数类型。
    5、点击“OK”,关闭该对话框。脚本生成器便会用参数中的值来取代脚本中被参数化的字符,参数用一对“{}”括住。
        注意:在参数化CORBA或者General-Java 用户脚本的时候,必须参数化整个字符串,而不是其中的部分。另外注意:除了Web或者WAP,缺省的参数括号对于任何脚本都是 “{}”。你可以在“General Options”对话框中的“Parameterization”标签(Tools>General Options)中定义参数括号种类。
    6、用同样的参数替换字符的其余情况,选中参数,点击右键,弹出菜单。从弹出的菜单中,选择“Replace More Occurrences”。搜索和替换对话框弹出。“Find What”中显示了你企图替换的值。“Replace With”中显示了括号中参数的名称。选择适当的检验框来匹配整个字符或者大小写。如果要搜索规则的表达式(.,!,?等等),选中“Regular Expression”检验框,然后点击“Replace”或者“Replace All”。
        注意:小心使用“Replace All”,尤其替换数字字符串的时候。脚本生成器将会替换字符出现的所有情况。
    7、如果想用以前定义过的参数来替换常量字符串的话,选中该字符串,点击右键,然后选择“Use Existing Parameter”,子菜单“Use Existing Parameters”弹出。从子菜单“Use Existing Parameters”选择参数,或者用“Select from Parameter List”来打开参数列表对话框。
        注意:如果用以前定义过的参数来替换常量字符串的话,那么,使用“Parameter List”非常方便。同时,还可以查看和修改该参数的属性。
    8、对于已经用参数替换过的地方,如果想取回原来的值,那么,就在参数上点击右键,然后选择“Restore Original value”。
        在Web用户脚本的树形视图中创建参数:
    1、将光标定位在企图参数化的地方,点击右键,从弹出的菜单中选择“Properties”。则相关的属性对话框打开。
    2、点击在要参数化的参量的旁边的“ABC”形状的图标。“Select or Create Parameter”对话框打开。
    3、在“Parameter name”中输入参数的名称,或者从列表中选择一个已经存在的参数。
    4、在“Parameter type”中输入参数的类型。
    5、点击“OK”关闭该对话框。用户脚本生成器会用参数来替换最初的字符串常量,并用一个表格形状的图标替换“ABC”形状的图标。
    6、要恢复参数化以前的值,点击图标,然后从弹出的菜单中选择“Undo Parameter”,则以前的值便会重现。
     
    三、定义参数的属性
        创建参数完成后,就可以定义其属性了。参数的属性定义就是定义在脚本执行过程中,参数使用的数据源。在Web用户脚本中,你既可以在基于文本的脚本视图中定义参数属性,也可以在基于图标的树形视图中定义参数属性。下面的过程将教你如何在基于本文的脚本视图中定义参数属性。
        在基于文本的脚本视图中定义参数属性步骤:
    1、 在参数上点击右键,有菜单弹出。
    2、 在弹出的菜单中,选择“Parameter Properties”。参数属性对话框打开,显示和当前参数类型相关的属性。
    3、 输入参数的属性值。
    4、 点击“Close”关闭参数属性对话框。
        在Web用户脚本的树形视图中定义参数的属性:
    1、将关标定位在参数上,然后点击右键,选择“Properties”。属性对话框打开。
    2、点击要定义属性的参数旁边的表格形状按钮,点击右键,选择“Parameter Properties”。参数属性对话框打开,和参数类型相关的属性显示出来。
    3、 输入参数的属性。
    4、 点击“Close”关闭参数属性对话框。
        使用参数列表:
      使用参数列表可以在任意时刻查看所有的参数,创建新的参数、删除参数,或者修改已经存在参数的属性。
    1、 点击参数列表按钮或者用“Vuser>Parameter List”。参数列表对话框打开。
    2、要创建新的参数,点击“New”按钮。新的参数则被添加在参数树中,该参数有一个临时的名字,你可以给它重新命名,然后回车。设置参数的类型和属性,点击“OK”,关闭参数列表对话框。
        注意:不要将一个参数命名为“unique”,因为这个名称是用户脚本生成器本身的。用户脚本生成器创建新的参数,但是不会自动用该参数在脚本中替换任意选中的字符串。
    3、要删除已有的参数,那么,要先从参数树中选择该参数,点击“Delete”,然后确认你的行为即可。
    4、要修改已有参数,那么,要先从参数树中选择该参数,然后编辑参数的类型和属性。
    四、理解参数的类型
      在你定义参数属性的时候,要指定参数值的数据源。你可以指定下列数据源类型的任何一种:
    Internal Data―― 虚拟用户内部产生的数据。
    Data Files ――存在于文件中的数据。可能是已存在的文件或者是用脚本生成器新创建的。
    User-Defined Functions―― 调用外部DLL函数生成的数据
      Internal Data包括以下几种:
    1、 Date/Time
      Date/Time用当前的日期/时间替换参数。要指定一个Date/Time格式,你可以从菜单列表中选择格式,或者指定你自己的格式。这个格式应该和你脚本中录制的Date/Time格式保持一致。
    2、 Group Name
      Group Name 用虚拟用户组名称替换参数。在创建scenario的时候,你可以指定虚拟用户组的名称。当从用户脚本生成器运行脚本的时候,虚拟用户组名称总是None。
    3、 Load Generator Name
      Load Generator Name用脚本负载生成器的名称替换参数。负载生成器是虚拟用户在运行的计算机。
    4. Iteration Number
      Iteration Number用当前的迭代数目替换参数。
    5、 Random Number
      Random Number用一个随机数替换参数。通过指定最大值和最小值来设置随机数的范围。
    6、 Unique Number
      Unique Number用一个唯一的数字来替换参数。你可以指定一个起始数字和一个块的大小。
    7、 Vuser ID
      Vuser ID用分配给虚拟用户的ID替换参数,ID是由Loadrunner的控制器在scenario运行时生成的。如果你从脚本生成器运行脚本的话,虚拟用户的ID总是-1。
    五、数据文件
      数据文件包含着脚本执行过程中虚拟用户访问的数据。局部和全局文件中都可以存储数据。可以指定现有的ASCII文件、用脚本生成器创建一个新的文件或者引入一个数据库。在参数有很多已知值的时候数据文件非常有用。数据文件中的数据是以表的形式存储的。一个文件中可以包含很多参数值。每一列包含一个参数的数据。列之间用分隔符隔开,比如说,用逗号。
      对数据文件设置参数属性
      如果使用文件作为参数的数据源,必须指定以下内容:文件的名称和位置、包含数据的列、文件格式,包括列的分隔符、更新方法。
      如果参数的类型是“File”,打开参数属性(Parameter Properties)对话框,设置文件属性如下:
    1、 在“File path”中输入文件的位置,或者点击“Browse”指定一个已有文件的位置。缺省情况下,所有新的数据文件名都是“parameter_name.dat”,注意,已有的数据文件的后缀必须是.dat。
    2、点击“Edit”。记事本打开,里面第一行是参数的名称,第二行是参数的初始值。使用诸如逗号之类的分隔符将列隔开。对于每一新的表行开始一行新的数据。
      注意:在没有启动记事本的情况下如果想添加列,就在参数属性对话框中点击“Add Col”,那么“Add new column”对话框就会弹出。输入新列的名称,点击“OK”。脚本生成器就会添加该列到表中,并显示该列的初始值。
    3、 在“Select Column”部分,指明包含当前参数数据的列。你可以指定列名或者列号。列号是包含你所需要数据的列的索引。列名显示在每列的第一行(row 0)。
    4、 在“Column delimiter”中输入列分隔符,你可以指定逗号、空格符等等。
    5、 在“First data line”中,在脚本执行的时候选择第一行数据使用。列标题是第0行。若从列标题后面的第一行开始的话,那就在“First data line”中输入1。如果没有列标题,就输入0。
    6、 在“Select next row”中输入更新方法,以说明虚拟用户在脚本执行的过程中如何选择表中的数据。方法可以是:连续的、随机的、唯一的、或者与其它参数表的相同行。
      6.1、顺序(Sequential):该方法顺序地给虚拟用户分配参数值。如果正在运行的虚拟用户访问数据表的时候,它会取到下一行中可用的数据。
      6.2、随机(Random):该方法在每次迭代的时候会从数据表中取随机数
      6.3、 使用种子取随机顺序(Use Random Sequence with Seed):如果从Loadrunner的控制器来运行scenario,你可以指定一个种子数值用于随机顺序。每一个种子数值在测试执行的时候代表了一个随机数的顺序。无论你何时使用这个种子数值,在scenario中同样的数据顺序就被分配给虚拟用户。如果在测试执行的时候发现了一个问题并且企图使用同样的随机数序列来重复测试,那么,你就可以启动这个功能(可选项)。
      6.4、唯一(Unique):Unique方法分配一个唯一的有顺序的值给每个虚拟用户的参数。
      6.5 、与以前定义的参数取同一行(Same Line As <parameter>):该方法从和以前定义过的参数中的同样的一行分配数据。你必须指定包含有该数据的列。在下拉列表中会出现定义过的所有参数列表。注意:至少其中的一个参数必须是Sequential、Random或者Unique。
        如果数据表中有三列,三个参数定义在列表中:id1,name1和title1,如下:。
    ID Name Title
    132 Kim Manager
    187 Cassie Engineer
    189 Jane VP
        对于参数id1,你可以指示虚拟用户使用Random方法,而为参数name1和title1就可以指定方法“Same Line as id1”。所以,一旦ID“132”被使用,那么,姓名(Name)“Kim”和职位(Title)“Manager”同时被使用。
    7、Updta value on数据的更新方法
    7.1、Each iteration――每次反复都要取新值
    7.2、Each occurrence――只要发现该参数就重新取值
    7.3、Once――在所有的反复中都使用同一个值
    8、When out of values超出范围:(选择数据为unique时才可用到)
    8.1、Abort Vuser――中止
    8.2、Continue in a cyclic manner――继续循环取值
    8.3、Continue with last value――取最后一个值
    9、Allocate Vuser values in the Controller在控制器中分配值:(选择数据为unique时才可用到)
      9.1、 Automatically allocate block size――自动分配
      9.2、Allocate()values for each Vuser――指定一个值
    六、从已存在的数据库中导入数据
      Loadrunner允许你利用参数化从已经存在的数据库中导入数据。可以使用下列两种方式之一:
    1、 使用Microsoft Query(要求在系统上先安装MS Query)。
    2、 指定数据库连接字符串和SQL语句。
        用户脚本生成器在从数据库中导入数据的过程中提供了一个向导。在向导中,你指明如何导入数据-通过MS Query创建查询语句或者直接书写SQL语句。在导入数据以后,以.dat为后缀并作为正规的参数文件保存。要开始导入数据库中数据的过程,在参数属性对话框中点击“Data Wizard”,则,数据库查询向导弹出。
      要创建新的查询
    1、 选择“Create new query”。如果需要MS Query的帮助,选择“Show me how to use Microsoft Query”,然后点击“Finish”。
    如果你还没有安装Microsoft Query,Loadrunner会提示你这个功能不可用。在进行之前,从Microsoft Office中安装MS Query。
    2、 在Microsoft Query中遵循以下步骤,导入期望的表和列。
    3、 在完成数据的导入后,选择“Exit and return to Virtual User Generator”,然后点击“Finish”。在参数属性对话框中数据库记录以data文件的形式显示出来。
    要在MS Query中编辑并查看数据,选择“View data or edit in Microsoft Query”。若要结束,则选择“File>Exit and return to Virtual User Generator”返回到脚本生成器。
    4、 在“Select Column”部分,指定包含当前参数数据的列可以指定列号或者列名。注意:列标题默认为第0行(row 0)。
    5、 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。其中每一项的含义文章前面已经讲述,就不再赘述。
    6、 如果选择“Advance row each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
      要指定数据库连接或者SQL语句
    1、 选择“Specify SQL Statement”,然后点击“Next”。
    2、点击“Create”指定一个新的连接字符串。选择数据源的窗口弹出。
    3、选择已有的数据源,或者点击“New”创建一个新的数据源。向导将提示你穿过创建ODBC数据源的过程。在完成后,连接字符串就会在连接字符串框中显示出来。
    4、 在SQL框中,输入或者粘贴SQL语句。
    5、点击“Finish”继续SQL语句并导入数据。数据库记录将以data文件的形式显示在参数属性框中。
    6、 在“Select Column”部分中,指定包含当前参数数据的列。你可以指定列号或者列名。
    7、 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。
    8、 如果从Update out of values中,选择“each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
     
  • LoadRunner脚本解释分析

    guobin_it 发布于 2008-01-11 19:00:18

    1、获得网站首页
        web_url("www.seventest.net",
            "URL=www.seventest.net/",
            "TargetFrame=",  //
    目标窗口 _BLANK: 打开一个新窗口
                                              _PARENT:
    取代最后一个窗口的父窗口
                                              _SELF:
    取代最后一个窗口

                                              _TOP:
    取代整个页面
            "Resource=0",            //URL
    是否为一个资源  0:不是

                                                         1:

            "RecContentType=text/html", //
    录制过程中,响应报头内容格式
            "Referer=",                 //
    提交网页的URL
            "Snapshot=t1.inf",          //
    快照文件名

            "Mode=HTML",                //
    录制水平: HTML or HTTP.

    HTML level: 指导VuGen录制直观的HTML动作,录制web_url,web_link,web_image。返回的是HTML 页面,而不是脚本和程序。
    HTTP level:
    指导VuGen录制全部的服务器响应。不产生web_link,web_image,web_submit_form。比HTML高级,但当读脚本时不是很直观。
            EXTRARES,                   //
    参数表划分标志(下个标志是一个资源特征表)
           "Url=/dy.css", "Referer=http://www.seventest.net/index.htm", ENDITEM,     //
    资源结束志
       
           "Url=/images/bg_03.gif", "Referer=http://www.seventest.net/index.htm", ENDITEM, 
           "Url=/images/logo-end%2020GAI.swf","Referer=http://www.seventest.net/index.htm", ENDITEM,
            "Url=/images/2.swf", "Referer=http://www.seventest.net/index.htm", ENDITEM,
            LAST);                      //
    特征表结束标志

    2、下载一个游戏
    web_url("Games",
           "URL=ftp://joe:secret@mygames.com/games/archive/loderunner.exe",
           "FtpAscii=1",         //1:
    ASCII模式执行FTP传输
                                            //0:
    二进制模式
           LAST);

    3、百度搜索科学
    Action()
    {
        //
    打开首页

     web_add_cookie ("BAIDUID=AAFDECDD16EF55636CA63DC64381BBEC:FG=1; DOMAIN=www.baidu.com");

    web_add_cookie("BDSTAT=7e00ef72b41d6156ecc574f4a7efce1b9d16fdfaaf51f3debd8f8c5497eef01f3a292df5e2fe587d;DOMAIN=www.baidu.com");

                                 //网络接口的对象表达式,经常用在JavaVB.

                                 //name=VALUE; 必须
                                  //domain=DOMAIN_NAME;
    必须
                                  //expires=DATE;
                                  //path=PATH; (default path is "/")
                                  //secure
                                 //The elements in the Cookie parameter are the same as the elements in the
                                 //Set–Cookie HTTP Response Header.

     web_url("www.baidu.com",
      "URL=http://www.baidu.com/",  
      "TargetFrame=",
      "Resource=0",
      "RecContentType=text/html",
      "Referer=",
      "Snapshot=t1.inf",
      "Mode=HTML",
      EXTRARES,
      "Url=/favicon.ico", "Referer=", ENDITEM,
      LAST);

     web_add_cookie("BAIDUID=AAFDECDD16EF55636CA63DC64381BBEC:FG=1; DOMAIN=s.baidu.com");

     web_add_cookie("BDSTAT=7e00ef72b41d6156ecc574f4a7efce1b9d16fdfaaf51f3debd8f8c5497eef01f3a292df5e2fe587d;

    DOMAIN=s.baidu.com");

     lr_think_time(13);
       //
    搜索科学

     web_submit_data("s",         //
    提交数据

      "Action=http://www.baidu.com/s",    //
    提交数据的HTTP address
      "Method=GET",
      "EncType=",                       //
    编码方式

      "TargetFrame=",
      "RecContentType=text/html",
      "Referer=http://www.baidu.com/",
      "Snapshot=t2.inf",
      "Mode=HTML",               //
    录制水平
      ITEMDATA,
      "Name=wd", "Value=?", ENDITEM,
      "Name=cl", "Value=3", ENDITEM,
      EXTRARES,
      "Url=http://s.baidu.com/w.gif?path=http://www.baidu.com/s?wd=%BF%C6%D1%A7&cl=3&t=1200288916042",

    "Referer=http://www.baidu.com/s?wd=%BF%C6%D1%A7&cl=3", ENDITEM,
      LAST);

     return 0;
    }

     

  • LoadRunner案例分析之一

    rickyzhu 发布于 2007-05-14 15:07:52

    昨天和Zee兄交流的时候,探讨了最近无忧测试论坛上的两个问题,我们俩的看法基本一致.

    第一个问题:是如何利用LoadRunner判断HTTP服务器的返回状态. 两种方法,第一种方法是利用LR的内置函数web_get_int_property, 如下是一个简单的例子:

    Action.c
    {
    int HttpRetCode;
    web_url(”my_home”, “URL=http://my_home”, “TargetFrame=_TOP”, LAST);
    HttpRetCode = web_get_int_property(HTTP_INFO_RETURN_CODE);
    if (HttpRetCode == 200)
    lr_log_message(”The scrīpt successfully accessed the My_home home page”);
    else
    lr_log_message(”The scrīpt failed to access the My_home home page “);
    }

    另外一种就是最原始的办法,也是Zee兄这种高手才最先想到的,自己取HTTP服务器的数据,然后利用关联函数分析啊. (果然是高啊). 其实所有的东西都可以从服务器的返回取,然后自己动手解析,呵呵. 举个不太恰当的例子: 你需要一套家具,可以去家具市场挑,当然也可以自己买木材原料和工具,动手加工. 那才是最合乎自己需要的. 这样一比喻, Zee兄弟似乎成了木匠了,嘻嘻~~

    第二个问题:动态数据参数化的问题.

    其实第一次看到这个问题,我没有马上反应过来,后来仔细想想, 明白了. 就是需要参数化的数据不是静态的,是动态的. 比如从数据库中选出来的.

    针对这个问题,我跟Zee兄弟的看法一致,应该提前从数据源(比如数据库)把数据选取出来,然后在执行的时候直接进行参数化的选取. 反之,如果在程序执行期间,进行数据的选取,将可能带来数据库服务器的强大压力,因为参加并发执行的每个虚拟用户都去数据库搜刮一下,对数据库将是多么严 峻的考验啊.

    朋友或者同事之间的探讨是加深对问题理解和增加知识面,扩展视野最直接的途径和方法,加强沟通,keep in touch.

    原帖:

    http://www.rickyzhu.com/2007/03/23/case-one-of-loadrunner/

  • SQL存储过程相关

    zibeike 发布于 2007-09-27 17:57:34

    http://blog.csdn.net/fbysss/archive/2006/07/08/892750.aspx

    作者fbysss
    msn:jameslastchina@hotmail.com 
    blog:blog.csdn.net/fbysss
    声明:本文由fbysss原创,转载请注明出处
    关键字:SQL语句
           好久不写复杂的sql语句,以至于很多东西都忘记。以至于写出@name="sss"来(应该使用单引号)
    还是写日志好,一些小的知识点很快可以查到,所以有机会就赶紧贴上来,顺便给需要的人参考。
    下面这段很简单,但是很容易陷入@@rowcount的“想当然”陷阱。
    declare
    @uid int,
    @examid int,
    @ugid int,
    @name varchar(50),--这里必须指定长度,否则默认为1,比如set @name='sss'会截取为's'
    @username varchar(50),
    @row_count int--临时变量
    set @uid =9008
    set @examid = 0
    set @ugid=1
    set @name='sss'
    set @username='sss'
    select uid from userinfo where examid=@examid and len(ltrim(rtrim(examid)))>0
    --注意这里本来想用一句 select  @uid =  uid from userinfo where examid=@examid and len(ltrim(rtrim(examid)))>0了事,但是那样的话,就算后面没有记录,@@rowcount也变成了1。
    set @row_count= @@rowcount
    /*if  @@rowcount = 0--这里要千万注意,因为@@rowcount随时可能改变,所以应该使用一个变量来保存记录数
    比如下面三句
    1.set @row_count= @@rowcount
    2.if @@rowcount = 0
    3.print @@rowcount
    如果1得到的记录数为0,那么print的结果是0
    但是,这里也许和想象有点不一样,@@rowcount为0不是因为前面的select语句没有记录,而是因为if @@rowcount=0这句没有对数据行的影响!
    这么写很有隐患,应该使用变量来保存结果
    */

    print 'debug1:rowcount:'+str(@@rowcount)
    if @row_count =0
    begin  
           
     print 'debug2:rowcount:'+str(@@rowcount)
     print '建立用户,建立用户组关联'
     select  @uid =  uid from userinfo where examid=@examid and len(ltrim(rtrim(examid)))>0
     insert into userinfo (name,username,examid) values (@name,@username,@examid)  --插入用户表 
     insert into usergroup_rela (uid,ugid) values (@@identity,@ugid) --加入用户组
    end
    else
    begin
            print '用户已经存在,建立用户组关联'
            select uid from usergroup_rela where uid = @uid and ugid=@ugid
            if @@rowcount = 0
     begin  
                insert into usergroup_rela (uid,ugid) values (@@identity,@ugid) --加入用户组
    --(@@identity可以得到刚刚insert 进去的id值(由数据库自动生成)

            end
     else             print '用户组关联已经存在'
    end    

     

  • LoadRunner编程之跳出迭代

    zibeike 发布于 2008-02-13 16:48:57

        LoadRunner中提供了函数exit(-1)来结束迭代。 使用return 0 来结束本次迭代,进入下一次迭代。

    例子如下:

        在运行时设置中,设置迭代次数为5,运行下面的脚本:

        int i;
        char aaa[]="test"; 
    Action()
    {

        i=0;
        if (i==0) {
        exit(-1);
        }
       
     lr_output_message("value:%s",aaa);

     return 0;
    }

    结果为:

    Virtual User scrīpt started
    Starting action vuser_init.
    Ending action vuser_init.
    Running Vuser...
    Starting iteration 1.
    Starting action Action.

        只运行了一次迭代,就结束了。

    下面的代码:

        int i;
        char aaa[]="test"; 
    Action()
    {

        i=0;
        if (i==0) {
        return 0;
        }
       
     lr_output_message("value:%s",aaa);

     return 0;
    }

    结果:

    Virtual User scrīpt started
    Starting action vuser_init.
    Ending action vuser_init.
    Running Vuser...
    Starting iteration 1.
    Starting action Action.
    Ending action Action.
    Ending iteration 1.
    Starting iteration 2.
    Starting action Action.
    Ending action Action.
    Ending iteration 2.
    Starting iteration 3.
    Starting action Action.
    Ending action Action.
    Ending iteration 3.
    Starting iteration 4.
    Starting action Action.
    Ending action Action.
    Ending iteration 4.
    Starting iteration 5.
    Starting action Action.
    Ending action Action.
    Ending iteration 5.
    Ending Vuser...
    Starting action vuser_end.
    Ending action vuser_end.
    Vuser Terminated.

        运行了5次迭代,但是每次迭代运行到lr_output_message("value:%s",aaa)之前都跳出迭代,进行下一次迭代。

       

  • Error in parameter [TDsrvURL]错误的一个解决方法

    zibeike 发布于 2007-10-22 16:52:09

      我这里用的TD8。0,在装TD的机器上访问TD主页没有问题,可是其他客户端访问START页面的时候,出现了如下错误:

    Error in parameter [TDsrvURL]错误(页面标题)

    错误内容的具体描述如下:Error:The RPC server is unavailable    Press OK to continue or CANCEL to  close application

    查看了网上一些资料,一些通用的方法都没有解决问题,最后在一个英文网站上大概找到个思路,而且成功解决该问题,解决方法如下:

    1。IIS信息管理器中找到TDBIN站点,属性中查看目录安全性。

    2。匿名访问和身份验证这里,点编辑出现编辑页面。

    3。选中匿名访问,匿名访问的用户我这里是空,现在修改为IUSR_XXXX,查找到这个用户添加上去就可以了。

    这里,看来,远程访问TD的时候,需要设置下这个地方呀,哈哈。解决问题了,Happing!


     

  • zibeike单元测试实践一:您的第一个单元测试

    zibeike 发布于 2008-08-25 20:40:04

         本系列课程是以《Pragmatic Unit Testing In C# with NUnit》这本书为基础,是zibeike在翻译和理解的基础上整理而来,希望对大家有些帮助,内容还是很多的。好的,那下面开始我们的单元测试之旅吧。
         您的第一个单元测试:
         单元测试是一段程序代码,这些程序代码是为了检验另一段程序代码的行为是否达到预期而写的。那么,该如何来达到这样的目的呢?
         为了检验代码的行为是否达到预期,你可以使用assertion,这是个非常简单的方法调用来验证某些事情是否是正确的。例如,方法IsTrue检查了给定的布尔条件是否是真,如果条件不为真,那验证失败。您可以象下面这样来实现这个程序:
         public void IsTrue(bool condition) {
            if (!condition) {
              abort();
            }
         }
         你可以使用断言(assert)来检查所有事情,包括数字是否互相相等等。
          int a = 2;
         IsTrue(a == 2);
         如果在调用IsTrue时,a不等于2,程序就会中止。
          因为我们是在检查是否相等,因此对这些数字使用断言会比较容易。为了检查两个整数是否相等,我们可以写一个方法,这个方法是以两个整数作为参数。
         public void AreEqual(int a, int b) {
              IsTrue(a == b);
         }
        只是用这两个断言,我们就可以开始写一些测试代码了。在下一章,我们会看到更多关于断言在单元测试代码中的使用。但是首先,我们先来思考一下在写代码之前,我们需要什么样的测试。
        1.1 测试计划
         我们来看一个简单的例子,一个静态方法用来寻找list中的最大数。
         static int Largest(int[] list);
        也就是说,给一组数,如[7,8,9],这个方法应该返回9。这是一个合理的测试。那有没有其他的测试呢?现在花一分钟,你要想出尽可能多的测试情况。
         你想出了多少测试用例呢?
         数组中的顺序不影响结果,所有你可以得到下面的想法:
        传入的数据        预期的结果
          [7, 8, 9]      9
         [8, 9, 7]       9
         [9, 7, 8]       9
    如果有两个最大值呢?
         [7, 9, 8, 9]      9
    因为是int类型的,不是对象类型,你可能不需要关心哪一个9被返
    回。
          如果只有一个数字呢?
          [1]               1
          如果是负数呢?
          [-9, -8, -7]     -7
          然后,我们来实际的写“largest”方法,并且测试它。这是我们的第一个实现的代码:
         public class Cmp f -
       ///
       /// <summary>
       /// Return the largest element in a list.
       /// </summary>
       /// <param name="list"> A list of integers    </param>
       /// <returns>
       /// The largest number in the given list
       /// </returns>
       ///
       public static int Largest(int[] list) {
       int index, max=Int32.MaxValue;
       for (index = 0; index < list.Length-1; index++) {
        if (list[index] > max) {
           max = list[index];
           }
        }
    return max;
      }
    }
         现在,我们对测试是有些了解了吧,我们下面就要学习使用NUnit框架来实现c#的测试。


    转载请注明出自zibeike的blog:http://www.51testing.com/?34866

  • LoadRunner添加Weblogic监控的注意事项(非单纯的操作步骤)

    zibeike 发布于 2008-08-21 20:31:53


      关于LR如何监控Weblogic(JMX方式)的操作就不在这里多说了,帮助文件和网上的介绍已经非常多了,关键是对各操作步骤是否理解正确以及添加过程中各种错误的原因及解决.
      1. LR的Controller机器上需要安装跟Weblogic版本一致的java虚拟机,如果安装的版本不一致,就会出现 类似 版本不匹配,某些类找不到的错误.
      2. 修改weblogicmon.ini的注意事项:
          [WebLogicMon] 下面的JVM和JavaVersion的设置,即为LR的Controller机器上安装的JVM的路径和版本,这个跟1是一致.
      3.LR8.0和8.1在添加对WebLogic9.0及以上版本的监控时,出现的计数器界面是空的,即获取不到Weblogic的性能数据,对这个问题我的推断是这样的:
        LR通过JMX方式获取Weblogic的各性能数据,而Weblogic9.0及以上版本的JMX使用的JMX1.2
        Weblogic8.1版本使用的JMX1.0,因为JMX1.2规范各API的比JMX1.0变化了很多,因此这两个不同 版本的JMX肯定是要用不同的代码去实现的,推断LR中没有支持JMX1.2的代码,因此也就无法通过JMX的方式来获取使用了JMX1.2规范的Weblogic的性能计数器的数据了.至于LR的最新版本是否支持Weblogic9.0及其以上版本,这个还没有做验证.

    本文出自zibeike的51Testing软件测试博客,转载请保留出处及链接:http://www.51testing.com/?34866
  • LoadRunner函数的介绍

    zibeike 发布于 2008-08-21 20:14:14

    LoadRunner函数

    一:通用函数

    LoadRunner的通用函数以lr为前缀,可以在任何协议中使用。可以如下分类:

    信息相关的函数:

    lr_error_message  lr_output_message

    事务函数:

    lr_start_transaction    lr_end_transaction

    运行时函数:

    lr_think_time         lr_exit

    参数相关的函数:

    lr_save_datetime  lr_advance_param  lr_eval_string  lr_save_string  lr_get_attrib_string

    一些函数的详细解释:

    1lr_error_message

    VuGen的回放日志和Controller的输出窗口发送错误信息,例子:

    lr_error_message("string");

    2lr_abort()

    中止脚本的执行。如果在Action中使用,就会中止Action的执行,而去执行vuser_end.

    3lr_exit

    退出脚本,action或者迭代。

    lr_exit(int continuation_option, int exit_status);

    4lr_save_string

    保存指定的非空字符串到一个参数。

    lr_save_string(const char *param_value, const char *param_name);

    5lr_save_date_time

    保存日期和时间到参数中。

    lr_save_datetime(const char *format, int offset, const char *name);

    lr_save_datetime中使用偏移量

    lr_save_datetime(“Tomorrow is %B %d %Y", DATE_NOW+ONE_DAY, “nextDate");

    DATE_NOW+ONE_DAY:当前日期的偏移量

    如果现在的时间是:2008年二月27

    nextDate 中保存的时间为:Tomorrow is 二月 28 2008

    6lr_advance_param

    lr_advance_param (const char * param);

    其中参数用双引号,但不用括号。

    7lr_eval_string

    lr_eval_string("{parameter_name}");

    返回指定参数的当前字符串值。

    检索参数值,可以使用来下面的函数打印该输出到输出信息中。

    lr_output_message 或者lr_error_message

    8lr_get_attrib_string

    lr_get_attrib_string (const char * argument);

    二.特定协议的函数

    这类函数跟录制的协议类型有关系。

    Web协议:以web为前缀

    lrd是数据库相关的函数,lrswindow socket协议的函数。

    web_reg_save_param(const char *ParamName,LB,RB,ORD,SaveLen,SaveOffset, LAST);

    例子:

    web_reg_save_param("flight_name", "LB=Select your departure ", "RB="", LAST);

    web_reg_find:

    web_reg_find(“Text=Welcome”, SaveCount, LAST);

     

  • LoadRunner中HTTP协议的录制及两种录制模式的比较

    zibeike 发布于 2008-08-21 20:06:52

    一,脚本编写

    1,  HTML –base scrīpt”和“URL-base scrīpt”的区别

    1)“HTML –base scrīpt”默认模式,为每个用户请求生成单独的函数

    如:

    Action()

    {

    web_url("WebTours",

            "URL=http://127.0.0.1:1080/WebTours/",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=",

            "Snapshot=t4.inf",

            "Mode=HTML",

            LAST);

           web_submit_form("login.pl",

            "Snapshot=t5.inf",

            ITEMDATA,

            "Name=username", "Value=jojo", ENDITEM,

            "Name=password", "Value=bean", ENDITEM,

            "Name=login.x", "Value=53", ENDITEM,

            "Name=login.y", "Value=13", ENDITEM,

            LAST);

    return 0;

    }

    2)“URL-base scrīpt”可以捕获所有作为用户操作的结果发送到服务器的HTTP请求,然后一一记录下来。可以捕获非HTML应用程序,例如小程序和非浏览器应用程序。

    如:

    Action()

    {

     

    web_url("WebTours",

            "URL=http://127.0.0.1:1080/WebTours/",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=",

            "Snapshot=t1.inf",

            "Mode=HTTP",

            LAST);

     

    web_concurrent_start(NULL);

     

    web_url("header.html",

            "URL=http://127.0.0.1:1080/WebTours/header.html",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=http://127.0.0.1:1080/WebTours/",

            "Snapshot=t2.inf",

            "Mode=HTTP",

            LAST);

     

    web_url("welcome.pl",

            "URL=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=http://127.0.0.1:1080/WebTours/",

            "Snapshot=t5.inf",

            "Mode=HTTP",

            LAST);

     

    web_concurrent_end(NULL);

     

    web_concurrent_start(NULL);

     

    web_url("hp_logo.png",

            "URL=http://127.0.0.1:1080/WebTours/images/hp_logo.png",

            "Resource=1",

            "RecContentType=image/png",

            "Referer=http://127.0.0.1:1080/WebTours/header.html",

            "Snapshot=t3.inf",

            LAST);

     

    web_url("webtours.png",

            "URL=http://127.0.0.1:1080/WebTours/images/webtours.png",

            "Resource=1",

            "RecContentType=image/png",

            "Referer=http://127.0.0.1:1080/WebTours/header.html",

            "Snapshot=t4.inf",

            LAST);

     

    web_concurrent_end(NULL);

     

    web_concurrent_start(NULL);

     

    web_url("home.html",

            "URL=http://127.0.0.1:1080/WebTours/home.html",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",

            "Snapshot=t6.inf",

            "Mode=HTTP",

            LAST);

     

    web_url("nav.pl",

            "URL=http://127.0.0.1:1080/WebTours/nav.pl?in=home",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true",

            "Snapshot=t7.inf",

            "Mode=HTTP",

            LAST);

     

    web_concurrent_end(NULL);

     

    web_url("mer_login.gif",

            "URL=http://127.0.0.1:1080/WebTours/images/mer_login.gif",

            "Resource=1",

            "RecContentType=image/gif",

            "Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",

            "Snapshot=t8.inf",

            LAST);

     

    web_submit_data("login.pl",

            "Action=http://127.0.0.1:1080/WebTours/login.pl",

            "Method=POST",

            "RecContentType=text/html",

            "Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",

            "Snapshot=t9.inf",

            "Mode=HTTP",

            ITEMDATA,

            "Name=userSession", "Value=97276.8320777643fAADzHHpAfDAAccpAzcD", ENDITEM,

            "Name=username", "Value=jojo", ENDITEM,

            "Name=password", "Value=bean", ENDITEM,

            "Name=JSFormSubmit", "Value=off", ENDITEM,

            "Name=login.x", "Value=56", ENDITEM,

            "Name=login.y", "Value=11", ENDITEM,

            LAST);

     

    web_concurrent_start(NULL);

     

    web_url("login.pl_2",

            "URL=http://127.0.0.1:1080/WebTours/login.pl?intro=true",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=http://127.0.0.1:1080/WebTours/login.pl",

            "Snapshot=t10.inf",

            "Mode=HTTP",

            LAST);

     

    web_url("nav.pl_2",

            "URL=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",

            "Resource=0",

            "RecContentType=text/html",

            "Referer=http://127.0.0.1:1080/WebTours/login.pl",

            "Snapshot=t11.inf",

            "Mode=HTTP",

            LAST);

     

    web_concurrent_end(NULL);

     

    web_concurrent_start(NULL);

     

    web_url("in_home.gif",

            "URL=http://127.0.0.1:1080/WebTours/images/in_home.gif",

            "Resource=1",

            "RecContentType=image/gif",

            "Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",

            "Snapshot=t12.inf",

            LAST);

     

    web_url("flights.gif",

            "URL=http://127.0.0.1:1080/WebTours/images/flights.gif",

            "Resource=1",

            "RecContentType=image/gif",

            "Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",

            "Snapshot=t13.inf",

            LAST);

     

    web_url("signoff.gif",

            "URL=http://127.0.0.1:1080/WebTours/images/signoff.gif",

            "Resource=1",

            "RecContentType=image/gif",

            "Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",

            "Snapshot=t14.inf",

            LAST);

     

    web_url("itinerary.gif",

            "URL=http://127.0.0.1:1080/WebTours/images/itinerary.gif",

            "Resource=1",

            "RecContentType=image/gif",

            "Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home",

            "Snapshot=t15.inf",

            LAST);

     

    web_concurrent_end(NULL);

     

    return 0;

    }

    3)如何选择?什么时候选择url的录制方式:

    * 不是基于浏览器的

    * 基于浏览器但是包含javascrīpt,并且发送了请求到服务器

    * 使用了https 安全协议

    4)两种脚本的内容比较:

    * http脚本直观,易于理解和维护

    * url 内容多,可伸缩性强,记录了更详细的用户操作信息。

    2HTML 高级选项:

    1)  默认是选择 描述用户行为的脚本

    2)  仅包含明确的URL脚本,录制结果如下:

    Action()

    {

     

         web_url("WebTours",

                "URL=http://127.0.0.1:1080/WebTours/",

                "TargetFrame=",

                "Resource=0",

                "RecContentType=text/html",

                "Referer=",

                "Snapshot=t1.inf",

                "Mode=HTML",

                LAST);

     

     

         web_url("Update.htm",

                "URL=http://scdown.qq.com/download/Update.htm",

                "TargetFrame=",

                "Resource=0",

                "RecContentType=text/html",

                "Referer=",

                "Snapshot=t2.inf",

                "Mode=HTML",

                LAST);

     

         web_url("Update.htm_2",

                "URL=http://scdown.qq.com/download/Update.htm",

                "TargetFrame=",

                "Resource=0",

                "RecContentType=text/html",

                "Referer=",

                "Snapshot=t3.inf",

                "Mode=HTML",

                LAST);

     

         web_url("Update.htm_3",

                "URL=http://scdown.qq.com/download/Update.htm",

                "TargetFrame=",

                "Resource=0",

                "RecContentType=text/html",

                "Referer=",

                "Snapshot=t4.inf",

                "Mode=HTML",

                LAST);

     

     

         web_submit_data("login.pl",

                "Action=http://127.0.0.1:1080/WebTours/login.pl",

                "Method=POST",

                "TargetFrame=",

                "RecContentType=text/html",

                "Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home",

                "Snapshot=t5.inf",

                "Mode=HTML",

                ITEMDATA,

                "Name=userSession", "Value=97276.9197245848fAADziVpffiDDDDDDAAccpAiQDf", ENDITEM,

                "Name=username", "Value=jojo", ENDITEM,

                "Name=password", "Value=bean", ENDITEM,

                "Name=JSFormSubmit", "Value=off", ENDITEM,

                "Name=login.x", "Value=52", ENDITEM,

                "Name=login.y", "Value=8", ENDITEM,

                LAST);

     

         return 0;

    }

    3,录制header

       默认设置是不录制, 选择需要录制的Headers,以便服务器能够正确处理编码信息。需要注意的是“accept-language,websphere这类服务器会根据HTTP   请求中的Header来确定编码。

  • LoadRunner的Oracle(2-tier)协议脚本排错实例

    zibeike 发布于 2008-08-14 14:54:49

       客户方在对一个C/S系统进行测试的时候,使用Oracle(2-tier)协议进行录制,回放脚本时候出错.于是到现场进行脚本排错.因为是隔了很长时间才记录这次排错过程,具体的脚本和错误信息都没有保存,所以记录过程中可能会少些原始脚本和错误的信息.

       1.查看录制的脚本,发现使用该协议是可以录制产生数据库各种操作的脚本,说明协议选择是正确的.

       2.回放时出现一个错误,具体错误信息忘记了.然后就开始从头到尾的分析脚本,因为是第一次接触Oracle(2-tier)这种协议的LR脚本,分析脚本就只能靠帮助以及根据以前的数据库知识经验了。 仔细分析了在出错语句和之前的几个语句。 发现出错语句lrd_ora8_stmt(OraStm1, 。。。)这个函数的第一个参数在前面没有找到定义的地方,然后再看其他执行SQL语句的流程,执行这个语句前都需要来分配和初始化LRDDBI Handle.在错误语句前加上lrd_ora8_handle_alloc()对OraStm1声明,回放脚本,错误消失,问题解决.

      3.被测系统的某个属性需要进行修改,在LR脚本中把该数据进行了参数化.参数使用顺序取值,回放迭代多次,脚本没有报错,但实际上该参数化的属性值只有在第一次回放的时候进行了修改,之后的迭代没有对系统起作用.

      4.分析该操作是SQL语句的更新操作,于是对执行的SQL语句部分进行检查分析.通过和客户沟通以及参考技术文档找到了数据库表和显示界面中各属性的对应关系.然后查看该更新的SQL语句发现,LR录制的SQL更新语句中使用了很多数据库字段为查询条件,除了使用唯一确定该条记录的ID外,还把被修改的字段也作为了查询条件,很明显这样第一次执行的时候是可以执行成功的.但再执行的时候由于该字段内容已经被更新,这样也就找不到以原来更新前的内容为查询条件的记录了. 删除WHERE语句中以被更新内容为条件的这个条件,再次运行LR迭代.脚本成功修改了被测系统的数据.这样所有错误都排除了.

      当然之后就是按照客户要求对该系统进行了性能测试,这个过程没有遇到什么问题,就不多说了.

  • LoadRunner脚本编写(6)— 数据类型转换和字符串操作

    zibeike 发布于 2008-07-09 16:05:57

     

    一,数据类型转换

    没有使用过C编程的LoadRunner脚本编写者会发现在数据类型转化方面比较困难。下面介绍这方面的知识。

    1.  相似函数的输出在不同的位置

    象很多C函数一样,使用atoi函数的结果即为返回值

    intResult = atoi( charY );

    而:itoa的返回结果为第二个参数。

    itoa( intX, charY, 10);

       第一个参数是需要转换的数字,第二个参数是转换后存储的字符数组,需要注意的是数组必须定义为固定的长度,如:char chary[20]

    数组的最大长度为3206432K),否则会出现“too many variables”编译错误。

    如果定义为变长的字符串如char *charY,则程序会出错。

       第三个参数不是数组的长度,而是数字的基数,10进制是最常用的,其他还有二进制,八进制,十六进制。

    2.  有一些函数实现了同样的功能

    itoa不是一个标准的ANSI C函数但是是Cstdlib.h中的一个函数。所以它不被包括在unix机器上的LibC中。我们可以使用标准的sprintf函数来代替:

    sprintfcharY,“%d”,intX);

    3.  是用%X来转换一个十六进制数

    int intNum

    sscanf(“ffff”,“%X”,&Num;

    lr_output_message(“%d”,intNum);  // 打印65535 ,ffff的整数值

    4.  从文本中提取数字的规则

    如果第一个字符不是数字或者为空,atoi返回0,即“e24”会返回0

    atoi 转换一个非数字的字符会返回组成这个字符的数字,如“-3.2返回-3.0。“123XXX345”返回123

    5.  LoadRunner脚本中的参数必须转换成C字符串。有两种方式来转化LR的参数为C语言的数字。

      i = atoi( lr_eval_string("{pX}") );

    sprintf( intX, "%d", lr_eval_string("{pX}") );

    6.  参数的算术运算

    LoadRunner没有提供对参数的算术运算的函数。所以LR的参数必须:

    1)  转换成C的整数

    2)  使用C的函数来运算最后返回一个C的字符串

    3)  把返回的字符串保存成参数

    char cBuf[10];

    int i;

    // 1. Evaluate parameter into a C integer:

    i = atoi( lr_eval_string("{pNum_in}") );

    // 2. Do the math and output the result to a C string:

    sprintf( cBuf, "%d", i+1);

    // 3. Save the string as a parameter to be passed on:

    lr_save_string( cBuf, "pNum_out");

    //Print out the parameter value after incrementing it.

    lr_message("**** Parameter from %s to %s",

         lr_eval_string("{pNum_in}"));

         lr_eval_string("{pNum_out}"));

    zibeike注:除了对于数字类型的参数的运算之外,对于文本形式的参数的操作,可以参考我的另一篇文章的内容:http://www.51testing.com/?34866/action_viewspace_itemid_75592.html

    二.字符串操作

    C语言中,字符串是固定长度的,因为他们本身由独立的字符组成的字符数组。数组是只读的。任何修改字符串长度的函数调用都会报错:

    Error: "C interpreter runtime error - memory violation error during replay.

    LoadRunneras_web.h库中的字符串函数可以使用“prototyping”声明的方式读写内存:

    char *strtok(char *, char *); // tokenizer prototype
    char *strstr(char *, char *); // substring prototype
    char *strdup(char *); // String duplication prototype
    float atof(); // alpha to return float datatype
    #include "as_web.h"
    char *strtok(char *, char *); // prototype function call.
     
    ActionX()
    {
       char aBuffer[256]; // input string to be parsed.
        char *cToken; // individual token from strtok.
       char cSeparator[] = " "; // blank separator.
       int i; // incrementer
       char val[3][20]; // output array of strings.
       char modified_val[20]; 
        
       // Create a parameter named pDate:
       lr_save_string("January 2, 2001", "pDate");
     
       // Put parameter into a string buffer:
       strcpy( aBuffer,lr_eval_string("{pDate}"));
     
       // Show the buffer for debugging:
       lr_output_message("%s\n",aBuffer);
     
       // get first word (to the first blank):
        cToken = strtok( aBuffer,cSeparator); 
       i = 1;
     
       if(!token) { // first token was not found:
               lr_output_message("No tokens found in string!");
               return( -1 );
       } else {
               while( cToken != NULL) { // tokens are not NULL:
                       lr_output_message("Token=%s", cToken);
     
                       // Stuff in another array:
                       strcpy( val[i], cToken ); 
     
                       // Get next token:
                       cToken = strtok( NULL, cSeparator); 
                       i++; // increment 
               }
               lr_output_message("Val #1 is: %s", val[1]);
               lr_output_message("Val #2 is: %s", val[2]);
               lr_output_message("Val #2 is: %s", val[3]);
     
               strncpy( modified_val, val[2], 1 );
               modified_val[2] = '\0';
               while (modified_val[2] != NULL) {
                       lr_output_message("===>%s", modified_val);
                       modified_val[2] = strtok(NULL, " ");
               }
       }
       return 0;
    }

    strcat 连接两个字符串

    strchr 返回指向第一个要查找的字符出现的位置的指针

    strcmp 比较两个字符

    strcpy 复制字符串到另一个

    stricmp 执行一个大小写敏感的比较

    其他还有strdupstrncatstrncpystrnicmpstrrchrstrsetstrspnstrstr等字符串操作的函数。

    zibeike注:关于更多字符串操作的脚本编写,可以参考我的另一篇文章:

    http://www.51testing.com/?34866/action_viewspace_itemid_75428.html

    zibeike翻译自:http://www.wilsonmar.com/1lrscrīpt.htm

  • LoadRunner脚本编写(5)-- 检查点,关联等函数

    zibeike 发布于 2008-07-07 22:46:35

    本文接着前面脚本编写4 http://www.51testing.com/?34866/action_viewspace_itemid_70224.html来继续翻译wilsonmar的文章。其中在翻译过程中,都以zibeike注的方式添加了自己对相关知识点的一些经验和理解。转载请注明作者zibeike和出处,谢谢。

    1.  错误预防和恢复

    参数默认是用{}括起来的,但也可以指定用<>

    NTLM或用户登录验证

    web_set_user("X\\Y", "Z", "A.com:80");

    在域与X上的用户名为Y的用户,使用密码Z来登录到A.com:80。在windows基本验证的时候这个脚本被默认录制下来,但如果web服务器需要更安全的NTLM或更深层次的验证,需要手动的添加这个函数到脚本中。对于NTML验证,用户名必须在域名之后,并且以\分割。使用\等符号,需要使用\\,前面的\用来做转义用,否则会出现警告提示。

     

    zibeike注:在论坛中也看到了一些朋友讨论windows弹出登录框的操作LR无法录制到,导致回放出错,一般出错信息多为“Error -26547: Authentication required, please use web_set_user, e.g. web_set_user("domain\\user", "password", "host:port");   [MsgId: MERR-26547]”,其实这种情况错误信息已经很明显的给你提示了,需要往脚本中添加web_set_user函数即可。

     

    2.  IP欺骗(略)

    3.  验证检查点

    通常脚本录制完后需要手动添加些脚本来来确保预期的操作确实进行了正确的响应(如在操作之后后验证显示的一段文本或者图片)。这些检查可以使用正则表达式。

    Web虚拟用户脚本中不会录制到检查点,需要手动添加或者使用VuGen的用户接口来添加函数代码。

    最常用的检查点函数是web_reg_find。这个注册函数会查找脚本中下一个操作如web_url后产生的一段文本。它是从返回的缓冲区扫描而不是在接收的页面中查找。这是比web_find更高效的一个函数。

    可以使用下面的代码来验证文本出现的次数:

    • web_reg_find("Text=ABC", "SaveCount=abc_count", LAST);
      web_url("Step", "URL=...", LAST);
      if (strcmp(lr_eval_string("{abc_count}"), "0") == 0)

    lr_output_message("not found");

    else

    lr_output_message("{abc_count} found");

    如果想保存并且显示找到的文本,可以使用web_reg_save_param界定左右边界把找到的信息保存到参数中。如下:

    • char *str1,*str2;
      str1="desired text";
      // Register the left and right beacons sought:
      web_reg_save_param("param","LB/ic=xxx","RB=xxx");
      // Do the monitored deed:
      web_url("some url","URL=www.xxx.com",LAST);
      // Compare:
      str2=lr_eval_string("{param}");
      if(strcmp(str1,str2)==0) {

    lr_output_message("param found");

    }else{

    lr_output_message("Value found is %s",str2);

    }

    zibeike注:1)这里想跟大家说下注册函数,在web/http协议的脚本中,注册函数均以web_reg为前缀,这种注册型的函数都是从缓冲区扫描或者获得数据,因此需要提前声明即需要在能获得该查找信息的函数之前添加这些注册函数。例如,web_url()请求了一个页面,我需要验证该页面中是否有某个特定的文本,那需要在web_url()函数之前加上web_reg_find,类似的还有关联的函数web_reg_save_para是一样的,需要放到能获得想要的数据的请求的函数之前。但如果想查看这些函数最终保存的结果,如想打印关联函数web_reg_save_para中保存的参数内容,打印的操作就需要放到请求的函数之后了。

    2web_findweb_reg_find的区别:前面的是查找页面显示的数据,因此需要放在请求页面的函数之后,而且查找的信息是显示的web页面上的信息。后者是注册型函数,需要放到请求的页面之前,而且查找的内容是服务器返回的缓冲数据中查找,所以查找内容应该看html源代码的内容。

    基于HTML录制方式的代码,可以使用web_image_checkHTML页面中包含的图片进行验证。并且需要注意的是只有在Runtime Settings > Internet Protocol Preferences 选择了"Enable Image and text check" 检查点才有效。

       

        下面会讲到数据类型转换,字符串操作等LoadRunner脚本编写知识,今天就到这里了。


    本文为zibeike原创,转载请注明出处:http://www.51testing.com/?34866

  • LoadRunner如何在大负载下测试

    zibeike 发布于 2008-06-10 14:36:10

       在大负载中使用LoadRunner进行负载测试,需要配置一些环境来满足大负载下各种资源的充足:

    1.为了避免出现“No Buffer Space Available”的错误,需要进行如下配置:

       1)修改注册表:

          * 设置“HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Par
    ameters\TcpTimedWaitDelay”为 30
          * 设置“HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Par
    ameters\MaxUserPort”为 65534
          * 在“HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session
    Manager\Sub Systems\Windows”设置SharedSection 为 4096

        2)通过在每个脚本的开头添加如下函数来设置“SHUTDOWN”模式为"ABRUPT"

         web_set_sockets_option(“SHUTDOWN_MODE”,”ABRUPT”)

     2.关闭所有的杀毒,反间谍扫描软件等。同时也关闭任务扫描和所有不需要的服务。

     3.脚本运行时设置:

       1)设置日志为“只在错误发生时发送信息” 

       2)去掉错误时产生snapshot的选项

       3)在miscellaneous上,去掉 定义每一步为一个事务 的选项

       4)不选择 模拟浏览器缓存,选上“simulate new user on each iteration”和它的子选项

     4.如果下载的页没有资源,在web_url函数中添加“Mode=HTTP”,这样会减少LG上的负载(不用转换成HTML)。默认情况下,web_url的Mode为Mode=HTML

     5.重启LG并且确保他们都能跟Controller连接.

     6.确保LG和控制器上有足够的剩余磁盘空间.

     7.在controller中去掉web page breakdown

     8.限制Vuser在所有LG上同时进行初始化的数目.可以在Controller的Tools > Options > Run-Time Settings中进行修改.每个LG都有这个设置.

     9.限制controller在运行时存储的错误数.通过修改wlrun.ini中的[output]项来实现:

      • FlagLimitOutputMessages=1
      • MaxNumberOfOutputMessages=<errors count> (default is 10,000)

     10.在Controller上修改Monitor的采样率来降低CPU的使用.可以在Controlller的Tools > Options > Monitors 下修改,如下图所示:

    11. 如果有很多错误产生,最好不要经常打开Error/Output窗口,因为这样会因为访问数据库而打开另外的数据库连接.

    12.负载测试中不要使用"Show Vuser"选项.

    13.把输出信息重定向到一个文本文件中来代替输出到mdb文件中.可以在wlrun7.ini中修改[output]下的

    ExportMessageToFile=1来实现.

    14.不要在Controller机器上运行虚拟用户.

    15.在场景中设置监视器:

      * 内存使用上 mmdrv进程的private bytes

      * disk使用

      * CPU使用

      * 网络使用

    16.把脚本中所与打印信息的脚本去掉.如下面的代码每次迭代都会调用一次,对大量并发用户的运行产生负面的影响.

    lr_vuser_status_message("pIteration: %s -
    START Action", lr_eval_string("{pIteration}"));
    lr_output_message("pIteration: %s - START Action", lr_eval_string("{pIteration}"));

    Controller处理所有虚拟用户的信息,这样会大大降低Controller的性能. 如下是类似的代码:

    web_reg_find("Text=Time on Server", "SaveCount=cErr", ..);
    web_url( some url …);
    if (atoi(lr_eval_string("{cErr}"))>0) {
    lr_error_message(some message);
    lr_end_transaction("S05_T01_Request_Content_Page", LR_FAIL);
    }

      通常认为在脚本中插入lr_error_message是不好的,除非是调用的客户化的API失败了才有必要插入该语句.如果是LoadRunner的函数调用失败(如上面的web_url调用),它会自动发送一个错误消息.

      在大量用户运行的情况下,控制Controller和LG之间的通信流量是非常重要的.发送多余的信息(错误,输出等信息)会增大通信流量降低负载能力.所以,通常都需要把代码中不必要的信息去掉.

    17.去掉脚本中所有的sleep()的调用,用lr_think_time()来代替.lr_think_time给LR让出控制,即LR能够在Vuser休眠的时候去做其他有用的事情.

    18.不要去掉lr_think_time:使用该函数能更准确的模拟负载,对LG产生相对小的压力

    19.web_reg_save_param和web_reg_find()函数:

       • 在 web_reg_save_param() 中添加“Notfound=empty” 参数.
       • 在 web_reg_find() 添加 "Savecount=some_parameter_name". 如果你想知道它是否成功可以使用atoi(lr_eval_string("{some_paramater_name }"))来衡量.

    20.其他

      可能会出现的问题:

       * 测试产生了太多的错误:

         错误引擎不能处理多于1.5GB的错误

         如果测试过程中每秒产生多与1000个错误,Controller的行为将不可预测

       * 测试产生了大量的在线数据

     上面的两个问题都可以使用如下的方法解决:

       例如: 场景是一个组有1000个虚拟用户

       可以把这个组分成两个组:

       G1 100 Vusers
       G2 900 Vusers

       这两个组可以跟原始的组产生一样的负载,对于G2在组命令行中添加如下参数:

       -disable_data -disable_messages

        _disable_data : 让这个组不发送任信息,不发送任何online信息,不写任何offline信息.

        _disable_message: 让这个组不给Controller发送任何信息(错误,日志)

    注意:使用上面的命令行选项会使该LG不给congtroller发送online和offline信息.这样这个组上的虚拟用户的分析数据就收集不到了.

    21.如果需要远程访问,Mercury仅支持PC anywhere.

    翻译自<LoadRunner Large Load Test Considerations>

      

       

     

751/41234>

数据统计

  • 访问量: 7972
  • 日志数: 19
  • 文件数: 3
  • 建立时间: 2008-06-25
  • 更新时间: 2008-10-14

RSS订阅

Open Toolbar