结合个人工作,交流软件测试领域相关的概念、测试工具、测试自动化等相关话题,欢迎各路朋友多多交流~

发布新日志

  • 使用开源库,自己来实现基于HTTP的交互模型

    2011-11-09 17:30:56

       一直这样认为,测试人员不是简单地掌握业务、懂得一些测试方法或会使用一些测试工具就可以了。对一个好的测试人员来说,知识面很重要,专业技能也很必要,包括至少会自己动手创造工具。
       这个贴源于前两年为解决一个交互比较复杂的系统的自动化问题,而不用selenium、watir等一些工具,进行自己”钻木取火“而采用一个Spnk库来简单简单实现了HTTP交互,一是解决问题,二也是练习之作。当然,您也可以继续深入做啦。但对我来说,已经够了。先简单介绍一下封装使用过程吧,后续再抽空分享一下在我的自动化解决方案中的应用。
       Spnk一个开源库,它已经封装http协议的处理细节,提供了常用的SP_NKHttpRequestSP_NKTcpSocketSP_NKHttpProtocolSP_NKHttpResponse四个类,提供了完整的实现HTTP操作的一些方法。下面结合一个简单的案例(案例会做一些简化)说明一下封装过程:      

    一、实现一个最基础的请求请求、响应交互:

    创建SP_NKHttpRequest对象,补充HTTP基本消息头信息

    SP_NKHttpRequest request;

    request.setMethod(“POST”);   //这个填写PostGet影响不大,真正调用是后面的SP_NKHttpProtocol的方法决定

    request.setVersion( "HTTP/1.1" );

    request.addHeader( "Connection", "Keep-Alive" );

    request.addHeader( "Host", host.c_str() );// 域名 如www.qq.com

    request.setURI( content.c_str() ); 

    上面的content变量,填充的是完整的http相对路径和请求参数,如:

    /cgi-bin/direct.cgi?AcctType=1&CallBackURL=app_callback.cgi&CmdCode=pay&Extend=&PayAmt=&PayChannel=vnet&ServiceCode=LTMCLUB&SessionKey=&SessionType=NoSession&UserIP=&VerifyKey=


    然后需要和web服务器(apache)建立连接,初始化SP_NKTcpSocket的对象

    SP_NKTcpSocket socket(“172.27.196.213”, 80);

     

    OK,建立连接后,直接使用SP_NKHttpProtocolget(当然也有post)方法,即可完成发送请求操作:

    int iRet = SP_NKHttpProtocol::get( &socket, &request, &response );  

     

    其中引用的response即是 SP_NKHttpResponse对象啦。对响应结果,可以判断如果get返回!=0 即说明http请求失败.

    SP_NKHttpResponse对象提供几个方法常用方法:getStatusCode()获取HTTP状态码;getContent()获取响应内容;getHeaderCount()返回消息头条目;getHeaderValue( int index )getHeaderValue( const char * name )获取头内容。

    如:

           if(response.getContent()!=NULL)

           {

                  sResponse = (char *)response.getContent(); //取出响应内容

           }

          

           strCookie = response.getHeaderName(“Set-Cookie”); //取出响应cookie内容

     

    至此,一个简易的HTTP处理模型就实现了。

     

    二、解决客户端cookie的问题

    涉及的HTTP的测试,cookie是必不可少的,如在我的实现案例中,cookie中保留了必要的加密交易信息。如何解决cookie的问题,使用spnk库可以很轻易地解决:

    strCookie = response.getHeaderName(“Set-Cookie”); //取出响应cookie内容

    http响应中,填写客户端cookie是放在响应的Set-Cookie消息头中,直接调用getHeaderName方法即可取得; 

    http响应也有可能有多个Set-Cookie的响应,这个时候也可以用下面的方式去遍历,分别取出来保存:

    //遍历包头

           for(;(pszHenadName = (char *)response.getHeaderName(i))!= 0;i++)

           {

                  //cookie需要抛出去给第二、三步交易使用

                  if(strcmp(pszHenadName,"Set-Cookie") == 0)   

                  {

                                string cookie = response.getHeaderValue(i);

                                tmpCookies+= cookie.substr(0,cookie.size()-7);  //简单起见,将多个cookie直接拼接在一起了。但由于每个cookie后面都有带一些结束符合,因此在合并时要去除7个字符(cookie对这个格式有严格要求)

                  }                         

           }

     

    当下一步交易需要使用到cookie时,直接将上面获取到的cookie放入到HTTP请求消息头中即可生效:

    request.addHeader( "Cookie", cookie.c_str() );

     

    三、如何解决客户端重定向的问题

    重定向有服务器端的和客户端的,对服务器端就不用我们担心了,apache或其他web服务器会搞定了。但对客户端的重定向,在自己封装web处理时,需要手动处理。一个http的客户端重定向过程如:(以Servlet的重定向为参考)

    在客户端第一次请求后,服务器端返回一个响应,告诉浏览器(客户端)需要跳转到第二个页面去处理,浏览器做响应处理后,即再向服务器端发起对第二个页面的请求。此处的跳转主要两个方式:

    1、  在响应消息头的Location头中:

    判断重定向,应该首先判断http应答中的状态码,3xx的是重定向,Location内指定重定向的地址.

    如果需要进行重定向的,在第一次响应中Location头信息类似:http://www.qq.com/cgi-bin/xxxxxx.cgi?SPItemResponse=35000003%24

    因此使用下面方法去取得即可:

    String nextJumpUrl = response. getHeaderValue(“Location”)

    if(nextJumpUrl!=NULL)

    {

           。。。 //这个时候就可以参照第一部分的方式,再创建一个http请求进行处理啦;

    }

     

    2、  在响应内容中使用javascript脚本进行跳转:

    使用javascript进行调整的方式比较简单,生成的javascript内容就记录在response.getContent()中,如下:

    <script. language=javascript>

    window.location.href='http://www.qq.com/xx/xxx.jsp?SPItemRequest=35000003%24pyXLXj57lzr%2FFYBN%2Bik3URnblwgf6l6AxeCk%2F9Pzt5edWDuveb4bT9k%2B8bYdfl05DYIwTT2qi0sebZuGR74MY7H1hRR4a%2FyKvO1Xv4MIMQx5qgaEO6eYxYRIYBDmSUb%2FGx70E2OASAND7ssBd6lc7WbsEYBpQiKVPzFBI5MFNDc6iTs0lQFMfAfhuLlBwVmaR7G8wBSbTFkcJ%2F4gDYKEyQZKlicEIUETe8bq4cnf7TWK8ik6ADoqb26Bm7ORKQWABx0lIX23Iw1lNp9pGN%2Buz5u8%2FFAaIepg%2BvzN1Gm';

    </script>

    因此,可以使用正则表达式去匹配window.location.href=’*’,解释出其中的内容,然后同样参照第一部分的方式,创建一个http请求去处理即可。


    至此,一个简单的HTTP交互模型就实现了。其实还是很简单的,测试人员都应该可以做起来。至于如何和实际应用结合,期待下次的文章吧。

Open Toolbar