发布新日志

  • OPEN API平台测试之Restful服务接入

    2008-12-19 20:46:47Top 1

    原始需求:平台在新的版本要支持对标准Rest风格的接口的接入,对用户提交的delete,post,put,update请求要正确的转发。而且请求的url格式要转换成isp能接收的格式,即资源占位符格式。

           需求理解:在本次的测试中隐含了两个大的需求点。如下:

           A.在新的需求中需要测试占位符是否能正确的转换,即客户发起http://sipserver?param1=AAA&param2=BBB&param3=CCC,能否路由到

           http://ispserver/AAA/BBB?param3=CCC

    或者http://ispserver/AAA?param2=BBB&param3=CCC的请求

           B.需要测试delete,post,put,update,get的操作符能否正确的被传递。即用户通过sipisp发起一个delete请求,那么是否能得到正确的isp响应。

           测试模型如下图

        

           

                             图一

           由上图可见如果要验证A的需求,首先需要有Rest风格的服务。由于目前网上已经有很丰富的OPEN API YAHOOAPIgoogleAPI都是标准的Rest风格的接口。所以在实战中选择了Yahoo的接口来测试SIP平台的路由功能。

    如果要验证B的需求,那么想在网上找合适的接口来测试就比较麻烦,所以我们决定自己来搭建Rest风格的服务来进行测试。

    本文将对上面两种方法逐一进行介绍。

    方法一 直接调用Yahoo接口(测试需求点A

    前置条件:注册yahoo接口到SIP平台上,暴露为alitest.ali-002-restyahoo

    测试步骤:一、直接访问yahoo的接口,得到返回值A

              二、通过sip访问服务alitest.ali-002-restyahoo,得到返回值B

              三、验证A是否等于B

    测试代码如下(代码中使用了httpunit,至于如何使用这个工具的工作原理,本文不做详细介绍)

    public class TestRestful {

       

        private String api_server = "http://10.2.226.19:8180/sip/rest";

        static String mysql_url = "jdbc:mysql://10.2.226.19:3306/sip";

     

        @Test

        public void TestAccessYahooFromSip() throws Exception

        {

           String url = "http://boss.yahooapis.com/ysearch/web/v1/car?appid=xq88cS3V34GQE7xg9l2pkbYC0A6YDWHCCcfihbPfaXmUikf002N9z80CAC.Ys47hehhxeQg0Gd4-&format=xml";

           WebConversation conversation = new WebConversation();

           GetMethodWebRequest request = new GetMethodWebRequest(url);

           WebResponse response = conversation.getResponse(request);

           String ExpXmlText = response.getText();

           System.out.println(ExpXmlText);

          

           String sip_appkey = "test_app003";// app_id

           String sip_apiname = "alitest.ali-002-restyahoo";

           String sip_appsecret = "secret_app003";

           String sessionid = "sddddeee2";

           String side = "ysearch";

           String type = "web";

           String version = "v1";

           String content = "car";

           String appid = "xq88cS3V34GQE7xg9l2pkbYC0A6YDWHCCcfihbPfaXmUikf002N9z80CAC.Ys47hehhxeQg0Gd4-";

           String format = "xml";

           String sip_thirdpart = "true";

           DeleteHisRec(sip_apiname);

           util.SIPHelp.Crush_Sip();

           Map<String, String> map = new HashMap<String, String>();

           map.put("side", side);

           map.put("type", type);

           map.put("version", version);

           map.put("content", content);

           map.put("appid", appid);

           map.put("format", format);

           map.put("sip_thirdpart",sip_thirdpart);

           map.put("sip_httpmethod","get");

          

           url = util.SIPHelp.prepareUrl(sip_appkey, sip_apiname, sip_appsecret, api_server, sessionid, map);

           //发起请求

           //System.out.println(url);

           request = new GetMethodWebRequest(url);

           response = conversation.getResponse(request);

           String ActXmlText = response.getText();

           //XMLAssert.assertXMLEqual("对比XML结果", ExpXmlText, ActXmlText);

           String path1 = "/ysearchresponse/resultset_web/result/title";

           XMLAssert.assertXpathValuesEqual(path1,ExpXmlText,path1,ActXmlText);

           System.out.println(ActXmlText);

       }

    }

           方法二 通过自己构建的Restful服务来进行平台透传行为(get,delete,put,post){需求点B测试}

           前置条件:搭建Restful服务。      本文只是简单介绍一下搭建过程。

    1.  安装rubyrailsmysql。安装mysqlrails的特性,它要依照数据库来创建资源。

    2.  创建空的rails web应用骨架

    rails mybook

    3.  创建用于访问的资源,rails将自动完成各种操作的map(路由或映射)

    ruby scrīpt/generate scaffold book name:string isbn:string

    这个命令的意思是创建一个资源(可以认为是一个数据结构)

    在这里是书,它包含书名和刊物号两个字段。

    在做完123的步骤之后我们会发现在mybook\config\routes.rb的代码中多了map.resources :books

    这说明在该服务中books已经是标明是一种资源,而且系统自动为他创建了new,delete,edit等服务

    查看(498) 评论(0) 收藏 分享 管理

  • OPEN API平台测试之Restful服务接入

    2008-12-19 20:46:41Top 1

    原始需求:平台在新的版本要支持对标准Rest风格的接口的接入,对用户提交的delete,post,put,update请求要正确的转发。而且请求的url格式要转换成isp能接收的格式,即资源占位符格式。

           需求理解:在本次的测试中隐含了两个大的需求点。如下:

           A.在新的需求中需要测试占位符是否能正确的转换,即客户发起http://sipserver?param1=AAA&param2=BBB&param3=CCC,能否路由到

           http://ispserver/AAA/BBB?param3=CCC

    或者http://ispserver/AAA?param2=BBB&param3=CCC的请求

           B.需要测试delete,post,put,update,get的操作符能否正确的被传递。即用户通过sipisp发起一个delete请求,那么是否能得到正确的isp响应。

           测试模型如下图

        

           

                             图一

           由上图可见如果要验证A的需求,首先需要有Rest风格的服务。由于目前网上已经有很丰富的OPEN API YAHOOAPIgoogleAPI都是标准的Rest风格的接口。所以在实战中选择了Yahoo的接口来测试SIP平台的路由功能。

    如果要验证B的需求,那么想在网上找合适的接口来测试就比较麻烦,所以我们决定自己来搭建Rest风格的服务来进行测试。

    本文将对上面两种方法逐一进行介绍。

    方法一 直接调用Yahoo接口(测试需求点A

    前置条件:注册yahoo接口到SIP平台上,暴露为alitest.ali-002-restyahoo

    测试步骤:一、直接访问yahoo的接口,得到返回值A

              二、通过sip访问服务alitest.ali-002-restyahoo,得到返回值B

              三、验证A是否等于B

    测试代码如下(代码中使用了httpunit,至于如何使用这个工具的工作原理,本文不做详细介绍)

    public class TestRestful {

       

        private String api_server = "http://10.2.226.19:8180/sip/rest";

        static String mysql_url = "jdbc:mysql://10.2.226.19:3306/sip";

     

        @Test

        public void TestAccessYahooFromSip() throws Exception

        {

           String url = "http://boss.yahooapis.com/ysearch/web/v1/car?appid=xq88cS3V34GQE7xg9l2pkbYC0A6YDWHCCcfihbPfaXmUikf002N9z80CAC.Ys47hehhxeQg0Gd4-&format=xml";

           WebConversation conversation = new WebConversation();

           GetMethodWebRequest request = new GetMethodWebRequest(url);

           WebResponse response = conversation.getResponse(request);

           String ExpXmlText = response.getText();

           System.out.println(ExpXmlText);

          

           String sip_appkey = "test_app003";// app_id

           String sip_apiname = "alitest.ali-002-restyahoo";

           String sip_appsecret = "secret_app003";

           String sessionid = "sddddeee2";

           String side = "ysearch";

           String type = "web";

           String version = "v1";

           String content = "car";

           String appid = "xq88cS3V34GQE7xg9l2pkbYC0A6YDWHCCcfihbPfaXmUikf002N9z80CAC.Ys47hehhxeQg0Gd4-";

           String format = "xml";

           String sip_thirdpart = "true";

           DeleteHisRec(sip_apiname);

           util.SIPHelp.Crush_Sip();

           Map<String, String> map = new HashMap<String, String>();

           map.put("side", side);

           map.put("type", type);

           map.put("version", version);

           map.put("content", content);

           map.put("appid", appid);

           map.put("format", format);

           map.put("sip_thirdpart",sip_thirdpart);

           map.put("sip_httpmethod","get");

          

           url = util.SIPHelp.prepareUrl(sip_appkey, sip_apiname, sip_appsecret, api_server, sessionid, map);

           //发起请求

           //System.out.println(url);

           request = new GetMethodWebRequest(url);

           response = conversation.getResponse(request);

           String ActXmlText = response.getText();

           //XMLAssert.assertXMLEqual("对比XML结果", ExpXmlText, ActXmlText);

           String path1 = "/ysearchresponse/resultset_web/result/title";

           XMLAssert.assertXpathValuesEqual(path1,ExpXmlText,path1,ActXmlText);

           System.out.println(ActXmlText);

       }

    }

           方法二 通过自己构建的Restful服务来进行平台透传行为(get,delete,put,post){需求点B测试}

           前置条件:搭建Restful服务。      本文只是简单介绍一下搭建过程。

    1.  安装rubyrailsmysql。安装mysqlrails的特性,它要依照数据库来创建资源。

    2.  创建空的rails web应用骨架

    rails mybook

    3.  创建用于访问的资源,rails将自动完成各种操作的map(路由或映射)

    ruby scrīpt/generate scaffold book name:string isbn:string

    这个命令的意思是创建一个资源(可以认为是一个数据结构)

    在这里是书,它包含书名和刊物号两个字段。

    在做完123的步骤之后我们会发现在mybook\config\routes.rb的代码中多了map.resources :books

    这说明在该服务中books已经是标明是一种资源,而且系统自动为他创建了new,delete,edit等服务

    查看(390) 评论(0) 收藏 分享 管理

  • 终于可以发文了

    2009-11-27 17:37:01

    但是已经没有兴趣了
  • 一个关于java空格符utf编码引起的外网bug的故事

    2008-12-19 20:43:03

    今天我又遇到外网bug了,真是不幸,又要掏银子了。掏银子事小(只是象征性惩罚),失面子事大,而且bug粗听上去还是非常低级别的。就是有个发送消息的接口(开发者调用这个接口,可以向旺旺的群里边发送消息,听上去非常强大,其实是需要授权的)。但是如果消息参数含空格如:a b的时候,在群的聊天对话筐中看到的却是a+b。究竟是怎么回事呢,难道真的是犯了低级错误了,没有验证到。 下面详细描述一下。不过在描述之前我向先把两个名词解释一下: 

    名次解释:

           ISP:互联网服务提供商,象goole,yahoo,淘宝,支付宝等提供API给开发者的服务提供者

    SIP:服务集成平台,互联网服务提供商,可以在这个平台上公布接口给开发者使用。方便开发者寻找合适的应用,同时对访问的安全性,频度等都进行过滤。对资源进行合理分流。
          
    在实际测试中,我们是针对SIP的平台有单独的测试用例,保证平台本身逻辑的正确性,如对访问的拦截机制,对访问的路由方式,支持访问的接口类型等测试。而针对ISP我们会对ISP服务本身进行测试。就好比一家自来水公司,在对自来水提供服务的过程中。既要对水本身的质量进行检查。还要对自来水管道,压阀设备,笼头进行检查一样。

    而在这次测试用例中我们对ISP提供的接口,即发送消息的接口进行了测试,测试代码片段如下:

        @Test

        public void testCase_HaveSpace() throws Exception {

           String tribId = "26813477";

           String message = " 你好!消息中含特殊字符,且含中文我爱,\"&";

           //String message ="aaa";

          

           String ExpXmlText ="<?xml version=\"1.0\" encoding=\"utf-8\"?>" +"\r\n"+

           "<SendTribMessage>" +"\r\n"+

           "   <ret>10000</ret>" +"\r\n"+

           "</SendTribMessage>";

           //testCase 负责拼装URL 并向isp发送请求,并对请求进行断言,此处略

           testCase(tribId,message,ExpXmlText);

    }

    在代码中很显然 参数message是包含空格的。而测试的结果也是正确的。这时候基本排除ISP的问题,于是我又去检查SIP,看SIP是否有对参数包含空格的情况进行测试。实际情况是SIP居然也已经对参数是空格的情况进行了检查,代码如下:

        @Test

        public void testCase17() throws Exception {

           String sip_appkey = "test_app004";// app_id

           String sip_apiname = "alitest.ali-001-login16";

           String sip_appsecret = "secret_app004";

           String sessionid = "sddddeee";

           String pk = " ";//URLEncoder.encode("中文","utf-8");

           String sip_username = "aaabbb";//URLEncoder.encode("中文","utf-8");

          

           String url = prepareUrl3(sip_appkey, sip_apiname, sip_appsecret,

                  api_server, sessionid,pk,sip_username);

           WebConversation conversation = new WebConversation();

           WebRequest request = new PostMethodWebRequest(url);

           WebResponse response = conversation.getResponse(request);

           String res = new String(response.getText().getBytes(

                  response.getCharacterSet()),"utf-8");

           String exp = " sip_username 没有得到中国";

           assertEquals(exp,res);

        }

     

    很显然参数pk中包含的空格,那是为什么呢。

    而客户报上来的错误是将空格转换成了+号,于是我们就去google了一把,终于发现了一篇类似的文章http://blog.csdn.net/sweetsoft/archive/2008/10/15/3081544.aspx原来由于我们平台要求用户在发起请求的时候都用utf-8编码,而平台会做一次解码再编码(还是utf-8),再发送给isp。而java” ”utf-8解码支持两种格式,一种是%20,一种是+号,SIP平台默认是用+号来解码编码的,也就是说传给ISP的时候是+号代替” ”的,如果ISP也是java的编写的服务,自然能够进行解码的,这就是为什么我直接测试SIP,不会出错的原因,因为我的测试服务也是使用java写的。但是这次群消息的接口是由C++写的,而C++只支持对20%的解码。

        问题是找到了,但是由这个问题,我们发现更严重或者说更重要的问题。就是原来我们测试体系是存在一定问题的。原来我们SIPISP是分开来测试的,也就是说ISP服务接上来的时候默认SIP是不会和它由冲突的,或者由于不兼容带来的bug是不存在的。因为我们和自来水公司是不同的,我们的管道可能用来输送自来水,也有可能用来输送石油。所以单独测试水质和管道是不行的。必须进行集成测试,也就是说必须在产品上线之前,对SIPISP服务进行联调测试。但是是不是把ISP服务本身的业务逻辑,拿过来在SIP上重新跑一遍呢。重新跑一遍其实会带来两个问题。

    1.  跑一遍了以后是否能保证兼容性测试

    2.  是否有资源支持全部重新跑一遍

    第二个问题自然是不用回答了,即使有资源,这样做也是一种浪费。好比做手工测试如果在集成测试阶段,把每个模块本身的业务逻辑都跑一遍,估计哪个有测试经验的人都不会这么干。

    第一个问题我估计也够呛,因为兼容性问题,好比今天的问题本身就不是在做ISP服务测试的时候能发现的,那重新跑也不会发现新问题。

    那究竟该怎么做呢,现在我还没有很好的答案,路漫漫其修远兮 吾将上下而求索,呵呵

  • 吹吹水:也谈灰盒测试

    2008-12-19 20:38:14

    第一次听说灰盒测试,是在金蝶上班的时候,那时候老大让我们研究灰盒测试,当时一头雾水。来阿里工作一年多自己感觉现在做的工作有点像灰盒测试,于是总结了一下,拿出来给大家分享。

    在测试领域众所周知存在黑盒测试和白盒测试,黑盒测试更多是在集成测试阶段进行只关注应用是否符合需求,而不关心代码设计的结构,方式,方法。而白盒测试是针对黑盒测试提出的,前提是知道软件产品内部工作过程。通过测试来检测软件产品内部动作是否按照规格说明书的规定正常进行,通常是在单元测试阶段进行。那么做了这两种测试是否覆盖了软件测试的全部内容,即是否就能保证产品的质量呢。其实是不一定的,或者说如果靠这两种方法来覆盖,投入的代价是比较大的。譬如目前很火的OPEN API的测试,譬如对具备软件平台性质产品的测试。因为通过黑盒手工测试是很难完成的,而白盒测试是在单元测试进行的,显然对产品的测试带来很大的局限性,它也无法测试到产品在集成过程中带来的问题。那么灰盒测试就有它出现的必然性,这就是所谓存在就是合理的。

             灰盒测试的特性:

    1.     灰盒测试通常是在集成测试前期进行的。灰盒测试通常在程序员做完白盒测试之后(有些书上认为白盒测试是由测试人员进行的,我觉得纯属理想主义),在功能测试人员进行大规模集成测试之前进行的。

    2.     灰盒测试是需要了解代码工程的实现的

    3.     灰盒测试是通过类似白盒测试的方法进行的,也就是说和白盒测试的方法是相同的,是通过编写代码,调用函数或者封装好的接口进行的。

    4.     灰盒测试是由测试人员进行测试的。

    灰盒测试和白盒测试的区别

    1.  测试的时段不同,白盒测试在单元测试阶段进行,灰盒测试在集成测试前期进行

    2.  测试的关注对象不同,白盒测试更关注内部实现是否按照规格说明书进行,灰盒测试除了需要关注白盒测试关注的内容还更多从业务层面去考虑问题,考虑更多的组合测试业务场景。

    3.  范围不同,白盒测试更关注单个代码段,函数的正确性,灰盒测试的对象已经基本能完成一个完整的业务功能。

    4.  灰盒测试的代码比较独立,不像白盒测试基本上和程序代码需要做到一一对应。

    灰盒测试和白盒测试的相同点

    1.  目的相同

    2.  方法相同,都是需要通过代码来实现

    3.  对测试人员素质要求相同

    灰盒测试和黑盒测试的不同点

    1.  测试的方法不同。

    2.  对测试人员要求不同。灰盒测试要求比较强的编程能力。

    3.  测试范围不同,关注的对象不同,黑盒测试是覆盖产品范围最广的测试,是灰盒测试无法取代的。但是灰盒测试是可以被黑盒替代的,只是代价比较大,需要很多的测试用例。

    灰盒测试和黑盒测试的相同点

    1.  目的相同

    2.  测试所处的时间段相近。