偶是测试新手,希望前辈们能多多指教。

发布新日志

  • 最全LR中性能数据翻译

    2009-05-12 14:44:19

    Transactions(用户事务分析)
    用户事务分析是站在用户角度进行的基础性能分析。
    1、Transation Sunmmary(事务综述)
    对事务进行综合分析是性能分析的第一步,通过分析测试时间内用户事务的成功与失败情况,可以直接判断出系统是否运行正常。
    2、Average Transaciton Response Time(事务平均响应时间)
    “事务平均响应时间”显示的是测试场景运行期间的每一秒内事务执行所用的平均时间,通过它可以分析测试场景运行期间应用系统的性能走向。
    例:随着测试时间的变化,系统处理事务的速度开始逐渐变慢,这说明应用系统随着投产时间的变化,整体性能将会有下降的趋势。
    3、Transactions per Second(每秒通过事务数/TPS)
    “每秒通过事务数/TPS”显示在场景运行的每一秒钟,每个事务通过、失败以及停止的数量,使考查系统性能的一个重要参数。通过它可以确定系统在任何给定时刻的时间事务负载。分析TPS主要是看曲线的性能走向。
    将它与平均事务响应时间进行对比,可以分析事务数目对执行时间的影响。
    例:当压力加大时,点击率/TPS曲线如果变化缓慢或者有平坦的趋势,很有可能是服务器开始出现瓶颈。
    4、Total Transactions per Second(每秒通过事务总数)
    “每秒通过事务总数”显示在场景运行时,在每一秒内通过的事务总数、失败的事务总署以及停止的事务总数。
    5、Transaction Performance Sunmmary(事务性能摘要)
    “事务性能摘要”显示方案中所有事务的最小、最大和平均执行时间,可以直接判断响应时间是否符合用户的要求。
    重点关注事务的平均和最大执行时间,如果其范围不在用户可以接受的时间范围内,需要进行原因分析。
    6、Transaction Response Time Under Load(事务响应时间与负载)
    “事务响应时间与负载”是“正在运行的虚拟用户”图和“平均响应事务时间”图的组合,通过它可以看出在任一时间点事务响应时间与用户数目的关系,从而掌握系统在用户并发方面的性能数据,为扩展用户系统提供参考。此图可以查看虚拟用户负载对执行时间的总体影响,对分析具有渐变负载的测试场景比较有用。
    7、Transaction Response Time(Percentile)(事务响应时间(百分比))
    “事务响应时间(百分比)”是根据测试结果进行分析而得到的综合分析图,也就是工具通过一些统计分析方法间接得到的图表。通过它可以分析在给定事务响应时间范围内能执行的事务百分比。
    8、Transaction Response Time(Distribution)(事务响应时间(分布))
    “事务响应时间(分布)”显示在场景运行过程中,事务执行所用时间的分布,通过它可以了解测试过程中不同响应时间的事务数量。如果系统预先定义了相关事务可以接受的最小和最大事务响应时间,则可以使用此图确定服务器性能是否在可以接受的范围内。

    Web Resources(Web资源分析)
    Web资源分析是从服务器入手对Web服务器的性能分析。
    1、Hits per Second(每秒点击次数)
    “每秒点击次数”,即使运行场景过程中虚拟用户每秒向Web服务器提交的HTTP请求数。
    通过它可以评估虚拟用户产生的负载量,如将其和“平均事务响应时间”图比较,可以查看点击次数对事务性能产生的影响。通过对查看“每秒点击次数”,可以判断系统是否稳定。系统点击率下降通常表明服务器的响应速度在变慢,需进一步分析,发现系统瓶颈所在。
    2、Throughput(吞吐率)
    “吞吐率”显示的是场景运行过程中服务器的每秒的吞吐量。其度量单位是字节,表示虚拟用在任何给定的每一秒从服务器获得的数据量。
    可以依据服务器的吞吐量来评估虚拟用户产生的负载量,以及看出服务器在流量方面的处理能力以及是否存在瓶颈。
    “吞吐率”图和“点击率”图的区别:
    “吞吐率”图,是每秒服务器处理的HTTP申请数。
    “点击率”图,是客户端每秒从服务器获得的总数据量。
    3、HTTP Status Code Summary(HTTP状态代码概要)
    “HTTP状态代码概要”显示场景或会话步骤过程中从Web服务器返回的HTTP状态代码数,该图按照代码分组。HTTP状态代码表示HTTP请求的状态。
    4、HTTP Responses per Second(每秒HTTP响应数)
    “每秒HTTP响应数”是显示运行场景过程中每秒从Web服务器返回的不同HTTP状态代码的数量,还能返回其它各类状态码的信息,通过分析状态码,可以判断服务器在压力下的运行情况,也可以通过对图中显示的结果进行分组,进而定位生成错误的代码脚本。
    5、Pages Downloader per Second(每秒下载页面数)
    “每秒下载页面数”显示场景或会话步骤运行的每一秒内从服务器下载的网页数。使用此图可依据下载的页数来计算Vuser生成的负载量。
    和吞吐量图一样,每秒下载页面数图标是Vuser在给定的任一秒内从服务器接收到的数据量。但是吞吐量考虑的各个资源极其大小(例,每个GIF文件的大小、每个网页的大小)。而每秒下载页面数只考虑页面数。
    注:要查看每秒下载页数图,必须在R-T-S那里设置“每秒页面数(仅HTML模式)”。
    6、Retries per Second(每秒重试次数)
    “每秒重试次数”显示场景或会话步骤运行的每一秒内服务器尝试的连接次数。
    在下列情况将重试服务器连接:
    A、初始连接未经授权
    B、要求代理服务器身份验证
    C、服务器关闭了初始连接
    D、初始连接无法连接到服务器
    E、服务器最初无法解析负载生成器的IP地址
    7、Retries Summary(重试次数概要)
    “重试次数概要”显示场景或会话步骤运行过程中服务器尝试的连接次数,它按照重试原因分组。将此图与每秒重试次数图一起使用可以确定场景或会话步骤运行过程中服务器在哪个时间点进行了重试。
    8、Connections(连接数)
    “连接数”显示场景或会话步骤运行过程中每个时间点打开的TCP/IP连接数。
    借助此图,可以知道何时需要添加其他连接。
    例:当连接数到达稳定状态而事务响应时间迅速增大时,添加连接可以使性能得到极大提高(事务响应时间将降低)。
    9、Connections Per Second(每秒连接数)
    “每秒连接数”显示方案在运行过程中每秒建立的TCP/IP连接数。
    理想情况下,很多HTTP请求都应该使用同一连接,而不是每个请求都新打开一个连接。通过每秒连接数图可以看出服务器的处理情况,就表明服务器的性能在逐渐下降。
    10、SSLs Per Second(每秒SSL连接数)
    “每秒SSL连接数”显示场景或会话步骤运行的每一秒内打开的新的以及重新使用的SSL连接数。当对安全服务器打开TCP/IP连接后,浏览器将打开SSL连接。

    Web Page Breakdown(网页元素细分)
    “网页元素细分”主要用来评估页面内容是否影响事务的响应时间,通过它可以深入地分析网站上那些下载很慢的图形或中断的连接等有问题的
    元素。
    1、Web Page Breakdown(页面分解总图)
    “页面分解”显示某一具体事务在测试过程的响应情况,进而分析相关的事务运行是否正常。
    “页面分解”图可以按下面四种方式进行进一步细分:
    1)、Download Time Breaddown(下载时间细分)
    “下载时间细分”图显示网页中不同元素的下载时间,同时还可按照下载过程把时间进行分解,用不同的颜色来显示DNS解析时间、建立连接时间、第一次缓冲时间等各自所占比例。
    2)、Component Breakdown(Over Time)(组件细分(随时间变化))
    “组件细分”图显示选定网页的页面组件随时间变化的细分图。通过该图可以很容易的看出哪些元素在测试过程中下载时间不稳定。该图特别适用于需要在客户端下载控件较多的页面,通过分析控件的响应时间,很容易就能发现那些控件不稳定或者比较耗时。
    3)、Download Time Breakdown(Over Time)(下载时间细分(随时间变化))
    “下载时间细分(随时间变化)” 图显示选定网页的页面元素下载时间细分(随时间变化)情况,它非常清晰地显示了页面各个元素在压力测试过程中的下载情况。
    “下载时间细分”图显示的是整个测试过程页面元素响应的时间统计分析结果,“下载时间细分(随时间变化)”显示的事场景运行过程中每一秒内页面元素响应时间的统计结果,两者分别从宏观和微观角度来分析页面元素的下载时间。
    4)、Time to First Buffer Breakdown(Over Time)(第一次缓冲时间细分(随时间变化))
    “第一次缓冲时间细分(随时间变化)”图显示成功收到从Web服务器返回的第一次缓冲之前的这段时间,场景或会话步骤运行的每一秒中每个网页组件的服务器时间和网络时间(以秒为单位)。可以使用该图确定场景或会话步骤运行期间服务器或网络出现问题的时间。
    First Buffer Time:是指客户端与服务器端建立连接后,从服务器发送第一个数据包开始计时,数据经过网络传送到客户端,到浏览器接收到第一个缓冲所用的时间。
    2、Page Component Breakdown(页面组件细分)
    “页面组件细分”图显示每个网页及其组件的平均下载时间(以秒为单位)。可以根据下载组件所用的平均秒数对图列进行排序,通过它有助于隔离有问题的组件。
    3、Page Component Breakdown(Over Time)(页面组件分解(随时间变化))
    “页面组件分解(随时间变化)”图显示在方案运行期间的每一秒内每个网页及其组件的平均响应时间 (以秒为单位)。
    4、Page Download Time Breakdown(页面下载时间细分)
    “页面下载时间细分”图显示每个页面组件下载时间的细分,可以根据它确定在网页下载期间事务响应时间缓慢是由网络错误引起还是由服务器错误引起。
    “页面下载时间细分”图根据DNS解析时间、连接时间、第一次缓冲时间、SSL握手时间、接收时间、FTP验证时间、客户端时间和错误时间来对每个组件的下载过程进行细分。
    5、Page Download Time Breakdown(Over Time)(页面下载时间细分(随时间变化))
    “页面下载时间细分(随时间变化)”图显示方案运行期间,每一秒内每个页面组件下载时间的细分。使用此图可以确定网络或服务器在方案执行期间哪一时间点发生了问题。
    “页面组件细分(随时间变化)”图和“页面下载时间细分(随时间变化)”图通常结合起来进行分析:首先确定有问题的组件,然后分析它们的下载过程,进而定位原因在哪里。
    6、Time to First Buffer Breakdown(第一次缓冲时间细分)
    “第一次缓冲时间细分”图显示成功收到从Web服务器返回的第一次缓冲之前的这一段时间内的每个页面组件的相关服务器/网路时间。如果组件的下载时间很长,则可以使用此图确定产生的问题与服务器有关还是与网络有关。
    网络时间:定义为第一个HTTP请求那一刻开始,直到确认为止所经过的平均时间。
    服务器时间:定义为从收到初始HTTP请求确认开始,直到成功收到来自Web服务器的一次缓冲为止所经过的平均时间。
    7、Time to First Buffer Breakdown(Over Time)(第一次缓冲时间细分(随时间变化))
    “第一次缓冲时间细分(随时间变化)”图显示成功收到从Web服务器返回的第一个缓冲之前的这段时间内,场景运行的每一秒中每个网页组件的服务器时间和网络时间。可以使用此图确定场景运行期间服务器或网络出现问题的时间点。
    8、Downloader Component Size(KB)(已下载组件大小)
    “已下载组件大小”图显示每个已经下载的网页组建的大小。通过它可以直接看出哪些组件比较大并需要进一步进行优化以提高性能。
  • 编写脚本和连接监视器

    2009-05-12 11:08:15

    一、脚本编写时需要注意的

           脚本编写要加thinktime,至于加多大合适根据需求和经验;另外thinktime通常放在lr_start_transaction和lr_end_transaction之外,因为action是记录响应时间之和。

          脚本内最好有检查点,意义在于每一次返回的请求时正确的页面;通常用web_reg_find指令,但中文检查点貌似支持不好。

    二、监视连接前的准备工作(针对windows系统服务器)

          首先保证被监视的windows系统开启以下二个服务Remote Procedure Call(RPC) 和Remote Registry Service (这里具体在那里开起服务就不说了)

          被监视的WINDOWS机器:右击我的电脑,选择管理->共享文件夹->共享 在这里面要有C$这个共享文件夹,(要是没有自己手动加)

          然后保证在安装LR的机器上使用运行.输入\\被监视机器IP\C$ 然后输入管理员帐号和密码,如果能看到被监视机器的C盘了,就说明你得到了那台机器的管理员权限,可以使用LR去连接了


    说明: LR要连接WINDOWS机器进行监视貌似要有管理员帐号和密码才行,

  • 常见的网络协议

    2009-05-08 11:56:56

    常见的网络协议有:

    (1)TCP/IP协议

    TCP/IP协议是Internet信息交换、规则、规范的集合,是Internet的标准通信协议,主要解决异种计算机网络的通信问题,使网络在互连时把技术细节隐藏起来,为用户提供一种通用的、一致的通信服务。

    其中,TCP是传输控制协议,规定了传输信息怎样分层、分组和在线路上传输;IP是网际协议,它定义了Internet上计算机之间的路由选择,把各种不同网络的特理地址转换为Internet地址。

    TCP/IP协议是Internet的基础和核心,是Internet使用的通用协议。其中传输控制协议TCP对应于OSI参考模型的传输层协议,它规定一种可靠的数据信息传递服务。IP协议又称为互联网协议,对应于OSI参考模型的网络层,是支持网间互联的数据报协议。TCP/IP协议与低层的数据链路层和物理层无关,这是TCP/IP的重要特点,正因为如此,它能广泛地支持由低层、物理层两层协议构成的物理网络结构。

    (2)PPP协议与SLIP协议

    PPP是点对点协议;SLIP是指串行线路Internet协议。它们是为了利用低速且传输质量一般的电话线实现远程入网而设计的协议。用户要通过拨号方式访问WWW、FTP等资源,必须通过PPP/SLIP协议建立与ISP的连接。

    (3)此外,常见的还有:文件传输协议FTP,邮件传输协议SMTP,远程登录协议Telnet,以及WWW系统使用的超文本传输协议HTTP等,这些都是常用的应用层协议。

  • 性能测试常见误区

    2009-05-06 13:51:38

    请看下面一个性能测试小案例:

    某公司OA产品的新版本即将发布。为了看看系统的性能,决定安排测试工程师A君执行性能测试任务。A君做法如下:

    1.       找到一台PC机,CPU主频1G,内存512M,……;

    2.       在找到的PC机上搭建了测试环境:安装了Oracle9i、Weblogic等系统软件

    3.       在自己的工作机上安装了LoadRunner7.8;

    4.       然后录制了登陆、发布公告等功能

    5.       开始设置30、50、100、500不同的并发用户数目进行并发

    6.       最后得出结论:系统只能运行80个左右的并发用户……

    无疑上面的做法存在很多不合理的地方,例如测试内容太少、测试服务器配置太低等。现实工作中,尽管性能测试以其在测试中独特的地位越来越为软件测试人员、开发人员和用户所重视,但是不管是测试人员还是开发人员,仍然在认识上存在这样或者那样的误区。

    误区1:提高一下硬件配置就可以提高性能了,因此性能测试不重要。

    这是以前系统规模不大时期留下来的认识。DOS时代以及后来Windows操作系统流行的初期,软件规模一般较小,而硬件的更新却是日新月异,软件性能一般不是突出问题,因为只要升级一下硬件,很容易就解决了性能问题。

    现在随着软件规模的扩大,提高硬件配置只是解决性能问题的一个基本手段。因为如果软件自身存在性能问题,再多的资源可能也不够用,例如内存泄漏问题,随着时间的增加,内存终究会被耗尽,最后导致系统崩溃。

    因此,如果用户对软件的性能要求较高,这将意味着不但要从硬件方面来提供性能,还要从数据库、WebServer、操作系统配置等方面入手来提高性能,同时开发的软件系统本身也要进行优化,以便全面提高性能。

    误区2:性能测试在所有其它测试完成后,测试一下看看就可以了。

    这是目前特别普遍的一种现象,例如前面的A君,这种现象主要是没有意识到性能测试的重要性。这种做法最严重的后果是如果性能问题是由软件系统本身产生的,可能会无法根治性能问题。例如架构设计方面的失误,可能意味着软件系统将被废掉。

    当然这并不意味所有的性能测试都要尽早进行,性能测试的启动时间要由软件特点来决定。性能测试策略的制定问题可以参考《程序员》20051011期的《治疗软件亚健康》。

    误区3:性能测试独立于功能测试。

    功能测试可以发现性能问题,性能测试也能发现功能问题。性能测试和功能测试是紧密联系在一起的,原因之一是由于很多性能问题是由软件自身功能缺陷引起的。如果应用系统功能不完善或者代码运行效率低下,通常会带来一些性能问题。功能测试通常要先于性能测试执行或者同步进行,软件功能完善可以保证性能测试进行得更加顺利。

    误区4:性能测试就是用户并发测试。

    仍然有很多人(尤其是开发人员和部分项目实施人员)一提到性能测试,就会联想到并发用户测试,进而认为性能测试就是“测试一下多用户的并发情况”。严格地讲,性能测试是以用户并发测试为主的测试。实际性能测试还包含强度测试、大数据量测试等许多内容。

    误区5:在开发环境下进行一下性能测试就可以了。

    很多时候,在软件开发完成后会进行性能测试,看一看软件的性能。实际上大多数的开发环境因为硬件条件比较差,所以反映不了过多的性能问题。

    因此性能测试要尽量在高配置的用户投产环境下进行。但是有两种可以例外的情况:一种是为了发现某些功能方面的问题,例如为了发现并发算法的一些缺陷;另外一种就是有非常好的硬件资源或者实验室作为开发环境。

    误区6:系统存在瓶颈,不可以使用。

    系统发现了瓶颈,的确是很让人担心的一件事情。不过不要紧,很多的瓶颈可以不必去理会。发现瓶颈的目的主要是为了掌握系统特性,为改善和扩展系统提供依据。因此在性能方面给系统留有30%左右的扩展空间就可以了。

    例如,1000个用户并发时发现了系统瓶颈,而客户的最大并发用户数量在500左右,这样的性能问题完全没有必要处理,要是550或者600个并发用户出现性能问题就应该认真地调整系统性能了。

    误区7:不切实际的性能指标。

    这种现象主要归结于对软件应用需求的不了解。很多时候,尤其是用户会提出很多不切实际的性能指标,例如,针对500个用户使用的OA系统,可能有的用户负责人会提出要满足100个甚至500个用户并发的性能目标,而实际并发数量不会高于50。这种情况只有和用户进行沟通才可以解决。

    上面列举的都是日常性能测试工作中相关人员常犯的错误,这些观点只在极其特殊的情况下才正确。希望读者了解这些常见的性能测试误区后,能在以后的工作中避免类似的情况。

  • 在JAX-WS中的快速信息集

    2009-05-05 14:10:26

        JAX-WS通过检查标准的HTTP头的Accept和Content-Type字段来支持快速信息集。在默认情况下,所有的JAX-WS Web Services的快速信息集都是打开的(通过服务运行时实现)。为了在信息交换中使用快速信息集,客户端必须明确指出客户端运行时有支持快速信息集文档的能力。我们可以通过向服务端发送一个以标准的XML格式编码的初始化请求,这个请求包括了HTTP Accept字段,它的值为MIME类型的application/fastinfoset。在发送初始化请求后,所有的客户端和服务端的数据规范都将以快速信息集格式编码,只要客户端继续使用同一个BindingProvider对象实例就会一直保持这种状态。

        在JAX-WS中,我们可以用两种方法来完成上述的约定:

    1. 在客户端的JVM中设置系统属性。

    2. 在binding provider对象(一个端口协议和委派)中设置属性。

        不管使用哪种方法,都需要指定属性名" com.sun.xml.ws.client.ContentNegotiation"和它的值"pessimistic"。在JAX-WS2.0中为了描述属性名,还在com.sun.xml.ws.developer.JAXWSProperties接口中定义了一个常量,CONTENT_NEGOTIATION_PROPERTY。但这个常量在以后的JAX-WS版本中并不建议使用。

        在这里我们使用第一种方法(也就是设置系统属性),我们可以通过如下的命令行来运行Web service客户端:
     
              java –Dcom.sun.xml.ws.client.ContentNegotiation=pessimistic ...
     
        下面的代码段显示了如何使用Ant来运行Web Sevice客户端:

    <target name="run"> <java fork="true" classname="${client}"> <classpath> <path refid="client.classpath"/> <pathelement location="${build.classes.home}"/> <pathelement location="${basedir}/conf"/> </classpath> <sysproperty key="com.sun.xml.ws.client.ContentNegotiation" value="pessimistic"/> <arg value="${isbn}"/> </java> </target>
    我们还可以通过第二种方法(也就是设置binding provider对象的方法)来达到同样的目的:
    CatalogPortType port = service.getCatalogPort(); ((BindingProvider) port).getRequestContext().put(JAXWSProperties.CONTENT_NEGOTIATION_PROPERTY, "pessimistic"); //((BindingProvider) port).getRequestContext().put("com.sun.xml.ws.client.ContentNegotiation", "pessimistic");
        上面的例子使用了一个端口协议。如果我们正在使用一个Dispatch实例,我们可以再次转换它,以得到一个请求上下文,并设置相应的属性来开启数据传输规范。这是因为在JAX-WS中的Dispatch实例也是一个BindingProvider
  • 使用Filter技术防止用户非法访问页面

    2009-05-05 13:35:16

    一 Filter概述

    Filter 技术是servlet 2.3 新增加的功能,它新增加的功能包括:
    1. 应用程序生命周期事件控制
    2. 新的国际化
    3. 澄清了类的装载规则;
    4. 新的错误及安全属性;
    5. 不赞成使用HttpUtils 类
    6. 各种有用的方法
    7. 阐明并扩展了几个servlet DTD
    8. filter功能

    其中最重要的就是filter功能。它使用户可以改变一个request和修改一个response,
    Filter 不是一个servlet,它不能产生一个response它能够在一个request到达servlet之前
    预处理request,也可以在离开servlet时处理response。换种说法,filter其实是一个
    “servlet chaining”(servlet 链)

    一个filter 包括:
    1. 在servlet被调用之前截获
    2. 在servlet被调用之前检查servlet request
    3. 根据需要修改request头和request数据
    4. 根据需要修改response头和response数据
    5. 在servlet被调用之后截获

    二 Filter在检修ABC系统中的应用

    检修ABC系统在初期搭建框架的时候决定使用Filter来处理用户非法访问URL以及Session过期等问题。
    我们首先定义了一些可以通过URL直接访问的页面,如登陆页面,重登陆页面等。当用户没有登陆而
    尝试访问受保护的URL时,Filter将拦截该请求,并把访问的URL重定向到登陆页面。

    在web.xml中的配置如下:
      <filter>
        <filter-name>filterservlet</filter-name>
        <filter-class>com.comtop.app.common.FilterServlet</filter-class>
        <init-param>
      <param-name>freePages</param-name>
      <param-value>

    /Login.jsp;/LoginAction.do;/index.jsp;/ReLogin.jsp;/SSOLoginAction.do;
         </param-value>
        </init-param>
        <init-param>
          <param-name>toPage</param-name>
          <param-value>/ReLogin.jsp</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>filterservlet</filter-name>
        <url-pattern>*.do</url-pattern>
      </filter-mapping>

      <filter-mapping>
        <filter-name>filterservlet</filter-name>
        <url-pattern>*.jsp</url-pattern>
      </filter-mapping>

    <filter></filter>中定义一些基本信息,比如filter的名称,filter的类以及相关初始参数。这里我
    们把能直接访问的页面定义为freePages,并定义了它的值。还定义了默认的重定向页面,Relogin.jsp。
    接着定义了filter-mapping,让后缀名为.do或.jsp的URL都被Filter所保护。

    FilterServlet具体代码(import部分省略):

    public class FilterServlet extends HttpServlet implements Filter {
     private FilterConfig filterConfig;
     private String[] freePages;
     private String toPage = null;
     private static Logger logger;

     
    /**
      * 初始化filter(这里重写父类的方法)
      * @param filterConfig FilterConfig filter配置对象
      * @throws ServletException
      */

     public void init(FilterConfig filterConfig) throws ServletException {
      logger = Toolkit.getInstance().getLogger(this.getClass().getName());
      int i = 0;
      String pages = null;
      StringTokenizer strTokenizer = null;

      if(logger.isDebugEnabled()) {
       logger.debug("init validate session filter ");
      }

      this.filterConfig = filterConfig;
      
    //以下从配置文件获取配置信息

      this.toPage = filterConfig.getInitParameter("toPage");
      pages = filterConfig.getInitParameter("freePages")
      if(toPage == null || pages == null || toPage.trim().length() == 0 ||
       pages.trim().length() == 0) {
    logger.error("web.xml中filterServlet没有配置初始化参数\"toPage\"或\"freePage\".");
       throw new ServletException(
    "web.xml中filterServlet没有配置初始化参数
    \"toPage\"或\"freePage\"."
    );
      }
      if(logger.isDebugEnabled()) {
       logger.debug("toPage:" + toPage);
       logger.debug("freePages:" + pages);
      }

      strTokenizer = new StringTokenizer(pages, ";");
      this.freePages = new String[strTokenizer.countTokens()];
      while(strTokenizer.hasMoreTokens()) {
       freePages[i++] = strTokenizer.nextToken();
      }

      if(!isFreePage(toPage)) {

    logger.error("web.xml中filter初始化参数\"toPage\"的值必须是\"freePage\"中的某个页面.");
       throw new ServletException(
    "web.xml中filter初始化参数\"toPage\"的值

    必须是\"freePage\"中的某个页面."
    );
      }
     }

     
    /**
      * 判断一个请求URI是否是不过滤的页面
      * @param requestURI String 请求URI
      * @return boolean 返回true为不过滤页面
      */


     private boolean isFreePage(String requestURI) {
      boolean isFree = false;
      for(int i = 0; i < freePages.length; i++) {
       if(requestURI.endsWith(freePages[i])) {
        return true;
       }
      }
      return isFree;
     }

     
    /**
      * 判断请求是否为有效Session
      * @param request ServletRequest 请求对象
      * @return boolean 返回true为有效Session
      */

     private boolean isValidSession(ServletRequest request) {
      HttpServletRequest httpRequest = (HttpServletRequest)request;
      if(httpRequest.getSession().getAttribute(GlobalConstants.SECURITY_LOGIN_KEY)

    ==
       GlobalConstants.SECURITY_IS_LOGIN) {
       return true;
      }
      if(logger.isDebugEnabled()) {
       logger.debug("Session无效,请求:" + httpRequest.getRequestURI());
      }
      return false;
     }

     
    /**
      * 过滤动作
      * @param request ServletRequest 请求对象
      * @param response ServletResponse 响应对象
      * @param filterChain FilterChain 过滤器链对象
      */

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain

    filterChain) {
      String requestURI = null;
      ActionErrors errors = new ActionErrors();
      ActionError errorSession = null;
      HttpServletRequest httpRequest = (HttpServletRequest)request;
      HttpServletResponse httpResponse = (HttpServletResponse)response;
      requestURI = httpRequest.getRequestURI();

            if(logger.isDebugEnabled()) {
       logger.debug("Session filter RequestURI:" + requestURI);
      }
      if(!isFreePage(requestURI)) {
    //如果是保护页面

       if(!isValidSession(request)) {
    //如果Session无效

        String toPageURL = null;
        try {
         toPageURL = httpRequest.getContextPath() + toPage;
         httpResponse.encodeRedirectURL(toPageURL);
         httpResponse.sendRedirect(toPageURL);
    //转发响应

        } catch(IOException ex) {
         logger.error("Session filter过滤时发生IO异常", ex);
        }
       }
      }

      if(!httpResponse.isCommitted()) {
    //如果响应未提交,交给过滤器链

       try {
        filterChain.doFilter(request, response);
       } catch(ServletException sx) {
        filterConfig.getServletContext().log(sx.getMessage());
       } catch(IOException iox) {
        filterConfig.getServletContext().log(iox.getMessage());
       }
      }

     }
     
    //父类的方法

     public void destroy() {
     }
     
     public FilterConfig getFilterConfig() {
      return this.filterConfig;
     }

     public void setFilterConfig(FilterConfig filterConfig) {
      this.filterConfig = filterConfig;
     }

    }


    这里isFreePage方法判断用户访问的URL是否是受保护的,从配置文件中将freePages的值得到后,以分号
    为隔离符将它们取出放到一个数组中,这个数组存放的每个String都是一个freePage。另外,isValidSession
    方法判断在session中是否存在用户的登陆信息,如果用户未登陆,则返回false。每一个filter从doFilter()方法
    中得到当前的request及response,在doFilter()方法中,以下代码完成核心判断:

      if(!isFreePage(requestURI)) {
    //如果是保护页面

       if(!isValidSession(request)) {
    //如果Session无效

        String toPageURL = null;
        try {
         toPageURL = httpRequest.getContextPath() + toPage;
         httpResponse.encodeRedirectURL(toPageURL);
         httpResponse.sendRedirect(toPageURL);
    //转发响应

        } catch(IOException ex) {
         logger.error("Session filter过滤时发生IO异常", ex);
        }
       }
      }

    只有是通过isFreePage(requestURI)和isValidSession(request)两层验证的页面才能被访问到,基本实
    现了防止用户非法访问页面的情况。在实际项目中还可以添加更多的验证方法。

  • SoapUI--WebService性能测试工具介绍

    2009-04-21 11:14:20

       soapUI把工作组织成项目。每个项目主要由需要测试的接口来识别。在这里,接口是指另外一端的指向一个暴露了Web service方法的站点的URI(统一资源标识)。你可以很快地创建一个基本的项目结构;soapUI能接受一个文件的WSDL或者一个Web service终点传输的WSDL。

      项目被有层次结构地组织,并且包含一个或多个TestSuite,TestSuite包含一个或多个TestCase,TestCase包含一个或多个测试步骤。真正的工作 – 发送请求、接受响应、分析结果、改变测试执行流程 – 发生在测试步骤这个层面。TestCase收集和组织需要执行某个对目标的特定操作的步骤。TestSuite汇总那些发生在某个特定区域的Web service的TestCase(例如订购一本书所需要的操作)。你可以通过右键点击项目树中的父节点并选择上下文菜菜单中的“New”菜单,来创建新的TestSuite、TestCase和测试步骤。

      soapUI通过检查附加给测试响应的断言来判断测试是通过还是失败。有大量的断言可供选择,从“simple contains”测试 – 如果某个提供的字符串匹配则表示成功 – 到“XPath matching”,对响应信息执行复杂的XPath表达式匹配成功则表示测试通过。

      测试步骤与程序代码很类似。目前,soapUI定义了6个测试步骤类型,最普遍的是请求(Request),发送一个HTTP请求给目标地址,并接收一个响应。可插入条件跳转测试步骤(Conditonal GoTo)来控制流程。一个或多个检查最近的响应的Xpath表达式是必不可少的。第一个表达式的成功会导致相关测试步骤分支的执行。

      soapUI最强大的是Groovy测试步骤。Groovy是类Java的轻量级脚本语言。一个Groovy测试步骤可以是任何Groovy代码,也就是说基本上Groovy能做的事情,在测试步骤中也能做。测试步骤中的Groovy代码可以访问soapUI框架。例如,一个Groovy测试步骤可以通过JDBC读取数据库的信息,与前一个测试步骤的响应信息进行比较,并响应地修改执行的流程 – 甚至执行另外一个TestCase。

        除了功能测试外,soapUI还能对Web service进行压力测试。每个压力测试包含一个或多个TestCase的执行,并且可以调整用于模拟各种各样的场景。你可以指定测试执行一定量的时间长度,或者一定量的迭代周期,指定以并发的方式执行还是随时间线性变化的方式。

      当压力测试完成后,一个压力测试编辑器会为每个TestCase提供大量的统计数据:执行的次数,最大、最小、平均执行时间等。还可以在统计图表页以图表的形式查看这些数据。

     

1277/7<1234567
Open Toolbar