发布新日志

  • 软件测试中服务器稳定性测试方法

    2010-01-29 15:14:31

    服务器稳定性是最重要的,如果在稳定性方面不能够保证业务运行的需要,在高的性能也是无用的。

      正规的服务器厂商都会对产品惊醒不同温度和湿度下的运行稳定性测试。重点要考虑的是冗余功能,如:数据冗余、网卡荣誉、电源冗余、风扇冗余等。

      一些测试方法主要分以下几种:

      压力测试:已知系统高峰期使用人数,验证各事务在最大并发数(通过高峰期人数换算)下事务响应时间能够达到客户要求。系统各性能指标在这种压力下是否还在正常数值之内。系统是否会因这样的压力导致不良反应(如:宕机、应用异常中止等)。

      Ramp Up 增量设计:如并发用户为75人,系统注册用户为1500人,以5%-7%作为并发用户参考值。一般以每15s加载5人的方式进行增压设计,该数值主要参考测试加压机性能,建议Run几次。以事务通过率与错误率衡量实际加载方式。

      Ramp Up增量设计目标: 寻找已增量方式加压系统性能瓶颈位置,抓住出现的性能拐点时机,一般常用参考Hits点击率与吞吐量、CPU、内存使用情况综合判断。模拟高峰期使用人数,如早晨的登录,下班后的退出,工资发送时的消息系统等。

      另一种极限模拟方式,可视为在峰值压力情况下同时点击事务操作的系统极限操作指标。加压方式不变,在各脚本事务点中设置同集合点名称(如:lr_rendzvous("same");)在场景设计中,使用事务点集合策略。以同时达到集合点百分率为标准,同时释放所有正在Run的Vuser。

      稳定性测试:已知系统高峰期使用人数、各事务操作频率等。设计综合测试场景,测试时将每个场景按照一定人数比率一起运行,模拟用户使用数年的情况。并监控在测试中,系统各性能指标在这种压力下是否能保持正常数值。事务响应时间是否会出现波动或随测试时间增涨而增加。系统是否会在测试期间内发生如宕机、应用中止等异常情况。

      根据上述测试中,各事务条件下出现性能拐点的位置,已确定稳定性测试并发用户人数。仍然根据实际测试服务器(加压机、应用服务器、数据服务器三方性能),估算最终并发用户人数。

      场景设计思想:

      从稳定性测试场景的设计意义,应分多种情况考虑:

      针对同一个场景为例,以下以公文附件上传为例简要分析场景设计思想:

      1)场景一:已压力测试环境下性能拐点的并发用户为设计测试场景,目的验证极限压力情况下测试服务器各性能指标。

      2)场景二:根据压力测试环境中CPU、内存等指标选取服务器所能承受最大压力的50%来确定并发用户数。

      测试方法:采用1)Ramp Up-Load all Vusers simultaneously

      2)Duration-Run Indefinitely

      3)在Sechedule-勾选Initalize all Vusers before Run

      容错性测试:通过模拟一些非正常情况(如:服务器突然断电、网络时断时续、服务器硬盘空间不足等),验证系统在发生这些情况时是否能够有自动处理机制以保障系统的正常运行或恢复运行措施。如有HA(自动容灾系统),还可以专门针对这些自动保护系统进行另外的测试。验证其能否有效触发保护措施。

      问题排除性测试:通过原有案例或经验判断,针对系统中曾经发生问题或怀疑存在隐患的模块进行验证测试。验证这些模块是否还会发生同样的性能问题。如:上传附件模块的内存泄露问题、地址本模块优化、开启Tivoli性能监控对OA系统性能的影响等等。

      测评测试是用于获取系统的关键性能指标点,而进行的相关测试。主要是针对预先没有明确的预期测试结果,而是要通过测试获取在特定压力场景下的性能指标(如:事务响应时间、最大并发用户数等)。

      评测事务交易时间:为获取某事务在特定压力下的响应时间而进行的测试活动。通过模拟已知客户高峰期的各压力值或预期所能承受的压力值,获取事务在这种压力下的响应时间。

      评测事务最大并发用户数:为获取某事务在特定系统环境下所能承受的最大并发用户数而进行的测试活动。通过模拟真实环境或直接采用真实环境,评测在这种环境下事务所能承受的最大并发用户数。判定标准阈值需预先定义(如响应时间,CPU占用率,内存占用率,已出现点击率峰值,已出现吞吐量峰值等)。

    评测系统最大并发用户数:为获取整个系统所能够承受的最大并发用户数而进行的的测试活动。通过预先分析项目各主要模块的使用比率和频率,定义各事务在综合场景中所占的比率,以比率方式分配各事务并发用户数。模拟真实环境或直接采用真实环境,评测在这种环境下系统所能承受的最大并发用户数。判定标准阀值预先定义(如响应时间,CPU占用率,内存占用率,已出现点击率峰值,已出现吞吐量峰值等)。取值标准以木桶法则为准(并发数最小的事务为整个系统的并发数)。

      评测不同数据库数据量对性能的影响:针对不同数据库数据量的测试,将测试结果进行对比,分析发现数据库中各表的数据量对事务性能的影响。得以预先判断系统长时间运行后,或某些模块客户要求数据量较大时可能存在的隐患。

      问题定位测试在通过以上测试或用户实际操作已经发现系统中的性能问题或怀疑已存在性能问题。需通过响应的测试场景重现问题或定义问题。如有可能,可以直接找出引起性能问题所在的代码或模块。

      该类测试主要还是通过测试出问题的脚本场景,并可以增加发现和检测的工具,如开启Tivoli性能监控、开启HeapDump输出、Linux资源监控命令等。并在场景运行过程中辅以手工测试。

  • LR结果分析1

    2010-01-29 13:24:18

  • LoadRunner中错误号为27796的讨论

    2010-01-29 12:43:42

    问题:

    在一次性能测试过程中,使用http协议的多用户服务器发送请求。设置了持续时间,出现错误为:Action.c(8): Error -27796: Failed to connect to server "server:port": [10060] Connection timed out.


    分析:

    因为负载生成器的性能太好,发数据包特别快,服务器也响应特别快,从而导致负载生成器的机器的端口在没有timeout之前就全部占满了。在全部占满后,就会出现上面的错误。执行netstat –na命令,可以看到打开了很多端口。所以就调整TCP的time out。即在最后一个端口还没有用到时,前面已经有端口在释放了。

    官方的troubleshooting:
    查看工具的troubleshooting,如下:
    代码:
    Message Code 27796
    Failed to connect to server 'hostname';port_ld': 'reason'.
    Unable to connect to the specified server and port.
    Troubleshooting
    o    Try to address the reason provided for the connection failure.
    o    Try to access the application with a browser from the injector machine and from another machine (such as the recording machine).
    o    Check that you accurately specified the correct host name and port.
    o    Ping the host/port.
    o    Check if the server application you are trying to access is running.
    o    If you used a hostname, check if it was resolved to the correct address.
    o    Check if the server application is listening to the right port.
    均不是解决之道。

    成功的解决方法:

    在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters里,有如下两个键值:
    TcpTimedWaitDelay
    MaxUserPort
    1,这里的TcpTimedWaitDelay默认值应该中是30s,所以这里,把这个值调小为5s(按需要调整)。
    2,也可以把MaxUserPort调大(如果这个值不是最大值的话)。

    以下是网友查到的一些资料

    TcpTimedWaitDelay 值決定了 TCP/IP 必須經過多久,才能釋出已關閉的連線及重複使用它的資源。這個關閉和釋出的間隔稱為 TIME_WAIT 狀態,或是區段生命期限上限 (2MSL) 狀態的兩倍。在這段時間內,通往用戶端和伺服器的連線重新開啟的成本,比建立新的連線低。藉由縮減這個項目的值,TCP/IP 可以更快釋出已關閉的連線,提供更多資源給新的連線。如果執行中的應用程式需要快速釋出、建立新連線,或多個連線在 TIME_WAIT 狀態中造成通訊量太低,因而需要進行調整的話,請調整這個參數。

    預設值是 0xF0,它會將等待時間設為 240 秒(4 分鐘)。

    最小的建議值是 0x1E,它會將等待時間設為 30 秒。請利用這個程序來檢視或自訂您的值。

    啟動 regedit 指令,瀏覽至 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP\Parameters 登錄次機碼,建立名稱為 TcpTimedWaitDelay 的新 REG_DWORD 值。
    將值設為十進位 30,也就是十六進位的 0x0000001e。這個值會將等待時間設為 30 秒。
    關閉登錄編輯器。
    停止並重新啟動系統。
    MaxUserPort
    MaxUserPort 值決定了當應用程式向系統要求可用的使用者埠時,TCP/IP 所能指派的最高埠號。如果您的系統報告建立 Socket 時,發生錯誤異常狀況,可能是匿名(短期)埠的數量不當所造成,當系統開啟大量的埠來建立 Web 服務、資料庫或其他遠端資源的連線時,尤其如此。


  • 软件测试步骤

    2010-01-04 09:40:39

    软件测试步骤
    •    测试过程按4个步骤进行,即单元测试、集成测试、确认测试和系统测试及发版测试。
    •    开始是单元测试,集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。
      
      
      
    •     集成测试把已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。
    •     确认测试则是要检查已实现的软件是否满足了需求规格说明中确定了的各种需求,以及软件配置是否完全、正确。
    •     系统测试把已经经过确认的软件纳入实际运行环境中,与其它系统成份组合在一起进行测试。
    单元测试 (Unit Testing)
    •     单元测试又称模块测试,是针对软件设计的最小单位 ─ 程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。
    •     单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。
    1. 单元测试的内容
    •     在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/O条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应。


      
    (1) 模块接口测试
    •    在单元测试的开始,应对通过被测模块的数据流进行测试。测试项目包括:
    –   调用本模块的输入参数是否正确;
    –   本模块调用子模块时输入给子模块的参数是否正确;
    –   全局量的定义在各模块中是否一致;


      
    •     在做内外存交换时要考虑:
      
    –   文件属性是否正确;
    –   OPEN与CLOSE语句是否正确;
    –   缓冲区容量与记录长度是否匹配;
    –   在进行读写操作之前是否打开了文件;
    –   在结束文件处理时是否关闭了文件;
    –   正文书写/输入错误,
    –   I/O错误是否检查并做了处理。


    (2) 局部数据结构测试
    •     不正确或不一致的数据类型说明
    •     使用尚未赋值或尚未初始化的变量
    •     错误的初始值或错误的缺省值
    •     变量名拼写错或书写错
    •     不一致的数据类型
    •     全局数据对模块的影响
    (3) 路径测试
    •    选择适当的测试用例,对模块中重要的执行路径进行测试。
    •    应当设计测试用例查找由于错误的计算、不正确的比较或不正常的控制流而导致的错误。
    •    对基本执行路径和循环进行测试可以发现大量的路径错误。
    (4) 错误处理测试
    •     出错的描述是否难以理解
    •     出错的描述是否能够对错误定位
    •     显示的错误与实际的错误是否相符
    •     对错误条件的处理正确与否
    •     在对错误进行处理之前,错误条件是否已经引起系统的干预等
    (5) 边界测试
    •     注意数据流、控制流中刚好等于、大于或小于确定的比较值时出错的可能性。对这些地方要仔细地选择测试用例,认真加以测试。
    •     如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素。


      
      
      
    2. 单元测试的步骤
    •    模块并不是一个独立的程序,在考虑测试模块时,同时要考虑它和外界的联系,用一些辅助模块去模拟与被测模块相联系的其它模块。
    –   驱动模块 (driver)
    –   桩模块 (stub) ── 存根模块
      
      
      
      
    •      如果一个模块要完成多种功能,可以将这个模块看成由几个小程序组成。必须对其中的每个小程序先进行单元测试要做的工作,对关键模块还要做性能测试。
    •      对支持某些标准规程的程序,更要着手进行互联测试。有人把这种情况特别称为模块测试,以区别单元测试。
    集成测试(Integrated Testing)
    •     集成测试 (集成测试、联合测试)
    •     通常,在单元测试的基础上,需要将所有模块按照设计要求组装成为系统。这时需要考虑的问题是:
    –   在把各个模块连接起来的时侯,穿越模块接口的数据是否会丢失;
    –   一个模块的功能是否会对另一个模块的功能产生不利的影响;


      
    –   各个子功能组合起来,能否达到预期要求的父功能;
    –   全局数据结构是否有问题;
    –   单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。
    在单元测试的同时可进行集成测试,
    发现并排除在模块连接中可能出现
    的问题,最终构成要求的软件系统。





    •    子系统的集成测试特别称为部件测试,它所做的工作是要找出集成后的子系统与系统需求规格说明之间的不一致。
    •    通常,把模块集成成为系统的方式有两种
    –   一次性集成方式
    –   增殖式集成方式


    1. 一次性集成方式(big bang)
    •    它是一种非增殖式组装方式。也叫做整体拼装。
    •    使用这种方式,首先对每个模块分别进行模块测试,然后再把所有模块组装在一起进行测试,最终得到要求的软件系统。
      
    2. 增殖式集成方式
    •     这种集成方式又称渐增式集成
    •     首先对一个个模块进行模块测试,然后将这些模块逐步组装成较大的系统
    •     在集成的过程中边连接边测试,以发现连接过程中产生的问题
    •     通过增殖逐步组装成为要求的软件系统。


    (1) 自顶向下的增殖方式
    •      这种集成方式将模块按系统程序结构,沿控制层次自顶向下进行组装。
    •      自顶向下的增殖方式在测试过程中较早地验证了主要的控制和判断点。
    •      选用按深度方向组装的方式,可以首先实现和验证一个完整的软件功能。
      
    (2) 自底向上的增殖方式
    •     这种集成的方式是从程序模块结构的最底层的模块开始集成和测试。
    •     因为模块是自底向上进行组装,对于一个给定层次的模块,它的子模块(包括子模块的所有下属模块)已经组装并测试完成,所以不再需要桩模块。在模块的测试过程中需要从子模块得到的信息可以直接运行子模块得到。


      
    •    自顶向下增殖的方式和自底向上增殖的方式各有优缺点。
    •    一般来讲,一种方式的优点是另一种方式的缺点。
    (3) 混合增殖式测试
    •    衍变的自顶向下的增殖测试
    –   首先对输入/输出模块和引入新算法模块进行测试;
    –   再自底向上组装成为功能相当完整且相对独立的子系统;
    –   然后由主模块开始自顶向下进行增殖测试。
      
    •    自底向上-自顶向下的增殖测试
    –   首先对含读操作的子系统自底向上直至根结点模块进行组装和测试;
    –   然后对含写操作的子系统做自顶向下的组装与测试。
    •    回归测试
    –   这种方式采取自顶向下的方式测试被修改的模块及其子模块;
    –   然后将这一部分视为子系统,再自底向上测试。
    关键模块问题
    •     在组装测试时,应当确定关键模块,对这些关键模块及早进行测试。
    •     关键模块的特征:
    ① 满足某些软件需求;
    ② 在程序的模块结构中位于较高的层次(高层控制模块);
    ③ 较复杂、较易发生错误;
    ④ 有明确定义的性能要求。


    确认测试(Validation Testing)
    •    确认测试又称有效性测试。任务是验证软件的功能和性能及其它特性是否与用户的要求一致。
    •    对软件的功能和性能要求在软件需求规格说明书中已经明确规定。它包含的信息就是软件确认测试的基础。
      
    1. 进行有效性测试(黑盒测试)
    •     有效性测试是在模拟的环境 (可能就是开发的环境) 下,运用黑盒测试的方法,验证被测软件是否满足需求规格说明书列出的需求。
    •     首先制定测试计划,规定要做测试的种类。还需要制定一组测试步骤,描述具体的测试用例。
      
    •    通过实施预定的测试计划和测试步骤,确定
    –   软件的特性是否与需求相符;
    –   所有的文档都是正确且便于使用;
    –   同时,对其它软件需求,例如可移植性、兼容性、出错自动恢复、可维护性等,也都要进行测试
      
    •     在全部软件测试的测试用例运行完后,所有的测试结果可以分为两类:
    –   测试结果与预期的结果相符。这说明软件的这部分功能或性能特征与需求规格说明书相符合,从而这部分程序被接受。
    –   测试结果与预期的结果不符。这说明软件的这部分功能或性能特征与需求规格说明不一致,因此要为它提交一份问题报告。


    2. 软件配置复查
    n       软件配置复查的目的是保证
    u  软件配置的所有成分都齐全;
    u  各方面的质量都符合要求;
    u  具有维护阶段所必需的细节;
    u  而且已经编排好分类的目录。
    n  应当严格遵守用户手册和操作手册中规定的使用步骤,以便检查这些文档资料的完整性和正确性。
    验收测试(Acceptance Testing)
    •     在通过了系统的有效性测试及软件配置审查之后,就应开始系统的验收测试。
    •     验收测试是以用户为主的测试。软件开发人员和QA(质量保证)人员也应参加。
    •     由用户参加设计测试用例,使用生产中的实际数据进行测试。
      
    •    在测试过程中,除了考虑软件的功能和性能外,还应对软件的可移植性、兼容性、可维护性、错误的恢复功能等进行确认。
    •    确认测试应交付的文档有:
    –   确认测试分析报告
    –   最终的用户手册和操作手册
    –   项目开发总结报告。


    系统测试(System Testing)
    •     系统测试,是将通过确认测试的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其它系统元素结合在一起,在实际运行环境下,对计算机系统进行一系列的组装测试和确认测试。
    •     系统测试的目的在于通过与系统的需求定义作比较,  发现软件与系统的定义不符合或与之矛盾的地方。
    α测试和β测试
    •    在软件交付使用之后,用户将如何实际使用程序,对于开发者来说是无法预测的。
    •    α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试。
      
    •     α测试的目的是评价软件产品的FLURPS(即功能、局域化、可使用性、可靠性、性能和支持)。尤其注重产品的界面和特色。
    •     α测试可以从软件产品编码结束之时开始,或在模块(子系统)测试完成之后开始,也可以在确认测试过程中产品达到一定的稳定和可靠程度之后再开始。


      
    •     β测试是由软件的多个用户在实际使用环境下进行的测试。这些用户返回有关错误信息给开发者。
    •     测试时,开发者通常不在测试现场。因而,β测试是在开发者无法控制的环境下进行的软件现场应用。
    •     在β测试中,由用户记下遇到的所有问题,包括真实的以及主观认定的,定期向开发者报告。
      
    •    β测试主要衡量产品的FLURPS。着重于产品的支持性,包括文档、客户培训和支持产品生产能力。
    •    只有当α测试达到一定的可靠程度时,才能开始β测试。它处在整个测试的最后阶段。同时,产品的所有手册文本也应该在此阶段完全定稿。
    测试类型
    •    软件测试是由一系列不同的测试组成。主要目的是对以计算机为基础的系统进行充分的测试。
    功能测试
      功能测试是在规定的一段时间内运行软件系统的所有功能,以验证这个软件系统有无严重错误。
      
    强度测试
      
      强度测试是要检查在系统运行环境不正常乃至发生故障的情况下,系统可以运行到何种程度的测试。例如:
    –   把输入数据速率提高一个数量级,确定输入功能将如何响应。
    –   设计需要占用最大存储量或其它资源的测试用例进行测试。


      
    –   设计出在虚拟存储管理机制中引起“颠簸”的测试用例进行测试。
    –   设计出会对磁盘常驻内存的数据过度访问的测试用例进行测试。
    •     强度测试的一个变种就是敏感性测试。在程序有效数据界限内一个小范围内的一组数据可能引起极端的或不平稳的错误处理出现,或者导致极度的性能下降的情况发生。此测试用以发现可能引起这种不稳定性或不正常处理的某些数据组合。


      
    性能测试
    •     性能测试是要检查系统是否满足在需求说明书中规定的性能。特别是对于实时系统或嵌入式系统。
    •     性能测试常常需要与强度测试结合起来进行,并常常要求同时进行硬件和软件检测。
    •     通常,对软件性能的检测表现在以下几个方面:响应时间、吞吐量、辅助存储区,例如缓冲区,工作区的大小等、处理精度,等等。
      
    恢复测试
      恢复测试是要证实在克服硬件故障(包括掉电、硬件或网络出错等)后,系统能否正常地继续进行工作,并不对系统造成任何损害。
    •     为此,可采用各种人工干预的手段,模拟硬件故障,故意造成软件出错。并由此检查:
    –   错误探测功能──系统能否发现硬件失效与故障;
      
    –   能否切换或启动备用的硬件;
    –   在故障发生时能否保护正在运行的作业和系统状态;
    –   在系统恢复后能否从最后记录下来的无错误状态开始继续执行作业,等等。
    –   掉电测试:其目的是测试软件系统在发生电源中断时能否保护当时的状态且不毁坏数据,然后在电源恢复时从保留的断点处重新进行操作。


      
    配置测试
      
    •     这类测试是要检查计算机系统内各个设备或各种资源之间的相互联结和功能分配中的错误。
    •     它主要包括以下几种:
    –   配置命令测试:验证全部配置命令的可操作性(有效性);特别对最大配置和最小配置要进行测试。软件配置和硬件配置都要测试。


      
    –   循环配置测试:证明对每个设备物理与逻辑的,逻辑与功能的每次循环置换配置都能正常工作。
    –   修复测试:检查每种配置状态及哪个设备是坏的。并用自动的或手工的方式进行配置状态间的转换。
      
    安全性测试
      安全性测试是要检验在系统中已经存在的系统安全性、保密性措施是否发挥作用,有无漏洞。
    •     力图破坏系统的保护机构以进入系统的主要方法有以下几种:
    –   正面攻击或从侧面、背面攻击系统中易受损坏的那些部分;
    –   以系统输入为突破口,利用输入的容错性进行正面攻击;


      
    –   申请和占用过多的资源压垮系统,以破坏安全措施,从而进入系统;
    –   故意使系统出错,利用系统恢复的过程,窃取用户口令及其它有用的信息;
    –   通过浏览残留在计算机各种资源中的垃圾(无用信息),以获取如口令,安全码,译码关键字等信息;
    –   浏览全局数据,期望从中找到进入系统的关键字;
    –   浏览那些逻辑上不存在,但物理上还存在的各种记录和资料等。
      
    可使用性测试
      
    •     可使用性测试主要从使用的合理性和方便性等角度对软件系统进行检查,发现人为因素或使用上的问题。
    •     要保证在足够详细的程度下,用户界面便于使用;对输入量可容错、响应时间和响应方式合理可行、输出信息有意义、正确并前后一致;出错信息能够引导用户去解决问题;软件文档全面、正规、确切。
      
    安装测试
      安装测试的目的不是找软件错误,而是找安装错误。
    •    在安装软件系统时,会有多种选择。
    –   要分配和装入文件与程序库
    –   布置适用的硬件配置
    –   进行程序的联结。
    •    而安装测试就是要找出在这些安装过程中出现的错误。
      
      
    •    安装测试是在系统安装之后进行测试。它要检验:
    –   用户选择的一套任选方案是否相容;
    –   系统的每一部分是否都齐全;
    –   所有文件是否都已产生并确有所需要的内容;
    –   硬件的配置是否合理,等等。


      
    容量测试
      
    •      容量测试是要检验系统的能力最高能达到什么程度。例如,
    –    对于编译程序,让它处理特别长的源程序;
    –    对于操作系统,让它的作业队列“满员”;
    –    对于信息检索系统,让它使用频率达到最大。
      在使系统的全部资源达到“满负荷”的情形下,测试系统的承受能力。


      
    文档测试
      
      这种测试是检查用户文档(如用户手册)的清晰性和精确性。
    •    用户文档中所使用的例子必须在测试中一一试过,确保叙述正确无误。
      
    自动测试
    •     认识自动测试
    •     什么时候使用自动测试
  • SQL自定义函数

    2009-12-12 16:31:40

  • sql2005创建存储过程(需要注意的几点)

    2009-12-12 16:09:43

    创建存储过程。存储过程是已保存的 Transact-SQL 语句集合,或对 Microsoft .NET Framework 公共语言运行时 (CLR) 方法的引用,可接收并返回用户提供的参数。可以创建过程供永久使用,或在一个会话(局部临时过程)中临时使用,或在所有会话(全局临时过程)中临时使用。

    启动 SQL Server 的一个实例时,也可以创建并自动运行存储过程。

     Transact-SQL 语法约定

    语法
     
    CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ ; number ]
        [ { @parameter [ type_schema_name. ] data_type }
            [ VARYING ] [ = default ] [ [ OUT [ PUT ]
        ] [ ,...n ]
    [ WITH <procedure_option> [ ,...n ]
    [ FOR REPLICATION ]
    AS { <sql_statement> [;][ ...n ] | <method_specifier> }
    [;]
    <procedure_option> ::=
        [ ENCRYPTION ]
        [ RECOMPILE ]
        [ EXECUTE_AS_Clause ]

    <sql_statement> ::=
    { [ BEGIN ] statements [ END ] }

    <method_specifier> ::=
    EXTERNAL NAME assembly_name.class_name.method_name
     

    备注
    Transact-SQL 存储过程的最大大小为 128 MB。

    只能在当前数据库中创建用户定义存储过程。临时过程对此是个例外,因为它们总是在 tempdb 中创建。如果未指定架构名称,则使用创建过程的用户的默认架构。有关架构的详细信息,请参阅用户架构分离。

    在单个批处理中,CREATE PROCEDURE 语句不能与其他 Transact-SQL 语句组合使用。

    默认情况下,参数可为空值。如果传递 NULL 参数值并且在 CREATE 或 ALTER TABLE 语句中使用该参数,而该语句中被引用列又不允许使用空值,则数据库引擎 会产生一个错误。若要阻止向不允许使用空值的列传递 NULL,请为过程添加编程逻辑,或使用 CREATE TABLE 或 ALTER TABLE 的 DEFAULT 关键字,以便对该列使用默认值。

    存储过程中的任何 CREATE TABLE 或 ALTER TABLE 语句都将自动创建临时表。建议对于临时表中的每列,显式指定 NULL 或 NOT NULL。如果在 CREATE TABLE 或 ALTER TABLE 语句中未进行指定,则 ANSI_DFLT_ON 和 ANSI_DFLT_OFF 选项将控制数据库引擎 为列指派 NULL 或 NOT NULL 属性的方式。如果某个连接执行的存储过程对这些选项的设置与创建该过程的连接的设置不同,则为第二个连接创建的表列可能会有不同的为空性,并且显示出不同的行为。如果为每个列显式声明了 NULL 或 NOT NULL,那么将对所有执行该存储过程的连接使用相同的为空性创建临时表。

    使用 SET 选项
    在创建或修改 Transact-SQL 存储过程时,数据库引擎 将保存 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 的设置。执行存储过程时,将使用这些原始设置。因此,所有客户端会话的 SET QUOTED_IDENTIFIER 和 SET ANSI_NULLS 设置在执行存储过程时都将被忽略。在创建或更改存储过程时不保存其他 SET 选项(例如 SET ARITHABORT、SET ANSI_WARNINGS 或 SET ANSI_PADDINGS)。如果存储过程的逻辑取决于特定的设置,则应在过程开头添加一条 SET 语句,以确保设置正确。从存储过程中执行 SET 语句时,该设置只在存储过程完成之前有效。之后,设置将还原为调用存储过程时的值。这样一来,单个客户端就可以设置所需的选项,而不会影响存储过程的逻辑。

    注意: 
    在传递存储过程或用户定义函数中的参数时,或在声明和设置批语句中的变量时,ANSI_WARNINGS 的优先级较低。例如,如果一个变量被定义为 char(3),但后来将该参数设置为一个大于三个字符的值,则数据将被截断为定义的大小,并且 INSERT 或 UPDATE 语句将执行成功。
     


    使用 CLR 存储过程的参数
    CLR 存储过程的参数可以是标量 SQL Server 系统数据类型的任何一种。

    为了使数据库引擎 在 .NET Framework 中被重载时引用正确的方法,<method_specifier> 中指示的方法必须具有下列特征:

    声明为静态方法。


    接收的参数个数与过程的参数个数相同。


    不能是类的构造函数或析构函数。


    使用的参数类型与 SQL Server 过程的相应参数的数据类型兼容。有关将 SQL Server 数据类型与 .NET Framework 数据类型匹配的信息,请参阅 SQL Server Data Types and Their .NET Framework Equivalents。


    返回 void,或者返回类型为 SQLInt32、SQLInt16、System.Int32 或 System.Int16 的值。


    如果对于任何特定的参数声明都指定了 OUTPUT,则按照引用返回它的参数,而不是按照值返回。


    获得有关存储过程的信息
    若要显示 Transact-SQL 存储过程的定义,请使用该过程所在的数据库中的 sys.sql_modules 目录视图。

    例如:

     复制代码
    USE AdventureWorks;
    GO
    SELECT definition
    FROM sys.sql_modules
    JOIN sys.objects ON sys.sql_modules.object_id = sys.objects.object_id AND TYPE = ''P'';
     
    注意: 
    不能使用 sys.sql_modules 目录视图查看使用 ENCRYPTION 选项创建的存储过程的文本。
     


    若要获取有关某过程引用的对象的报表,请查询 sys.sql_dependencies 目录视图或使用 sp_depends。sp_depends 不返回有关 CLR 存储过程引用的对象的信息。若要显示有关 CLR 存储过程的信息,请使用该过程所在的数据库中的 sys.assembly_modules 目录视图。

    若要显示有关存储过程中定义的参数的信息,请使用该过程所在的数据库中的 sys.parameters 目录视图。

    延迟名称解析
    可以创建引用尚不存在的表的存储过程。在创建时,只进行语法检查。直到第一次执行该存储过程时才对其进行编译。只有在编译过程中才解析存储过程中引用的所有对象。因此,如果语法正确的存储过程引用了不存在的表,则仍可以成功创建;但如果引用的表不存在,则存储过程将在运行时失败。有关详细信息,请参阅延迟名称解析和编译。

    执行存储过程
    当执行用户定义的存储过程时,无论是在批中还是在模块(例如用户定义的存储过程或函数)内,极力建议使用架构名称来限定存储过程名。

    如果存储过程编写为可以接受参数值,则可以提供参数值。该值必须是常量或变量。不能指定函数名作为参数值。变量可以是用户定义变量或系统变量,例如 @@SPID。

    有关详细信息,请参阅执行存储过程(数据库引擎)。

    第一次执行某个过程时,将编译该过程以确定检索数据的最优访问计划。如果已经生成的计划仍保留在数据库引擎 计划缓存中,则存储过程随后执行的操作可能重新使用该计划。有关详细信息,请参阅执行计划的缓存和重新使用。

    使用 cursor 数据类型的参数
    Transact-SQL 存储过程只能将 cursor 数据类型用于 OUTPUT 参数。如果为某个参数指定了 cursor 数据类型,则还需要 VARYING 和 OUTPUT 参数。如果为某个参数指定了 VARYING 关键字,则数据类型必须是 cursor,并且必须指定 OUTPUT 关键字。有关详细信息,请参阅在 OUTPUT 参数中使用 cursor 数据类型。

    临时存储过程
    数据库引擎 支持两种临时过程:局部临时过程和全局临时过程。局部临时过程只对创建该过程的连接可见。全局临时过程则可由所有连接使用。局部临时过程在当前会话结束时将被自动删除。全局临时过程在使用该过程的最后一个会话结束时被删除。有关详细信息,请参阅创建存储过程(数据库引擎)。

    自动执行存储过程
    SQL Server 启动时可以自动执行一个或多个存储过程。这些存储过程必须由系统管理员在 master 数据库中创建,并以 sysadmin 固定服务器角色作为后台进程执行。这些过程不能有任何输入或输出参数。有关详细信息,请参阅自动执行存储过程。

    存储过程嵌套
    存储过程可以被嵌套。这表示一个存储过程可以调用另一个存储过程。在被调用过程开始运行时,嵌套级将增加,在被调用过程运行结束后,嵌套级将减少。存储过程最多可以嵌套 32 级。有关详细信息,请参阅嵌套存储过程。

    若要估计编译后的存储过程大小,请使用下列性能监视器计数器。

    性能监视器对象名  性能监视器计数器名称 
    SQLServer: Plan Cache Object
     Cache Hit Ratio
     
     
     Cache Pages
     
     
     Cache Object Counts*
     

    * 各种类别的缓存对象均可以使用这些计数器,包括即席 sql、准备好的 sql、过程、触发器等。

    有关详细信息,请参阅 SQL Server Plan Cache 对象。

    <sql_statement> 限制
    可以在存储过程中指定除了 SET SHOWPLAN_TEXT 和 SET SHOWPLAN_ALL 以外的任何 SET 语句。这些语句在批处理中必须唯一。选择的 SET 选项在存储过程执行过程中有效,之后恢复为原来的设置。

    如果用户不是存储过程所有者,则在使用存储过程时,必须使用对象架构名称对存储过程内所有数据定义语言 (DDL) 语句(例如 CREATE、ALTER 或 DROP 语句、DBCC 语句、EXECUTE 和动态 SQL 语句)中使用的对象名称进行限定。有关详细信息,请参阅设计存储过程(数据库引擎)。

    参数
    schema_name
    过程所属架构的名称。

    procedure_name
    新存储过程的名称。过程名称必须遵循有关标识符的规则,并且在架构中必须唯一。

    极力建议不在过程名称中使用前缀 sp_。此前缀由 SQL Server 使用,以指定系统存储过程。有关详细信息,请参阅创建存储过程(数据库引擎)。

    可在 procedure_name 前面使用一个数字符号 (#) (#procedure_name) 来创建局部临时过程,使用两个数字符号 (##procedure_name) 来创建全局临时过程。对于 CLR 存储过程,不能指定临时名称。

    存储过程或全局临时存储过程的完整名称(包括 ##)不能超过 128 个字符。局部临时存储过程的完整名称(包括 #)不能超过 116 个字符。

    ; number
    用于对同名过程进行分组的可选整数。使用一个 DROP PROCEDURE 语句可将这些分组过程一起删除。例如,称为 orders 的应用程序可能使用名为 orderproc;1、orderproc;2 等的过程。DROP PROCEDURE orderproc 语句将删除整个组。如果名称中包含分隔标识符,则数字不应包含在标识符中;只应在 procedure_name 前后使用适当的分隔符。

    带编号的存储过程有以下限制:

    不能使用 xml 或 CLR 用户定义类型作为数据类型。


    不能对带编号的存储过程创建计划指南。


    注意: 
    后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并应着手修改当前还在使用该功能的应用程序。
     


    @ parameter
    过程中的参数。在 CREATE PROCEDURE 语句中可以声明一个或多个参数。除非定义了参数的默认值或者将参数设置为等于另一个参数,否则用户必须在调用过程时为每个声明的参数提供值。存储过程最多可以有 2,100 个参数。

    通过使用 at 符号 (@) 作为第一个字符来指定参数名称。参数名称必须符合有关标识符的规则。每个过程的参数仅用于该过程本身;其他过程中可以使用相同的参数名称。默认情况下,参数只能代替常量表达式,而不能用于代替表名、列名或其他数据库对象的名称。有关详细信息,请参阅 EXECUTE (Transact-SQL)。

    如果指定了 FOR REPLICATION,则无法声明参数。

    [ type_schema_name. ] data_type
    参数以及所属架构的数据类型。除 table 之外的其他所有数据类型均可以用作 Transact-SQL 存储过程的参数。但是,cursor 数据类型只能用于 OUTPUT 参数。如果指定了 cursor 数据类型,则还必须指定 VARYING 和 OUTPUT 关键字。可以为 cursor 数据类型指定多个输出参数。

    对于 CLR 存储过程,不能指定 char、varchar、text、ntext、image、cursor 和 table 作为参数。有关 CLR 类型与 SQL Server 系统数据类型之间关系的详细信息,请参阅 SQL Server Data Types and Their .NET Framework Equivalents。有关 SQL Server 系统数据类型及其语法的详细信息,请参阅数据类型 (Transact-SQL)。

    如果参数的数据类型为 CLR 用户定义类型,则必须对此类型有 EXECUTE 权限。

    如果未指定 type_schema_name,则 SQL Server 2005 Database Engine 将按以下顺序引用 type_name:

    SQL Server 系统数据类型。


    当前数据库中当前用户的默认架构。


    当前数据库中的 dbo 架构。


    对于带编号的存储过程,数据类型不能为 xml 或 CLR 用户定义类型。

    VARYING
    指定作为输出参数支持的结果集。该参数由存储过程动态构造,其内容可能发生改变。仅适用于 cursor 参数。

    default
    参数的默认值。如果定义了 default 值,则无需指定此参数的值即可执行过程。默认值必须是常量或 NULL。如果过程使用带 LIKE 关键字的参数,则可包含下列通配符:%、_、[] 和 [^]。

    注意: 
    只有 CLR 过程的默认值记录在 sys.parameters.default 列中。对于 Transact-SQL 过程参数,该列将为 NULL。
     


    OUTPUT
    指示参数是输出参数。此选项的值可以返回给调用 EXECUTE 的语句。使用 OUTPUT 参数将值返回给过程的调用方。除非是 CLR 过程,否则 text、ntext 和 image 参数不能用作 OUTPUT 参数。使用 OUTPUT 关键字的输出参数可以为游标占位符,CLR 过程除外。

    RECOMPILE
    指示数据库引擎 不缓存该过程的计划,该过程在运行时编译。如果指定了 FOR REPLICATION,则不能使用此选项。对于 CLR 存储过程,不能指定 RECOMPILE。

    若要指示数据库引擎 放弃存储过程内单个查询的计划,请使用 RECOMPILE 查询提示。有关详细信息,请参阅查询提示 (Transact-SQL)。如果非典型值或临时值仅用于属于存储过程的查询子集,则使用 RECOMPILE 查询提示。

    ENCRYPTION
    指示 SQL Server 将 CREATE PROCEDURE 语句的原始文本转换为模糊格式。模糊代码的输出在 SQL Server 2005 的任何目录视图中都不能直接显示。对系统表或数据库文件没有访问权限的用户不能检索模糊文本。但是,可通过 DAC 端口访问系统表的特权用户或直接访问数据库文件的特权用户可使用此文本。此外,能够向服务器进程附加调试器的用户可在运行时从内存中检索已解密的过程。

    该选项对于 CLR 存储过程无效。

    注意: 
    使用此选项创建的过程不能在 SQL Server 复制过程中发布。
     


    EXECUTE AS
    指定在其中执行存储过程的安全上下文。

    有关详细信息,请参阅 EXECUTE AS 子句 (Transact-SQL)。

    FOR REPLICATION
    指定不能在订阅服务器上执行为复制创建的存储过程。使用 FOR REPLICATION 选项创建的存储过程可用作存储过程筛选器,且只能在复制过程中执行。如果指定了 FOR REPLICATION,则无法声明参数。对于 CLR 存储过程,不能指定 FOR REPLICATION。对于使用 FOR REPLICATION 创建的过程,忽略 RECOMPILE 选项。

    FOR REPLICATION 过程将在 sys.objects 和 sys.procedures 中包含 RF 对象类型。

    <sql_statement>
    要包含在过程中的一个或多个 Transact-SQL 语句。有关某些适用的限制的信息,请参阅“备注”部分。

    EXTERNAL NAME , assembly_name.class_name.method_name
    指定 .NET Framework 程序集的方法,以便 CLR 存储过程引用。class_name 必须为有效的 SQL Server 标识符,并且该类必须存在于程序集中。如果类包含一个使用句点 (.) 分隔命名空间各部分的限定命名空间的名称,则必须使用方括号 ([ ]) 或引号 (" ") 将类名称分隔开。指定的方法必须为该类的静态方法。

    注意: 
    默认情况下,SQL Server 不能执行 CLR 代码。可以创建、修改和删除引用公共语言运行时模块的数据库对象;不过,只有在启用了 clr enabled 选项之后,才能在 SQL Server 中执行这些引用。若要启用该选项,请使用 sp_configure。
     


    权限
    需要在数据库中有 CREATE PROCEDURE 权限,对在其中创建过程的架构有 ALTER 权限。

    对于 CLR 存储过程,需要对 <method_specifier> 中引用的程序集的所有权,或拥有对该程序集的 REFERENCES 权限。

    示例
    A. 使用简单过程
    以下存储过程将从视图中返回所有雇员(提供姓和名)、职务以及部门名称。此存储过程不使用任何参数。
    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''HumanResources.usp_GetAllEmployees'', ''P'' ) IS NOT NULL
        DROP PROCEDURE HumanResources.usp_GetAllEmployees;
    GO
    CREATE PROCEDURE HumanResources.usp_GetAllEmployees
    AS
        SELECT LastName, FirstName, JobTitle, Department
        FROM HumanResources.vEmployeeDepartment;
    GO

     

    usp_GetEmployees 存储过程可通过以下方式执行:

    EXECUTE HumanResources.usp_GetAllEmployees;
    GO
    -- Or
    EXEC HumanResources.usp_GetAllEmployees;
    GO
    -- Or, if this procedure is the first statement within a batch:
    HumanResources.usp_GetAllEmployees;

     

    B. 使用带有参数的简单过程
    下面的存储过程只从视图中返回指定的雇员(提供名和姓)及其职务和部门名称。此存储过程接受与传递的参数精确匹配的值

    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''HumanResources.usp_GetEmployees'', ''P'' ) IS NOT NULL
        DROP PROCEDURE HumanResources.usp_GetEmployees;
    GO
    CREATE PROCEDURE HumanResources.usp_GetEmployees
        @lastname varchar(40),
        @firstname varchar(20)
    AS
        SELECT LastName, FirstName, JobTitle, Department
        FROM HumanResources.vEmployeeDepartment
        WHERE FirstName = @firstname AND LastName = @lastname;
    GO

     

    usp_GetEmployees 存储过程可通过以下方式执行:

     复制代码
    EXECUTE HumanResources.usp_GetEmployees ''Ackerman'', ''Pilar'';
    -- Or
    EXEC HumanResources.usp_GetEmployees @lastname = ''Ackerman'', @firstname = ''Pilar'';
    GO
    -- Or
    EXECUTE HumanResources.usp_GetEmployees @firstname = ''Pilar'', @lastname = ''Ackerman'';
    GO
    -- Or, if this procedure is the first statement within a batch:
    HumanResources.usp_GetEmployees ''Ackerman'', ''Pilar'';

     

    C. 使用带有通配符参数的简单过程
    以下存储过程只从视图中返回指定的一些雇员(提供名和姓)及其职务和部门名称。此存储过程模式与所传递的参数相匹配;或者,如果未提供参数,则使用预设的默认值(以字母 D 打头的姓)。
     
    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''HumanResources.usp_GetEmployees2'', ''P'' ) IS NOT NULL
        DROP PROCEDURE HumanResources.usp_GetEmployees2;
    GO
    CREATE PROCEDURE HumanResources.usp_GetEmployees2
        @lastname varchar(40) = ''D%'',
        @firstname varchar(20) = ''%''
    AS
        SELECT LastName, FirstName, JobTitle, Department
        FROM HumanResources.vEmployeeDepartment
        WHERE FirstName LIKE @firstname
            AND LastName LIKE @lastname;
    GO

     

    usp_GetEmployees2 存储过程可以按多种组合执行。下面只显示了几个组合:


    EXECUTE HumanResources.usp_GetEmployees2;
    -- Or
    EXECUTE HumanResources.usp_GetEmployees2 ''Wi%'';
    -- Or
    EXECUTE HumanResources.usp_GetEmployees2 @firstname = ''%'';
    -- Or
    EXECUTE HumanResources.usp_GetEmployees2 ''[CK]ars[OE]n'';
    -- Or
    EXECUTE HumanResources.usp_GetEmployees2 ''Hesse'', ''Stefen'';
    -- Or
    EXECUTE HumanResources.usp_GetEmployees2 ''H%'', ''S%'';

     

    D. 使用 OUTPUT 参数
    以下示例将创建 usp_GetList 存储过程。此过程将返回价格不超过指定数值的产品的列表。此示例显示如何使用多个 SELECT 语句和多个 OUTPUT 参数。OUTPUT 参数允许外部过程、批处理或多条 Transact-SQL 语句在过程执行期间访问设置的某个值。


    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''Production.usp_GetList'', ''P'' ) IS NOT NULL
        DROP PROCEDURE Production.usp_GetList;
    GO
    CREATE PROCEDURE Production.usp_GetList @product varchar(40)
        , @maxprice money
        , @compareprice money OUTPUT
        , @listprice money OUT
    AS
        SELECT p.name AS Product, p.ListPrice AS ''List Price''
        FROM Production.Product p
        JOIN Production.ProductSubcategory s
          ON p.ProductSubcategoryID = s.ProductSubcategoryID
        WHERE s.name LIKE @product AND p.ListPrice < @maxprice;
    -- Populate the output variable @listprice.
    SET @listprice = (SELECT MAX(p.ListPrice)
            FROM Production.Product p
            JOIN  Production.ProductSubcategory s
              ON p.ProductSubcategoryID = s.ProductSubcategoryID
            WHERE s.name LIKE @product AND p.ListPrice < @maxprice);
    -- Populate the output variable @compareprice.
    SET @compareprice = @maxprice;
    GO

     

    执行 usp_GetList,返回价格低于 $700 的 Adventure Works 产品(自行车)的列表。OUTPUT 参数 @cost 和 @compareprices 用于流控制语言,以便在“消息”窗口中返回消息。

    注意: 
    OUTPUT 变量必须在创建过程时或使用变量时定义。参数名和变量名不一定要匹配;但是,除非使用 @listprice = variable 的形式,否则数据类型和参数位置必须匹配。
     
    DECLARE @compareprice money, @cost money
    EXECUTE Production.usp_GetList ''%Bikes%'', 700,
        @compareprice OUT,
        @cost OUTPUT
    IF @cost <= @compareprice
    BEGIN
        PRINT ''These products can be purchased for less than
        $''+RTRIM(CAST(@compareprice AS varchar(20)))+''.''
    END
    ELSE
        PRINT ''The prices for all products in this category exceed
        $''+ RTRIM(CAST(@compareprice AS varchar(20)))+''.''

     

    下面是部分结果集:
    Product                                            List Price
    -------------------------------------------------- ------------------
    Road-750 Black, 58                      &nbs

    p;          539.99
    Mountain-500 Silver, 40                            564.99
    Mountain-500 Silver, 42                            564.99
    ...
    Road-750 Black, 48                                 539.99
    Road-750 Black, 52                                 539.99

    (14 row(s) affected)

    These items can be purchased for less than $700.00.
     

    E. 使用 WITH RECOMPILE 选项
    如果为过程提供的参数不是典型的参数,并且新的执行计划不应被缓存或存储在内存中,则 WITH RECOMPILE 子句会很有用。
     
    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''dbo.usp_product_by_vendor'', ''P'' ) IS NOT NULL
        DROP PROCEDURE dbo.usp_product_by_vendor;
    GO
    CREATE PROCEDURE dbo.usp_product_by_vendor @name varchar(30) = ''%''
    WITH RECOMPILE
    AS
        SELECT v.Name AS ''Vendor name'', p.Name AS ''Product name''
        FROM Purchasing.Vendor v
        JOIN Purchasing.ProductVendor pv
          ON v.VendorID = pv.VendorID
        JOIN Production.Product p
          ON pv.ProductID = p.ProductID
        WHERE v.Name LIKE @name;
    GO

     

    F. 使用 WITH ENCRYPTION 选项
    以下示例将创建 HumanResources.usp_encrypt_this 存储过程。


    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''HumanResources.usp_encrypt_this'', ''P'' ) IS NOT NULL
        DROP PROCEDURE HumanResources.usp_encrypt_this;
    GO
    CREATE PROCEDURE HumanResources.usp_encrypt_this
    WITH ENCRYPTION
    AS
        SELECT EmployeeID, Title, NationalIDNumber, VacationHours, SickLeaveHours
        FROM HumanResources.Employee;
    GO

     

    如以下示例所示,WITH ENCRYPTION 选项可阻止返回存储过程的定义。

    运行 sp_helptext:


    EXEC sp_helptext ''HumanResources.usp_encrypt_this'';
     

    下面是结果集:


    The text for object ''HumanResources.usp_encrypt_this'' is encrypted.
     

    直接查询 sys.sql_modules 目录视图:

     USE AdventureWorks;
    GO
    SELECT definition FROM sys.sql_modules
    WHERE object_id = OBJECT_ID(''HumanResources.usp_encrypt_this'');
     

    下面是结果集:


    definition
    ----------------------
    NULL

    (1 row(s) affected)
     

    G. 使用延迟名称解析
    以下示例将创建 usp_proc1 过程。该过程使用延迟名称解析。尽管引用的表在编译时不存在,但仍能创建存储过程。但是,执行过程时表必须存在。


    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''dbo.usp_proc1'', ''P'' ) IS NOT NULL
        DROP PROCEDURE dbo.usp_proc1;
    GO
    CREATE PROCEDURE dbo.usp_proc1
    AS
        SELECT column1, column2 FROM table_does_not_exist
    GO

     

    若要验证是否已创建了存储过程,请运行以下查询:

     
    USE AdventureWorks;
    GO
    SELECT definition
    FROM sys.sql_modules
    WHERE object_id = OBJECT_ID(''dbo.usp_proc1'');

     

    下面是结果集:
    definition
    -----------------------------------------------------------------------
    CREATE PROCEDURE usp_proc1
    AS
        SELECT column1, column2 FROM table_does_not_exist

    (1 row(s) affected)

     

    H. 使用 EXECUTE AS 子句
    以下示例显示使用 EXECUTE AS 子句指定执行存储过程的安全上下文。在此示例中,选项 CALLER 指定此过程可在调用它的用户上下文中执行。

     USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''Purchasing.usp_vendor_info_all'', ''P'' ) IS NOT NULL
        DROP PROCEDURE Purchasing.usp_vendor_info_all;
    GO
    CREATE PROCEDURE Purchasing.usp_vendor_info_all
    WITH EXECUTE AS CALLER
    AS
        SELECT v.Name AS Vendor, p.Name AS ''Product name'',
          v.CreditRating AS ''Credit Rating'',
          v.ActiveFlag AS Availability
        FROM Purchasing.Vendor v
        INNER JOIN Purchasing.ProductVendor pv
          ON v.VendorID = pv.VendorID
        INNER JOIN Production.Product p
          ON pv.ProductID = p.ProductID
        ORDER BY v.Name ASC;
    GO

     

    I. 创建 CLR 存储过程
    以下示例将创建 GetPhotoFromDB 存储过程,此过程引用 HandlingLOBUsingCLR 程序集中的 LargeObjectBinary 类的 GetPhotoFromDB 方法。创建存储过程前,需要在本地数据库中注册 HandlingLOBUsingCLR 程序集。

     
    CREATE ASSEMBLY HandlingLOBUsingCLR
    FROM ''\\MachineName\HandlingLOBUsingCLR\bin\Debug\HandlingLOBUsingCLR.dll'''';
    GO
    CREATE PROCEDURE dbo.GetPhotoFromDB
    (
        @ProductPhotoID int,
        @CurrentDirectory nvarchar(1024),
        @FileName nvarchar(1024)
    )
    AS EXTERNAL NAME HandlingLOBUsingCLR.LargeObjectBinary.GetPhotoFromDB;
    GO
     

    J. 使用 OUTPUT 游标参数
    OUTPUT 游标参数用来将存储过程的局部游标传递回执行调用的批处理、存储过程或触发器。

    首先,创建以下过程:在 titles 表上声明并打开一个游标:

    USE AdventureWorks;
    GO
    IF OBJECT_ID ( ''dbo.currency_cursor'', ''P'' ) IS NOT NULL
        DROP PROCEDURE dbo.currency_cursor;
    GO
    CREATE PROCEDURE dbo.currency_cursor
        @currency_cursor CURSOR VARYING OUTPUT
    AS
        SET @currency_cursor = CURSOR
        FORWARD_ONLY STATIC FOR
          SELECT CurrencyCode, Name
          FROM Sales.Currency;
        OPEN @currency_cursor;
    GO

     

    接下来,运行以下批处理:声明一个局部游标变量,执行上述过程以将游标赋值给局部变量,然后从该游标提取行。

     
    USE AdventureWorks;
    GO
    DECLARE @MyCursor CURSOR;
    EXEC dbo.currency_cursor @currency_cursor = @MyCursor OUTPUT;
    WHILE (@@FETCH_STATUS = 0)
    BEGIN;
         FETCH NEXT FROM @MyCursor;
    END;
    CLOSE @MyCursor;
    DEALLOCATE @MyCursor;
    GO

  • 索引

    2009-12-12 15:51:57

    索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。

    索引是对数据库表中一个或多个列(例如,employee表的姓氏(lname)列)的值进行排序的结构。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。

    索引提供指针以指向存储在表中指定列的数据值,然后根据指定的排序次序排列这些指针。数据库使用索引的方式与使用书的目录很相似:通过搜索索引找到特定的值,然后跟随指针到达包含该值的行。

    在数据库关系图中,可以为选定的表创建、编辑或删除索引/键属性页中的每个索引类型。当保存附加在此索引上的表或包含此表的数据库关系图时,索引同时被保存。有关详细信息,请参见创建索引。

    通常情况下,只有当经常查询索引列中的数据时,才需要在表上创建索引。索引将占用磁盘空间,并且降低添加、删除和更新行的速度。不过在多数情况下,索引所带来的数据检索速度的优势大大超过它的不足之处。然而,如果应用程序非常频繁地更新数据,或磁盘空间有限,那么最好限制索引的数量。

    索引类型

    根据数据库的功能,可在数据库设计器中创建三种类型的索引——唯一索引、主键索引和聚集索引。

    提示:尽管唯一索引有助于找到信息,但为了获得最佳性能,建议使用主键约束或唯一约束。

    唯一索引:唯一索引不允许两行具有相同的索引值。

    主键索引:数据库表通常有一列或列组合,其值用来唯一标识表中的每一行。该列称为表的主键。

    在数据库关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。

    聚集索引:聚集索引中,表中各行的物理顺序与键值的逻辑(索引)顺序相同。表只能包含一个聚集索引。

    如果不是聚集索引,表中各行的物理顺序与键值的逻辑顺序不匹配。聚集索引比非聚集索引有更快的数据访问速度

    在Microsoft?SQLServer?数据库中可以创建聚集索引。在聚集索引中,表中各行的物理顺序与索引键值的逻辑(索引)顺序相同。表只能包含一个聚集索引。聚集索引通常可加快UPDATE和DELETE操作的速度,因为这两个操作需要读取大量的数据。创建或修改聚集索引可能要花很长时间,因为执行这两个操作时要在磁盘上对表的行进行重组。

    可考虑将聚集索引用于:

    1:包含数量有限的唯一值的列,如state列只包含50个唯一的州代码。

    2:使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、<和<=。

    3:返回大结果集的查询。(摘自Microsoft?SQLServer?帮助)

    聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。

    当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员ID列emp_id查找特定雇员的最快速的方法,是在emp_id列上创建聚集索引或PRIMARYKEY约束。

    在创建聚集索引之前,应先了解您的数据是如何被访问的。可考虑将聚集索引用于:

    1包含大量非重复值的列。

    2使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、<和<=。

    3被连续访问的列。

    4返回大型结果集的查询。

    5经常被使用联接或GROUPBY子句的查询访问的列;一般来说,这些是外键列。对ORDERBY或GROUPBY子句中指定的列进行索引,可以使SQLServer不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。

    6OLTP类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。

    聚集索引不适用于:

    1频繁更改的列这将导致整行移动(因为SQLServer必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

    2宽键来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。

    说明:如果该表上尚未创建聚集索引,且在创建PRIMARYKEY约束时未指定非聚集索引,PRIMARYKEY约束会自动创建聚集索引。

    注意事项:定义聚集索引键时使用的列越少越好,这一点很重要。如果定义了一个大型的聚集索引键,则同一个表上定义的任何非聚集索引都将增大许多,因为非聚集索引条目包含聚集键。当把SQL脚本保存到可用空间不足的磁盘上时,索引优化向导不返回错误。

    索引的缺点

    到目前为止,我们讨论的都是索引的优点。事实上,索引也是有缺点的。

    首先,索引要占用磁盘空间。通常情况下,这个问题不是很突出。但是,如果你创建每一种可能列组合的索引,索引文件体积的增长速度将远远超过数据文件。如果你有一个很大的表,索引文件的大小可能达到操作系统允许的最大文件限制。

    第二,对于需要写入数据的操作,比如DELETE、UPDATE以及INSERT操作,索引会降低它们的速度。这是因为MySQL不仅要把改动数据写入数据文件,而且它还要把这些改动写入索引文件。

    在大型数据库中,索引是提高速度的一个关键因素。不管表的结构是多么简单,一次500000行的表扫描操作无论如何不会快。如果你的网站上也有这种大规模的表,那么你确实应该花些时间去分析可以采用哪些索引,并考虑是否可以改写查询以优化应用。要了解更多信息,请参见MySQLmanual。另外注意,本文假定你所使用的MySQL是3.23版,部分查询不能在3.22版MySQL上执行。

    转自于:什么时候才要建索引,什么时候不要建索呢?

    以下情况不要建索引:

    • 1、如果每次都需要取到所有表记录,无论如何都必须进行全表扫描了,那么是否加索引也没有意义了。
    • 2、对非唯一的字段,例如“性别”这种大量重复值的字段,增加索引也没有什么意义。
    • 3、对于记录比较少的表,增加索引不会带来速度的优化反而浪费了存储空间,因为索引是需要存储空间的,而且有个致命缺点是对于update/insert/delete的每次执行,字段的索引都必须重新计算更新

    以下情况要建立索引


        SELECT c.companyID, c.companyName FROM Companies c, User u WHERE c.companyID = u.fk_companyID AND c.numEmployees >= 0 AND c.companyName LIKE '%i%' AND u.groupID IN (SELECT g.groupID FROM Groups g WHERE g.groupLabel = 'Executive')

        这条语句涉及3个表的联接,并且包括了许多搜索条件比如大小比较,Like匹配等。在没有索引的情况下Mysql需要执行的扫描行数是77721876行。而我们通过在companyID和groupLabel两个字段上加上索引之后,扫描的行数只需要134行。在Mysql中可以通过Explain Select来查看扫描次数。可以看出来在这种联表和复杂搜索条件的情况下,索引带来的性能提升远比它所占据的磁盘空间要重要得多。

  • 软件测试基础知识

    2008-10-29 14:51:51

    1.软件开发过程的几个主要阶段:
    1)定义。明确开发的目标,软件的需求。
    2
    )计划。制订软件开发所涉及到的计划。
    3
    )设计。设计、编码、编写文档等,完成要求的软件特性。
    4
    )稳定化。主要是测试和缺陷修复,确保软件的质量。
    5
    )安装。安装、提交完成的软件,为客户提供运行环境。
    2.
    几种常用的软件生命周期模型:
    1
    )瀑布模型。2)原型模型。3)增量模型。4)螺旋模型。
    从软件测试人员的角度来看软件开发过程,需要注意的是:测试贯穿在整个开发过程中,而不是在某个阶段集中地做一下测试而其它阶段不用理会测试工作。

    一个软件之所以被认为为质量优秀,是它内在具备了这样一些特性:
    满足用户的需求;
    合理进度、成本、功能关系;
    具备扩展性和灵活性,能够适应一定程度的需求变化;
    能够有效地处理例外的情况;
    保持成本和性能的平衡。

    软件质量保证(Software Quality Assurance-----SQA)是为了确保软件开发过程和结果符合预期的要求而建立的系列规程,以及依照规程和计划采取的一系列活动及其结果评审。

    软件质量保证的活动主要包括:
    技术方法的就用;
    正式技术评审的实施;
    软件测试;
    标准的执行;
    修改的控制;
    度量;
    记录和记录保存。

    软件错误的定义:软件错误是软件产品中存在的导致期望的运行结果和实际结果间出现差异的一系列问题,这些问题包括故障、失效、缺陷。


    软件测试:
    软件测试就是为了发现软件中存在的错误而分析或执行程序的过程。具体地说,软件测试是分析程序或根据软件开发各阶段的规格说明和各程序的内部结构而精心设计出一批测试用例,并利用测试用例来运行程序,以发现程序错误的过程。

    软件测试有两个基本的功能:验证(Verification)和确认(Validation)
    验证指保证软件正确地实现了特写功能的一系列活动。
    确认指保证最终的产品满足系统需求。
    通俗的说:验证保证产品的正确性;确认保证生产了正确的产品。

    软件测试人员应该至少具备以下两个关键领域方面的知识:
    1
    )软件测试技术;
    2
    )被测应用程序及其相关应用领域知识。

    理解以下的描述:
    测试能提高软件的质量,但是提高质量不能依赖测试;
    测试只能证明错误存在,不能证明错误不存在;
    测试的主要困难是不知道该如何进行有效地测试,也不知道什么时候能够放心的结束测试;
    每个程序员都应当测试自己的程序(份内事),但不能作为程序已通过测试的依据(所以项目需要独立的测试人员);
    80-20
    原则:80%的错误聚集在20%的模块中,经常出错的模块改错后还是会经常出错;
    测试应当循序渐进,不要企图一次性做完。"欲速则不达"

    测试人员的目标和主要工作:
    目标:(1.基本目标是发现软件错误;
    2.要尽可能早的找出软件错误;
    3.必需确保找出的软件错误得以关闭。

    主要工作:
    1
    )规划测试任务
    2
    )设计测试(包括编写测试用例等等)
    3
    )建立一个合适的测试环境
    4
    )评估、获取、安装和配置自动测试工具
    5
    )执行测试
    6
    )撰写适当的测试文档

    软件测试的分类
    1
    .从是否需要执行被测试软件的角度分:有静态测试和动态测试。
    2
    .从测试是否针对软件结构和算法的角度分类分:白盒测试和黑盒测试。
    3
    .从测试的不同阶段分:单元测试、集成测试、系统测试和验收测试四个阶段。
    其中系统测试有:功能测试、健壮性测试、性能测试、用户界面测试、安全性测试、压力测试、可靠性测试、安装/反安装测试等等。

    针对某些功能作用的测试:
    回归测试:指错误被修正后或软件功能、环境发生变化后进行的重新测试。
    功能测试:测试软件的功能是否符合功能性需求,通常采用黑盒测试方式。
    负载测试:测试软件系统的最大负载,超出此负载软件有可能会失常。
    压力测试:与负载测试差不多,叫法不同。
    易用性测试:测试软件是否易用,主观性比较强。一般要根据用户的反馈信息来评价。
    安装与反安装测试:测试软件在"全部、部分、升级"等状况下的安装/反安装过程。
    恢复测试:测试系统从故障中恢复的能力。
    安全性测试:测试系统防止非法侵入的能力。
    兼容性测试:测试系统与其它软件、硬件兼容的能力。
    内存泄漏测试:测试软件在运行过程中是否会造成内存泄漏。
    比较测试:通过与同类产品比较,考察该产品的优点、缺点。
    Alpha
    测试:一种先期的用户测试,此时系统刚刚开发完成。
    Beta
    测试:一种后期的用户测试,此时系统已经通过内部测试,大部分错误已经改正,即将正式发行。同Alpha测试一样都由用户进行,场地不同,Alpha测试一般是把用户请到开发方的场地来测试,Beta测试是指在一个或多个用户的场所进行测试。

    测试工作的主要步骤:
    1
    )测试计划:测试人员要首先对需求进行分析,最终定义一个测试集合。
    2
    )测试设计与开发:根据软件需求、说明书完成测试用例设计并编写必要的测试驱动程序。
    3
    )执行测试:需要做的工作是,建立测试环境;根据前面编写的测试计划和测试用例运行测试;记录测试结果;报告软件缺陷;跟踪软件缺陷直至其被处理;分析测试结果

     

     测试工程师职业素质
    1
    )责任心2)学习能力3)怀疑精神4)沟通能力5)专注力6)洞察力7)团队精神8)注重积累

    ----这份资料不知道当初从哪转载的了,所以在此没有注明出处,谢谢当初共享资料的前辈!-----


                                                 

     

  • 测试过程中如何进行Bug描述

    2008-10-27 08:43:45

     

    1术语解释

    测试程序:提供给测试组测试的程序;

    测试计划:对测试程序(构件、应用程序、系统等)及其目标进行简要说明;

    测试bug:不符合测试需求的错误,也就是缺陷;

    错误跟踪系统:是某个程序或应用系统,使得项目组可以报告、管理以及分析错误报告和错误趋势,如Rational ClearQuest就是一个错误跟踪系统

    2、为什么要提交bug

    在得到一个详尽的测试程序后,剩下的工作就是执行测试计划了。但是由于任何由人编写的程序都不可避免的存在着不符合测试需求的错误,也就是bug。因此需要一个方法来跟踪、分析和展示那些测试活动,避免偏离最小。这种方法称之为错误跟踪系统。它主要是有效的管理缺陷,实现以下作用:

    1)减少由于缺陷报告不明确而被开发组驳回的情况;

    2)加快缺陷的处理速度;

    3)提高测试的可信度;

    4)加强测试组与开发组在整个项目过程中的团队合作

    3、如何才能提交好的测试bug

    在有些组织里,程序员几乎会把一半的测试bug返回给测试组,因为那些错误不可再现、没有发现错误、同设计要求一致,或者错误报告根本无法操作。如果错误报告有如此高的返回率,基本可以认为是过程崩溃,需要立即解决:因为编写这些报告浪费了时间;会影响程序员和测试人员之间的团队凝聚力;最糟糕的是失去改进产品质量的机会。

    有些错误总是不可再现的或提出质疑的。有些错误只是间断地在模糊的或极端的条件下表现出来。有时候,测试环境和程序员之间的不一致会导致“在我的系统上工作良好”的反应。在需求不清楚的项目中,在一定的测试条件下,对“正确”行为的观点可以存在合理的不同。有时候,当真正的问题在于糟糕的测试过程、测试数据或不正确的测试用例时,测试人员可能错误解释测试测试结果和报告错误。

    为了防止这类问题,要提交好的测试bug,作为一个好的测试人员,必须遵循以下八个步骤:

    1) 结构:无论你是做探索性的或是描述性的、手工的或自动的测试,都要认真仔细的测试;

    2)再现:尽量三次再现故障。如果问题是间断的,那么最好报告问题发生的概率;例如,每3次出现一次,每3次出现2次等;

    3) 推广:确定系统其他部分是否可能出现这种错误,以及使用不同的数据是否可能出现这种问题,特别是那些存在严重影响的问题。

    4)总结:简要描述客户或用户的质量体验和观察到的一些特征。

    5)压缩:精简任何不必要的信息,特别是冗余的测试步骤。

    6)去除歧义:使用清晰的语言,尤其要避免使用那些有多个不同或相反含义的词汇。

    7)中立:公正地表达自己的意思,对错误及其特征的事实进行描述,避免夸张或忽略的语句,引起过度的注意力或忽视。

    8)评审:至少有一个同行,最好是一个有经验的测试工程师或测试经理,在你提交测试报告或测试评估报告之前先自己读一遍。

    好的测试bug描述是告诉读者测试人员发现了什么,而不是测试人员做了什么。因此只需要根据上述八个步骤写下最少的必需重现步骤

    4、如何提交bug

    一个好的错误跟踪系统包括了错误的必要信息,如果做得不好,会造成迷惑,并误导读者。

    好的故障描述应该包括十个基本部分:标题、项目、所属模块、优先级、重要性、异常等级、可重复性、现象、操作过程和附件。

    标题

    使用一两句话来描述错误,告诉经理、开发人员以及其他读者为什么应该关心该问题。好的标题应该着重于出现的bug现象。但是过于简洁易引起误导,使得原本重要的问题被忽视。因此必须应该采用简洁、切中要害的概要,这样才能引起读者的重视。不重要的就描述比较轻微,例如:“联系人的email没有检查合法性”;重要的就要体现比较严重,例如:“填了运营商仍然提示运营商不能为空,使得无法进行下一步的操作”,会更容易让开发人员理解究竟是什么问题及其重要性,并及时处理。

    项目

    是指该错误属于哪一个项目,归哪个项目组解决,使不同的项目组看到和及时定位自己项目的错误。

    所属模块

    是指准确说明发异常等级生错误的模块,切忌发生错误指派模块,导致后续流程错误;

    优先级

    分为以下4级:1级:“马上解决”,表示问题必须马上解决,否则系统根本无法达到预定的需求;2级:“高度重视”,表示有时间就要马上解决,否则系统偏离需求较大或预定功能不能正常实现;3级:“正常处理”,即进入个人计划解决,表示问题不影响需求的实现,但是影响其他使用方面,比如页面调用出错,调用了错误的数据库等;4级:“低优先级”,即问题在系统发布以前必须确认解决或确认可以不予解决。

    重要性

    分为以下5级:1级:“非常严重”,表示缺陷不修改整个系统流程不能继续;2级:“比较严重”,表示缺陷不修改不影响系统其他流程,但是本模块流程不能继续;3级:“一般”,表示缺陷不影响流程;4级:“轻微”,表示缺陷可以延期解决;5级:“优化”,表示修改以后流程会更好。

    异常等级

    有以下5级:系统崩溃-指该错误使得操作系统死机等致命性的错误;应用程序崩溃-指该错误使得测试程序崩溃,即无任何反应;应用程序异常-指错误使得应用程序结果不符合逻辑或是最初的需求;轻微异常-指错误有,但是无伤大雅,例如错别字等;建议-指改进后更好,不改进也对程序无碍。

    可重复性

    是针对问题是否通过执行“操作步骤”就可以重新出现,如果是就“可再现”;如果这个bug只出现了一次,就再也不出现了,称这类问题为“不可再现”;其余的就是“未知”,如每隔几天才出现一次;

    现象

    是对标题的详细描述,因为标题不宜过长,所以现象也是对标题的具体化。

    操作过程

    是指对于可重现的bug,执行这些操作步骤就可以出现该bug;对于不可重现和重现概率为未知的bug,通过备份的数据库和操作过程就可以重现该bug

    附件

    是粘贴必要的附件,如果是可重复性是“可重现”的bug,则可以参考步骤是否复杂,如果很复杂,则可以粘贴附件,从而使得开发人员直接可以明白是什么问题,提高开发人员的修改效率;如果步骤不多有能够重现,则可以不粘贴附件。如果可重复性是“不可再现”的,这种情况必须粘贴附件,以备份出现问题后的情形;如果是未知的,也必须粘贴附件,因为开发人员不可能把时间耗费在等待bug的重现上

    提交bug的流程如下图所示:

     

     

     

    ----转自“风流§狂傲”的个人空间----

  • oldsidney QTP学习笔记 之十四 插入已存在的动作

    2008-09-18 13:19:19

    转自:http://hi.baidu.com/ruanjianceshi/blog/item/9236f819bbc7817adbb4bd23.html

    插入已存在的动作 
    当你在规划一系列的测试个案时,可能会发现有些动作,如登入,可能在很多的测试个案中都会用到,则当你在一个测试脚本中,已经建立好登入的动作后,你可以透过复制或是呼叫方式,在其它的测试脚本中使用登入的动作。


    当你以复制的方式插入动作,则你可以修改这个动作的复本,而且你的修改不会影响原来的动作,原来动作的改变也不会影响这个复本。当你以呼叫的方式插入动作,这个动作会变成只读的动作,你只能在原来的测试脚本中,才能修改被呼叫的动作。使用呼叫的方式,测试脚本可以有比较好的可维护性,因为当被测系统改变时,你只要修改原始的测试脚本就可以了。 


    在接下来建立一个类似ActionA的测试脚本,其中Sign_in以及ReturnHome动作
    将来自外部的测试脚本(以呼叫的方式使用其它测试脚本中的动作)而且FlightOrder动作会作稍微的修改。 
     
    1  插入呼叫(call)的动作 
    首先,你将以呼叫的方式,把ActionA中的Sign_in与ReturnHome动作,插入ActionB中。 
     
    1.  开启一个新的测试脚本存成ActionB 
    假如你忘记怎么作,请参考「录制测试脚本」的步骤1。 

    2.  插入呼叫的Sign_in动作 
    点选【Insert】>【Call to Existing Action】,开启【Select Action】对话窗口。 

    点选【From test】右边的【浏览】按钮,选取【ActionA】测试脚本后点选【Open】,只有可再使用的动作(reusable actions)会显示在【Select Action】对话窗口中。 
    选取Sign_in动作后,按下【OK】,Sign_in[ActionA]动作会出现在测试脚本的最下方,而且图示变成 。 
    注意,你无法在Keyword View中展开Sign_in动作,要检视Sign_in动作,你可以在
    【Action】清单中选取Sign_in动作。由于此动作目前是只读的,假如你要修改的话,只有开启原来的测试脚本(ActionA)才能够修改它。
     
    选取【Action】清单中的Test Flow回到原来的Keyword View。 

    3.  插入呼叫的ReturnHome动作 
    依照步骤2,将ActionA测试脚本中的ReturnHome动作,插入测试脚本的最下方。 

    4.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。

    5.  修改原始的ReturnHome动作 
    点选【File】>【Open】,选取ActionA测试脚本,然后按下【Open】。 
    对ReturnHome动作点二下以便检视其内容。 
    在Keyword View,选取ReturnHome动作的图示,然后点选【Insert】>【Step】>
    【Comment】,开启【Insert Comment】对话窗口,并加入批注。 
    输入:Return to page used in first step of the test,后按下【OK】。 
    加入批注如下: 

    6.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。 

    7.  检查原始ReturnHome动作的修改也影响到呼叫它的测试脚本 
    点选【File】>【Open】,选取ActionB测试脚本,按下【Open】。 
    对ReturnHome[ActionA]动作的图示点二下以便检视其内容,可以看到你在原始测试脚本
    (ActionA)中加入的批注也出现在呼叫它的测试脚本(ActionB)中。 
    在【Action】工具列,点选【Action】清单并选取Test Flow回到原本的Keyword View。
  • oldsidney QTP学习笔记 之十三 插入新动作

    2008-09-18 13:17:44

    转自:http://hi.baidu.com/ruanjianceshi/blog/item/fb9ed72ae40a912dd42af1df.html

    插入新动作 
    接下来,你将会插入一个新的动作,并且录制回到Mercury Tours首页的步骤,让整个测试脚本的起始与结束都是在同一页面。 
     
    1.  插入新的动作 
    点选【Insert】>【New Action】或是点选工具列上的【Insert New Action】按钮,开启
    【Insert New Action】对话窗口。 


     
    在【Name】字段中输入动作名称ReturnHome,并选取【At the end of the test】然后点选
    【OK】。关闭对话窗口后,在测试脚本最后面会显示刚刚新增的ReturnHome动作。 

    2.  准备录制测试脚本 
    启动浏览器并开启【Flight Finder】网页。 
    输入Mercury Tours的网址(
    http://newtours.mercuryinteractive.com)并登入,则会开启
    【Flight Finder】网页。 
    调整一下浏览器与QuickTest的位置,以便可以同时看到二个窗口。 

    3.  变更【Record and Run settings】 
    目前你的【Record and Run settings】是设定在【Open the following browser when a record or run session begins】,所以QuickTest会自动开启浏览器到你指定的网址。不过你现在是
    要在已开启的浏览器上,录制的新的动作,所以你必须变更设定。 
    点选【Test】>【Record and Run Settings】,开启【Record and Run Settings】对话窗
    口。 
    在【Web】页签,选取【Record and run test on any open Web browser】,然后点选
    【OK】。 

    4.  录制 ReturnHome 动作  
    在Keyword View中,选取新的ReturnHome动作。 
    点选【Test】>【Record】或是点选工具列上的【Record】按钮。 
    在【Flight Finder】网页上,点选左边目录区的【Home】,回到Mercury Tours的首页。 
    然后点选工具列上的【Stop】按钮停止录制。 

    5.  回复【Record and Run Settings】设定 
    由于你为了录制ReturnHome动作而变更了【Record and Run Settings】的设定,但是这样
    的变更会影响QuickTest执行测试脚本的方式。对这个测试脚本来说,你需要QuickTest帮
    你自动开启浏览器并浏览Mercury Tours首页,所以你必须将【Record and Run Settings】
    设定改回原本的设定。 
    点选【Test】>【Run and Record Settings】,开启【Run and Record Settings】对话窗
    口。 
    同样在【Web】页签,勾选【Open the following browser when a record or run session 
    begins】,并确认
    6.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮,储存测试脚本。

     
    将动作设定成可再使用的动作 (Reusable Actions) 

    所谓的可再使用的动作(Reusable Actions)相当于程序设计中的函数(function)。当你有个业务流程,在很多测试脚本中都会用到时,你可以将这个业务流程录制成一个可再使用的动作(Reusable Actions)。然后就可以在需要用到此业务流程的测试脚本中,呼叫使用它。

    要让一个动作可以被其它的测试脚本呼叫使用,这个动作必须是一个可再使用的动作(Reusable Actions)。例如,所建立的Sign_in以及ReturnHome动作,在其它的测试脚本
    中,通常也会有相同的动作,所以就可以将其设定为可再使用的动作(Reusable Actions)。 

     
    1.  将Sign_in动作设定成可再使用的动作(Reusable Actions) 
    在Keyword View以鼠标右键点选Sign_in然后选取【Action Properties】,会开启【Action 
    Properties】对话窗口。点选【Reusable action】然后按下【OK】。假如出现讯息窗口,注意一下显示的讯息,然后点选【Do not show this dialog box again】,然后按【OK】。则此动作的图示会变成 ,而且动作的名称会变成蓝色的文字。 

    2.  检视Sign_in动作 
    注意,你现在已经无法在Keyword View上展开Sign_in动作了。 
    当你将某个动作转换成可再使用的动作(Reusable Actions)后,你会发现在Keyword View
    上方出现了一个动作清单,清单中显示在这个测试脚本中的所有可再使用的动作(Reusable Actions),以及所呼叫的外部动作。 

    要检视Sign_in动作的内容,只要在下拉列表中选取Sign_in动作就可以了。 
    在【Action】下拉列表中,选取【Test Flow】就可以回到原本的Keyword View了。 
    3.  将ReturnHome也设定成可再使用的动作(Reusable Actions) 
    对ReturnHome动作,重复步骤1与2。 
    4.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。 
  • oldsidney QTP学习笔记 之十二 将测试脚本切割成多个动作

    2008-09-18 13:16:18

    转自:http://hi.baidu.com/ruanjianceshi/blog/item/f4efd43f8e890bc27d1e71e0.html

    在QuickTest中Action是一个可以被重复使用(reuse)的最小单位,当你建立一个全新的测试脚本时,测试脚本中只有一个Action名为Action1,你可以将整个测试脚本切割成多个Actions,让测试脚本更为模块化且更容易被重复使用。 
     
     使用多个动作 


    假如你检视一下之前录制的测试脚本,你将会发现其实整个测试脚本可以分割成几个特别的业务流程:

     登入网站 
    搜寻并预定机票  
    注销 


    假如您要建立可以预订五张不同机票的测试脚本,就如同我们在「参数化」中所学到的,可以将整个测试脚本参数化。或者,您也可以透过将测试脚本切割成三个动作:登入网站、搜寻并预定机票、注销,然后将第二个动作参数化,以仿真一个用户登入,然后预定五张机票,最后再注销。 


    要将测试脚本切割成动作,你可以插入新的动作、将一个动作切割成二个动作、插入已经存在的动作、或是呼叫已经存在的动作。 


    你可以使用以下的菜单选项或工具列上的按钮,在录制测试脚本时或是录制完测试脚本后,插入动作:

      点选【Insert】>【New Action】或是工具列上的【Insert New Action】按钮。 

      点选【Step】>【Split Action】或是工具列上的【Split Action】按钮。   点选【Insert】>【Copy of Action】或是在Action上点选鼠标右键,选取【Insert Copy of Action】。   点选【Insert】>【Call to Action】或是在Action上点选鼠标右键,选取【Insert Call to Action】。 
     
    建立新动作 
    接下来,建立一个分割成三个动作的测试脚本。 
     


      录制测试脚本 
    1.  执行QuickTest并开启一个全新的测试脚本 
    请参考「录制测试脚本」的步骤.
    http://hi.baidu.com/ruanjianceshi/blog/item/a26d19d8b7d53b3532fa1c36.html 


    2.  开始录制Mercury Tours范例网站 
    接下来录制一个与「录制测试脚本」中类似的测试脚本。不过为了练习如何
    使用多个actions,这个测试脚本的执行步骤有稍微的经过安排。


    首先先关闭所有的浏览器。 
    点选【Test】>【Record】或是点选工具列上的【Record】按钮,将开启【Record and Run Settings】对话窗口。 

    1.在【Web】页签,点选【Open the following browser when a record or run session
    begins】。 在【Type】清单中选择使用的浏览器,并在【Address】字段中输入
    http://newtours.mercuryinteractive.com。 
    勾选【Do not record and run on browsers that are already open】以及【Close the
    browser when the test is closed】选项。  
    2.【Windows Applications】页签,勾选【Record and run on these applications (opened on session start)】,而且请确认清单中没有任何应用程序。 
    点选【OK】。 
    QuickTest会开启浏览器,显示Mercury Tours首页,并开始录制测试脚本。
    3.  登入Mercury Tours 
    在【User Name】以及【Password】输入你之前注册的账号与密码。 
    点选【Sign-In】。 
    开启【Flight Finder】网页。 

    4.  输入航班信息 
    输入下列数据: 
    【Departing From】:New York 
    【On】:Dec 29 
    【Arriving In】:San Francisco 
    【Returning】:Dec 31 
    其余为默认值,点选【CONTINUE】,开启【Select Flight】网页。 

    5.  选择航班 
    接受默认值,点选【CONTINUE】,开启【Book a Flight】网页。 

    6.  输入必要的旅客信息 
    输入旅客姓名与信用卡号。 
    点选网页下方的【SECURE PURCHASE】,开启【Flight Confirmation】网页。 

    7.  回到【Flight Finder】网页 
    在【Flight Confirmation】网页下方,点选【BACK TO FLIGHTS】,回到【Flight Finder】
    网页。 
    回到【Flight Finder】网页后再停止录制,让开始与结束都是同一页面,这样才可以让测试脚本可以重复执行。 

    8.  停止录制  
    点选工具列上的【Stop】按钮停止录制。  

    9.  将测试脚本储存成「ActionA」 
    点选【File】>【Save As】,将测试脚本储存成「ActionA」。 
    将测试脚本分成二个动作 

    因为你的测试脚本包含了二个主要的业务流程:登入与订票,所以将整个测试流程分成二个动作便相当合理。 
    1.  选择第二个动作要开始的网页 
    在Keyword View,展开(+)【Action1】>【"Welcome: Mercury Tours"】。 

    2.  将测试脚本分成二个动作 
    选取【”Find a Flight: Mercury”】网页,并点选【Step】>【Split Action】或是点选工具列上的【Split Action】按钮,开启【Split Action】对话窗口。 

    3.  输入动作的名称与说明 
    在【1st action】中的【Name】字段输入:Sign_in。 
    在【1st action】中的【Descrīption】字段输入:
    Enters user name and password to sign  in。 
    在【2nd action】中的【Name】字段输入: FlightOrder。 
    在【2nd action】中的【Descrīption】字段输入:Chooses and purchases a flight。 
    其余字段保留默认值,点选【OK】关闭【Split Action】对话窗口。在Keyword View中会出
    现二个动作。 
    点选【View】>【Expand All】检视每个动作的内容。注意,【FlightOrder】动作的开始与结束应该都是【Find a Flight: Mercury】网页。 
     
  • oldsidney QTP学习笔记 之十一 使用万用字符表示法

    2008-09-18 13:14:47

    转自:http://hi.baidu.com/ruanjianceshi/blog/item/3bbfbc3e5ab098fa828b1389.html

    使用万用字符表示法 
    在「建立检查点」建立了文字检查点,以检查某个特定文字。在QuickTest你可以使用万用字符表示法,让测试脚本更有弹性、更能适应应用程序的变化。 
     
      万用字符的表示法 
    透过万用字符表示法,QuickTest 可以利用不同的属性识别对象,也可以检查不同的文字。不管是对象的属性、方法的参数、测试步骤的参数、检查点都可以使用万用字符表示法。 
    万用字符表示法透过一些特殊字符如点(.)、星号(*)、脱字符号(^)、以及中括号([]),组合搜寻的规则。要进一步了解如何使用万用字符表示法,请参考QuickTest Professional User’s Guide。 
     
      使用万用字符表示法 


    接下来,你将会建立一个文字检查点,用来检查飞机出发日期,而此日期会依照你选取的航班不同而改变。你可以透过万用字符表示法,设定文字检查点止检查此日期文字的格式,而不是检查其日期。 
    为此,你将会使用万用字符表示法,设定检查日期的范围是否正确。 
     
    1.  执行QuickTest并开启「Recording」测试脚本 
    假如QuickTest没开启,点选【开始】>【程序集】>【QuickTest Professional】>
    【QuickTest Professional】。 
       假如开启欢迎窗口,点选【Open Existing】。   假如没开启欢迎窗口,点选【File】>【Open】或是点选工具列上的【Open】按钮。 
    在【Open QuickTest Test】对话窗口,选择刚刚录制的「Recording」测试脚本,然后点选
    【Open】。 


    2.  将测试脚本另存成名为【RegExpression】测试脚本 
    点选【File】>【Save As】,将测试脚本存档成「RegExpression」。 


    3.  确认【Active Screen】是开启的  
    假如你没有看到QuickTest右下方的【Active Screen】,点选工具列上的【Active Screen】
    按钮,或是点选【View】>【Active Screen】。


    4.  选取要建立检查点的文字 
    在Keyword View中,展开(+)【"Welcome: Mercury Tours"】并且点选【"Select a Flight: 
    Mercury"】网页,则这个网页会出现在【Active Screen】。 
    在【Active Screen】,以鼠标框住出发班机的日期12/29/2004,再以鼠标右键点选并选取
    【Insert Text Checkpoint】,开启【Text Checkpoint Properties】对话窗口。 


    5.  使用万用字符表示要检查的文字 
    在【Checked Text】点选【Edit Constant Value Options】按钮,开启【Constant Value 
    Options】对话窗口。 

    在【Value】字段,输入[0-1][0-9]/[0-3][0-9]/200[0-9]。设定QuickTest以MM/DD/200Y文字
    格式检查此文字检查点。 
    勾选【Regular expression】选项,会出现讯息问你要不要在每个特殊字符前加上反斜线,点选【No】。 
    注意:假如你点选【Yes】QuickTest会将特殊字符,如([)、(-)以及(])视作一般字
    符,而非万用字符了。
     
    接受其它默认值,点选【OK】关闭【Constant Value Options】对话窗口,回到【Text 
    Checkpoint Properties】对话窗口。 
    点选【OK】关闭【Text Checkpoint Properties】对话窗口。 
    QuickTest会在测试脚本中,【"Select a Flight: Mercury"】网页的下方加入文字检查点。 

    6.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。 

     
    执行并分析使用万用字符表示法的测试脚本

    接下来将执行测试脚本,并分析其执行结果。 
     
    1.  执行「RegExpression」测试脚本 
    点选工具列上的【Run】按钮,或是点选【Test】>【Run】,开启【Run】对话窗口。 
    选取【New run results folder】并接受预设的执行结果目录名称。  
    点选【OK】,开始执行测试脚本。当执行完毕,会自动开启测试结果窗口。 

    2.  检视检查点的执行结果 
    在results tree,展开(+)【Test RegExpression Summary】>【RegExpression Iteration 1 
    (Row 1)】>【Action1 Summary】>【Welcome: Mercury Tours】>【Select a Flight: 
    Mercury】。 选取【CheckPoint:"[0-1][0-9]/[0-3][0-9"】。 
    可能会注意到检查点的显示名称比你输入的万用字符表示法还短,如果要了解更多的信
    息,请参考「了解检查点的种类」。 

    由于实际值与万用字符表示法的格式是一致的,所以此文字检查点结果为通过。

    3.  关闭测试结果窗口 
    点选【File】>【Exit】关闭测试结果窗口。 
  • oldsidney QTP学习笔记 之十 执行并分析使用输出值的测试脚本

    2008-09-18 13:11:49

    建立输出值 

    转自:http://hi.baidu.com/ruanjianceshi/blog/item/5a97f736985cd0310b55a963.html
    在「参数化」中,使用参数与Data Table让测试脚本可以使用不同的测试资料。同样
    地,也可以从应用程序输出数据到Data Table,而且此数据还可以在测试脚本的后面阶段被使用到。QuickTest会将取得的数据显示在Runtime Data Table。 
    举例来说,你可以透过输出值验证二个不同网页上的航班是一样的,首先你先以输出值将一个网页上的航班编号输出到Data Table,然后用此输出值当成另一个网页上航班编号的预期结果。 
     
      建立一个输出值 
    在「参数化」中,因为在表格检查点中机票价钱的预期结果,并未随着出发地点的改变而变动,导致第二、三次的执行结果是失败的。 
    接下来,将会从【Select a Flight: Mercury】网页上取得机票价钱,并且以取得的机票价钱更新表格检查点的预期结果。如此一来,测试脚本就可以利用在【Select a Flight: Mercury】网页上取得的机票价钱,去验证【Book a Flight: Mercury】上显示的机票价钱。  
     
    1.  执行QuickTest并开启「Parameter」测试脚本 
    假如QuickTest没开启,点选【开始】>【程序集】>【QuickTest Professional】>
    【QuickTest Professional】。   假如开启欢迎窗口,点选【Open Existing】。   假如没开启欢迎窗口,点选【File】>【Open】或是点选工具列上的【Open】按钮。
    在【Open QuickTest Test】对话窗口,选择刚刚录制的「Parameter」测试脚本,然后点选
    【Open】。


    2.  将测试脚本另存成名为「Output」测试脚本 
    点选【File】>【Save As】,将测试脚本存档成「Output」。 


    3.  确认【Active Screen】是开启的 
    假如你没有看到QuickTest右下方的【Active Screen】,点选工具列上的【Active Screen】
    按钮,或是点选【View】>【Active Screen】。 


    4.  选取要输出的文字 
    在Keyword View中,展开(+)【"Welcome: Mercury Toirs"】并且点选【"Select a Flight: 
    Mercury"】网页,则这个网页会出现在【Active Screen】。 
    在「Active Screen」中,选取框住270,但是不包含$符号。然后点选鼠标右键,然后选取
    【Insert Text Output】,会开启【Text Output Value Properties】对话窗口。 

    5.  设定输出值 
    点选【Modify】按钮,开启【Output Options】对话窗口。 

     在【Name】字段会显示Select_a_FlightOutput_Text_out,将其改成depart_flight_price。 
    接受其它默认值,点选【OK】,QuickTest会在Data Table中加入depart_flight_price字
    段。 
    注意:在Data Table 上 depart_flight_price字段的第一行会显示从应用程序上取得的输出
    值—270。在执行时,第一次QuickTest还是会取得一样的值—270,但是接下去第二、三
    次,就会从应用程序上取得实际值,并存放到Data Table 中。
     
    QuickTest会在你选取的测试步骤之前加上一个输出值步骤。 


    6.  修正表格检查点的预期值 
    在Keyword View中,展开 (+)【"Welcome:Mercury Tour"】>【"Book a Flight: Mercury"】。 
    在【Checkpoint "New York to San Francisco"】上点选鼠标右键,选取【Checkpoint 
    Properties】,开启【Table Checkpoint Properties】对话窗口。 
    点选第三行,第三列(被勾选的字段),在【Configure value】中点选【Parameter】,然后按下【Parameter Options】按钮,开启【Parameter Options】对话窗口。 

    并从【Name】下拉列表中选取depart_flight_price。 
    点选【OK】,回到【Table Checkpoint Properties】对话窗口,可以看到这个检查点的预期
    结果已经被参数化。 
    按下【OK】关闭【Table Checkpoint Properties】对话窗口。 

    7.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。

     
    执行并分析使用输出值的测试脚本 
    接下来,你会执行测试脚本并分析其结果。 
     
    1.  执行「Output」测试脚本 
    点选工具列上的【Run】或试点选【Test】>【Run】,开启【Run】对话窗口。 
    选取【New run results folder】,其余为默认值。 
    点选【OK】开始执行测试脚本。当执行完毕,会自动开启测试结果窗口。 

    2.  检验执行时期的数据(run-time data) 
    在测试结果窗口中,点选results tree上的 Run-Time Data,可以在表格中看到测试执行时撷
    取到的输出值,而且在depart_flight_price字段中显示不同的机票价钱。
    3.  检视检查点的结果 
    点选【View】>【Expand All】。 
    选取【Output Iteration 1 (Row 1)】>【"Book a Flight: Mercury"】>【Checkpoint:"New York 
    to San Francisco"】。 
    注意:在【Details】窗格中,显示检查点的结果是通过的。 
    同样地,也检视Iterations 2以及3,在【Details】窗格中,检查点的结果也是通过的。 

    4.  关闭测试结果窗口  
    点选【File】>【Exit】关闭测试结果窗口。 
  • oldsidney QTP学习笔记 之九参数化的修正及分析执行步骤

    2008-09-18 13:10:52

    转自:http://hi.baidu.com/ruanjianceshi/blog/item/14b4d539290b9ef33a87ce17.html

    修正受到参数化影响的测试步骤 


    当某个测试步骤被参数化后,有可能会影响到其它的测试步骤也需要作参数化的动作。接下来,您将会对出发地点的文字检查点作参数化,以符合您对出发地点作参数化的预期结果。 
     
    1.  修改文字检查点 
    在Keyword View中,展开(+)【"Welcome: Mercury Tours"】>【"Flight Confirmation: 
    Mercury"】。 
    然后点选鼠标右键,选取【Checkpoint Properties】,开启【Text Checkpoint Properties】
    对话窗口。

     对文字检查点作参数化 
    在【Checked Text】的【Constant】字段中会显示「New York」,表示测试脚本每次执行
    时,这个文字检查点的预期值为「New York」。 
    点选【Parameter】。 
    点选【Parameter Options】按钮,开启【Parameter Options】对话窗口。 

     在【Name】下拉列表中选取「departure」,指定这个文字检查点使用departure字段中的
    值,当成是检查点的预期值。 
    点选【OK】关闭对话窗口,此文字检查点也被参数化了。 


    3.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。 


     
    执行并分析使用参数的测试步骤 


    现在,您可以执行修改完成后的「Parameter」测试脚本了。QuickTest会使用Data Table中
    departure字段的值,执行三次测试脚本。 
     
    1.  执行「Parameter」测试脚本 

    点选工具列上的【Run】或是点选【Test】>【Run】,开启【Run】对话窗口。 
    选取【New run results folder】,其余为默认值。 
    点选【OK】开始执行测试脚本。当执行完毕,会自动开启测试结果窗口。


    检视测试结果  

    Iteration 2: 
    在results tree中,展开(+)【Parameter Iteration 2】>【Action1 Summary】>
    【Welcome Mercury Tours】>【Flight Confirmation: Mercury】。 
    选取【Checkpoint:"New York"】。 


    在检查点的【Details】窗格中,显示Portland为预期结果同时也是实际值,所以此文字
    检查点为通过。你也可以看到在下方的【Application】窗格中,显示机票的出发地点也
    是Portland。 

    Iteration 3: 
    在results tree中,展开(+)【Parameter Iteration 3】>【Action1 Summary】 > 
    【Welcome Mercury Tours】>【Flight Confirmation: Mercury】。 
    选取【Checkpoint:"New York"】。

    在检查点的【Details】窗格中,显示Seattle为预期结果同时也是实际值,所以此文字
    检查点为通过。你也可以看到在下方的【Application】窗格中,显示机票的出发地点也
    是Seattle。 
    以下的表格显示每次执行时,此文字检查点的结果: 

     

    注意:虽然每次执行时,文字检查点的结果是通过的,但是第二次与第三次的执行结果仍然为失败。这是因为出发地点改变,造成在表格检查点中的机票价钱改变,导致表格检查点失败。在以后将会修正表格检查点,让QuickTest自动更新表格检查点的预期结果,就可以检查正确的票价了。 


    关闭测试结果窗口  
    点选【File】>【Exit】关闭测试结果窗口。 
     

  • oldsidney QTP学习笔记 之八参数化

    2008-09-18 13:09:22

    转自:http://hi.baidu.com/ruanjianceshi/blog/item/8f535982050570a20df4d27e.html

    参数化 
         当你在作测试时,你可能会想要使用多种不同的测试数据,针对同样的操作或功能进行测试。 
    举例来说,当你想要使用10组不同的订单数据,来验证新增订单的功能。最简单的方式是你可以直接将这10组不同数据的操作录制下来;另一个聪明的选择是,你可以将新增订单的操作录制下来,然后透过QuickTest的参数化功能,建立这10组不同的数据,如此一来,QuickTest执行测试脚本时,就会分别使用这10组数据,执行10次新增订单的测试了。 


      定义数据表参数 
    在之前录制的测试脚本预订了从纽约到旧金山的机票,在测试脚本中,纽约是个常数
    值,也就是说,每次执行测试脚本预定机票时,出发地点都是纽约。在此将会学习
    如何将测试脚本中的出发地点参数化,如此一来,执行测试脚本时就会以不同的出发地点去预订机票了。 
     
    1.  执行QuickTest并开启「Checkpoint」测试脚本 
    假如QuickTest没开启,点选【开始】>【程序集】>【QuickTest Professional】>
    【QuickTest Professional】。   假如开启欢迎窗口,点选【Open Existing】。   假如没开启欢迎窗口,点选【File】>【Open】或是点选工具列上的【Open】按钮。 
    在【Open QuickTest Test】对话窗口,选择刚刚录制的「Checkpoint」测试脚本,然后点选【Open】。 


    2.  将测试脚本另存成名为「Parameter」测试脚本 
    点选【File】>【Save As】。将测试脚本存档成「Parameter」。


    3.  确认【Active Screen】是开启的 
    假如你没有看到QuickTest右下方的【Active Screen】,点选工具列上的【Active Screen】
    按钮,或是点选【View】>【Active Screen】。


    4.  确认【Data Table】是开启的 
    假如在QuickTest下方没有出现【Data Table】,请点选工具列上的【Data Table】按钮,或是点选【View】>【Data Table】。


    5.  选取要参数化的文字 
    在Keyword View中,展开(+)【Action1】>【"Welcome: Mercury Tour"】>【"Find a Flight: 
    Mercury"】。 

    在Keyword View中点选"fromPort"右边的【Value】字段,然后再点选参数化图示  

     

    。会开启【Value Configuration Options】对话窗口。 

    6.  设定要参数化的属性 
    点选Parameter。如此一来,你就可以使用参数值来取代纽约(New York)这个常数值。 
    请选择【Data Table】这个选项,这个选项表示此参数的值会从QuickTest的Data Table中
    取得。 
    而且【Name】字段会出现p_Item,请将其修改成departure。 

     点选【OK】关闭窗口。QuickTest会在Data Table中新增departure参数字段,并且插入一
    行New York的值。则New York会成为测试脚本执行时所用的的第一个值。


     

     

    在数据表中输入参数 
    如您所见,QuickTest会在Data Table中显示参数值。在此课程,你会在Data Table中加入更多
    笔出发地点的资料,让QuickTest可以使用这些资料执行测试脚本。 
     
    1.  在departure字段输入更多数据 
    点选departure字段的第二行,并输入「Portland」。 
    点选第三行,并输入「Seattle」。 
    按下【Enter】。 
    2.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。 
     

    同时请特别注意一下在Keyword View中的变化。在参数化之前,此测试步骤是显示
    【"fromPort" Select "New York"】。现在,这个测试步骤变成了【fromPort Select 
    DataTable(“departure”, DTGlobalSheet)】。而且当您点选【Value】字段时,【Value】字段会变成如下图所示,表示此测试步骤已经被参数化了,而且其值是从Data Table中的
    departure字段中取得。

  • oldsidney QTP学习笔记 之七执行并分析使用检查点的测试脚本

    2008-09-18 13:07:27

    注:转自:http://hi.baidu.com/ruanjianceshi/blog/item/f324ad4be743ecf082025cd3.html

    执行并分析使用检查点的测试脚本 
    在此将会执行使用检查点的测试脚本,并且分析执行的结果。  
     
    1.  展开整个Keyword View检视整个测试脚本 
    选取【View】>【Expand All】或是使用【*】这个快速键。整个Keyword View就会展开如
    下所示: 

    2.  开始执行测试脚本 
    点选【Run】或是选取【Test】>【Run】,会开启【Run】对话窗口。勾选【New run results folder】,接受默认值。 
    点选【OK】。当测试执行完毕,QuickTest会自动开启测试结果窗口。  


    3.  检视测试结果 
    当QuickTest 执行完测试脚本,测试执行结果窗口会自动开启,而且此次的测试执行结果应
    该是Passed,也就是说,所有的检查点都是Passed。假如你的测试结果是Failed,表示有
    检查点Failed。 


    4.  检视网页检查点的结果 
     在test tree展开(+)【Checkpoint Iteration 1 (Row 1)】>【Action1 Summary】> 【Welcome: Mercury Tours】>【Book a Flight: Mercury】。 
    并选取【Checkpoint:"Book a Flight: Mercury"】。
     
    在右边的【Details】窗格,你可以看到网页检查点的详细结果,例如网页检查点检查了哪些项目。 
    建议:你可以拖曳【Details】窗格下方的边缘,以便能更清楚的看到整个测试的结果。  
    由于所有网页检查的项目,其实际值与预期值相符,所以这个网页检查点的结果是passed。 

    5.  检视表格检查点的结果 
    在test tree的【Book a Flight: Mercury】网页展开(+)【New York to San Francisco】。 
    并选取【Checkpoint:"New York to San Francisco"】。 
    在【Details】窗格你可以看到表格检查点的详细结果,也可以在下方看到整个表格的内容
    (有被检查的字段以黑色粗体文字显示,没有被检查的字段以灰色文字显示)。由于这个表格检查点检查的字段值,其实际值与预期值相符,所以检查点的结果为passed。 

    6.  检视标准检查点的结果 
    在test tree的【Book a Flight: Mercury】网页 展开(+)【passFirst0】。 
    并选取【Checkpoint:"passFirst0"】。 
    在【Details】窗格你可以看到标准检查点的详细结果,如检查了哪些属性,以及属性值为
    何。由于这个检查点所有属性值的实际值与预期值都一样,所以检查点的结果是passed。

     7.  检视文字检查点的结果 
    在test tree的展开(+)【Checkpoint Iteration 1 (Row 1)】>【Action1 Summary】>【Welcome: Mercury Tours】>【Flight Confirmation: Mercury】。 
    并选取【Checkpoint:"New York"】。 
    在【Details】窗格你可以看到文字检查点的详细结果,由于这个文字检查点的实际值与预期值都一样,所以检查点的结果是passed。

    8.  关闭测试结果窗口  
    点选 【File】>【Exit】关闭测试结果窗口。 


  • oldsidney QTP学习笔记 之六文字,表格检查点的建立

    2008-09-18 13:04:45

    注:转自http://hi.baidu.com/ruanjianceshi/blog/item/2832b319a0492e4543a9ad91.html

    检查文字 
    在此你将会建立一个文字检查点,检查在【"Flight Confirmation"】网页中是否出现【"New York"】。 
     
    1.  选取要建立检查点的网页 


    在Keyword View中,展开(+)【Action1】>【"Welcome: Mercury Tours"】。 
    选取Keyword View中的【"Flight Confirmation: Mercury"】网页。在【Active Screen】会显
    示网页的画面。 


    2.  建立文字检查点 
    在【Active Screen】中,选取在「Departing,」下方的「New York」。 
    对选取的文字按下鼠标右键,点选【Insert Text Checkpoint】开启【Text Checkpoint Properties】对话窗口。 

    当【Checked Text】出现在下拉式清单中时,在【Constant】字段会显示你刚刚选取的文
    字。这也就是QuickTest在执行测试脚本时所要检查的文字。 
    点选【OK】关闭对话窗口。 
    QuickTest会在测试脚本上加上一个文字检查点,这个文字检查点会出现在【"Flight Confirmation: Mercury"】网页下方。 

    3.  储存测试脚本 


    点选【File】>【Save】或是点选工具列上的【Save】按钮。 


     检查表格 


    在此你将会建立一个表格检查点,检查【Book a Flight: Mercury】网页上出国航班的价钱。 


    1.  选取要建立检查点的网页  
    在Keyword View中,展开(+)【Action1】>【"Welcome: Mercury Tours"】。 
    选取Keyword View中的【"Book a Flight: Mercury"】网页。在【Active Screen】会显示网页
    的画面。 


    2.  建立表格检查点  
    在【Active Screen】中,在第一个航班的价钱上(New York to San Francisco)—270—点
    选鼠标右键,然后选取【Insert Standard Checkpoint】。 
    会开启【Object Selection – Checkpoint Properties】对话窗口。 
    一开始被选取的是WebElement: 270,这时你要点选上一层的WebTable对象,选取
    WebTable: New York to San Fransisco。 

     注意,你会看到在【Active Screen】上,你选取的表格也会被框起来。点选【OK】。 
    接着开启【Table Checkpoint Properties】对话窗口,显示整个表格的内容。 

    预设是每个字段都会被勾选,表示所有字段都会做检查。你可以对某个字段点二下,取消检查字段,或是选取整个栏或列,执行选取或取消的动作。  
    在每个字段的标题列点二下,取消勾选的图示,然后在第3行、第3列点二下,会在270左
    边出现勾选的图示。则执行时QuickTest会对此字段值做检查。

     

    建议:你可以拖曳的方式改变字段的宽度与高度,以便检视表格内的数据。  
    点选【OK】关闭对话窗口。 
    QuickTest会在测试脚本中,【"Book a Flight: Mercury"】页面下加上一个表格检查点。 

    3.  储存测试脚本 
    点选【File】>【Save】或是点选工具列上的【Save】按钮。 

  • QTP9.2的安装

    2008-09-18 09:19:11

    QTP9.2应用程序下载及破解补丁见如下:

    http://bbs.51testing.com/thread-108263-1-1.html

    1.将以下地址直接拷到下载工具中下载 http://cachefile9.fs2you.com/zh-cn/download/0d2b36bd4c614e632b849f89e1fc1104/qtp92.zipQTP9.2安装程序。

    2.安装的时候,会要求的debugger调试工具安装(选择存放debugger调试工具的路径)。

    3.安装完成后,将QTP破解补丁(mgn-mqt82.EXE)放到安装目录下运行,重启机子即可。

  • 应聘华为 16道经典面试题(转)

    2008-08-20 10:07:42

    在我们的工作中,有很多的客户问到关于华为的面试的问题,希望我们能提供一些关于华为面试的经验,也有很多的客户建议我们能开设这样一个板块,向大家介绍如何面对知名企业的面试,我们也将相关的面试经验收集整理,供大家参阅,今天要讲的是华为的面试经验!
        面试过程中,面试官会向应聘者发问,而应聘者的回答将成为面试官考虑是否接受他的重要依据。对应聘者而言,了解这些问题背后的“猫腻”至关重要。本文对面试中经常出现的一些典型问题进行了整理,并给出相应的回答思路和参考答案。读者无需过分关注分析的细节,关键是要从这些分析中“悟”出面试的规律及回答问题的思维方式,达到“活学活用”。

        问题一:“请你自我介绍一下”

        ■思路:1、这是面试的必考题目。

        2、介绍内容要与个人简历相一致。

        3、表述方式上尽量口语化。

        4、要切中要害,不谈无关、无用的内容。

        5、条理要清晰,层次要分明。

        6、事先最好以文字的形式写好背熟。

        问题二:“谈谈你的家庭情况”

        ■思路:1、况对于了解应聘者的性格、观念、心态等有一定的作用,这是招聘单位问该问题的主要原因。

        2、简单地罗列家庭人口。

        3、宜强调温馨和睦的家庭氛围。

        4、宜强调父母对自己教育的重视。

        5、宜强调各位家庭成员的良好状况。

        6、宜强调家庭成员对自己工作的支持。

        7、宜强调自己对家庭的责任感。

        问题三:“你有什么业余爱好?”

        ■思路:1、业余爱好能在一定程度上反映应聘者的性格、观念、心态,这是招聘单位问该问题的主要原因。

        2、最好不要说自己没有业余爱好。

        3、不要说自己有那些庸俗的、令人感觉不好的爱好。

        4、最好不要说自己仅限于读书、听音乐、上网,否则可能令面试官怀疑应聘者性格孤僻。

        5、最好能有一些户外的业余爱好来“点缀”你的形象。

        问题四:“你最崇拜谁?”

        ■思路:1、最崇拜的人能在一定程度上反映应聘者的性格、观念、心态,这是面试官问该问题的主要原因。

        2、不宜说自己谁都不崇拜。

        3、不宜说崇拜自己。

        4、不宜说崇拜一个虚幻的、或是不知名的人。

        5、不宜说崇拜一个明显具有负面形象的人。

        6、所崇拜的人人最好与自己所应聘的工作能“搭”上关系。

        7、最好说出自己所崇拜的人的哪些品质、哪些思想感染着自己、鼓舞着自己。

        问题五:“你的座右铭是什么?”

        ■思路:1、座右铭能在一定程度上反映应聘者的性格、观念、心态,这是面试官问这个问题的主要原因。

        2、不宜说那些医引起不好联想的座右铭。

        3、不宜说那些太抽象的座右铭。

        4、不宜说太长的座右铭。

        5、座右铭最好能反映出自己某种优秀品质。

        6、参考答案——“只为成功找方法,不为失败找借口”

        问题六:“谈谈你的缺点”

        ■思路:1、不宜说自己没缺点。

        2、不宜把那些明显的优点说成缺点。

        3、不宜说出严重影响所应聘工作的缺点。

        4、不宜说出令人不放心、不舒服的缺点。

        5、可以说出一些对于所应聘工作“无关紧要”的缺点,甚至是一些表面上看是缺点,从工作的角度看却是优点的缺点。

        问题七:“谈一谈你的一次失败经历”

        ■思路:1、不宜说自己没有失败的经历。

        2、不宜把那些明显的成功说成是失败。

        3、不宜说出严重影响所应聘工作的失败经历4、所谈经历的结果应是失败的。

        5、宜说明失败之前自己曾信心白倍、尽心尽力。

        6、说明仅仅是由于外在客观原因导致失败。

        7、失败后自己很快振作起来,以更加饱满的热情

    面对以后的工作。

        问题八:“你为什么选择我们公司?”

        ■思路:1、面试官试图从中了解你求职的动机、愿望以及对此项工作的态度。

        2、建议从行业、企业和岗位这三个角度来回答。

        3、参考答案——“我十分看好贵公司所在的行业,我认为贵公司十分重视人才,而且这项工作很适合我,相信自己一定能做好。”

        问题九:“对这项工作,你有哪些可预见的困难?”

        ■思路:1、不宜直接说出具体的困难,否则可能令对方怀疑应聘者不行。

        2、可以尝试迂回战术,说出应聘者对困难所持有的态度——“工作中出现一些困难是正常的,也是难免的,但是只要有坚忍不拔的毅力、良好的合作精神以及事前周密而充分的准备,任何困难都是可以克服的。”

        问题十:“如果我录用你,你将怎样开展工作”

        ■思路:1、如果应聘者对于应聘的职位缺乏足够的了解,最好不要直接说出自己开展工作的具体办法。

        2、可以尝试采用迂回战术来回答,如“首先听取领导的指示和要求,然后就有关情况进行了解和熟悉,接下来制定一份近期的工作计划并报领导批准,最后根据计划开展工作。”

        问题十一:“与上级意见不一是,你将怎么办?”

     ■思路:1、一般可以这样回答“我会给上级以必要的解释和提醒,在这种情况下,我会服从上级的意见。”

        2、如果面试你的是总经理,而你所应聘的职位另有一位经理,且这位经理当时不在场,可以这样回答:“对于非原则性问题,我会服从上级的意见,对于涉及公司利益的重大问题,我希望能向更高层领导反映。”

        问题十二:“我们为什么要录用你?”

        ■思路:1、应聘者最好站在招聘单位的角度来回答。

        2、招聘单位一般会录用这样的应聘者:基本符合条件、对这份共组感兴趣、有足够的信心。

        3、如“我符合贵公司的招聘条件,凭我目前掌握的技能、高度的责任感和良好的饿适应能力及学习能力 ,完全能胜任这份工作。我十分希望能为贵公司服务,如果贵公司给我这个机会,我一定能成为贵公司的栋梁!”

        问题十三:“你能为我们做什么?”

        ■思路:1、基本原则上“投其所好”。

        2、回答这个问题前应聘者最好能“先发制人”,了解招聘单位期待这个职位所能发挥的作用。

        3、应聘者可以根据自己的了解,结合自己在专业领域的优势来回答这个问题。

        问题十四:“你是应届毕业生,缺乏经验,如何能胜任这项工作?”

        ■思路:1、 如果招聘单位对应届毕业生的应聘者提出这个问题,说明招聘单位并不真正在乎“经验”,关键看应聘者怎样回答。

        2、对这个问题的回答最好要体现出应聘者的诚恳、机智、果敢及敬业。

        3、如“作为应届毕业生,在工作经验方面的确会有所欠缺,因此在读书期间我一直利用各种机会在这个行业里做兼职。我也发现,实际工作远比书本知识丰富、复杂。但我有较强的责任心、适应能力和学习能力,而且比较勤奋,所以在兼职中均能圆满完成各项工作,从中获取的经验也令我受益非浅。请贵公司放心,学校所学及兼职的工作经验使我一定能胜任这个职位。”

        问题十五:“你希望与什么样的上级共事?”

        ■思路:1、通过应聘者对上级的“希望”可以判断出应聘者对自我要求的意识,这既上一个陷阱,又上一次机会。

        2、最好回避对上级具体的希望,多谈对自己的要求。

        3、如“做为刚步入社会新人,我应该多要求自己尽快熟悉环境、适应环境,而不应该对环境提出什么要求,只要能发挥我的专长就可以了。”

        问题十六:“您在前一家公司的离职原因是什么?”

        ■思路:1、最重要的是:应聘者要使找招聘单位相信,应聘者在过往的单位的“离职原因”在此家招聘单位里不存在。

        2、避免把“离职原因”说得太详细、太具体。

        3、不能掺杂主观的负面感受,如“太幸苦”、“人际关系复杂”、“管理太混乱”、“公司不重视人才”、“公司排斥我们某某的员工”等。

        4、但也不能躲闪、回避,如“想换换环境”、“个人原因”等。

        5、不能涉及自己负面的人格特征,如不诚实、懒惰、缺乏责任感、不随和等。

        6、尽量使解释的理由为应聘者个人形象添彩。 7、如“我离职是因为这家公司倒闭。我在公司工作了三年多,有较深的感情。从去年始,由于市场形势突变,公司的局面急转直下。到眼下这一步我觉得很遗憾,但还要面对显示,重新寻找能发挥我能力的舞台。”

        同一个面试问题并非只有一个答案,而同一个答案并不是在任何面试场合都有效,关键在于应聘者掌握了规律后,对面试的具体情况进行把握,有意识地揣摩面试官提出问题的心理背景,然后投其所好。

     

361/212>
Open Toolbar