在做Web应用程序开发时,在不同的系统之间,经常需要通过Http协议进行通讯。
API要给前端提供接口,接口开发完毕之后,除了进行各个功能单元的单元测试之外,我们还要模拟前端的调用,进行测试。
这种类型的测试,有多种实现办法,比如:
测试方法 | 优点 | 缺点 |
1、写个测试工程,模拟客户端调用 | 和工程集成在一起,不容易丢失 | 开发工作量 |
2、使用浏览器插件(比如Postman、DHC),模拟客户端调用 | 可以保存访问URL,操作简单 | 如果后端负载均衡,想测试某台机器,比如,发版验证,则不适用 |
3、使用Linux命令(curl),模拟客户端调用 | 满足所有场景 | 需要熟悉命令 |
以上各种测试办法各有优缺点,需要根据具体的应用场景进行选择。
本文单独介绍强大的curl,熟练掌握这个命令,不但可以满足各种Http测试场景,而且随着使用的逐步熟练,对于Http协议的掌握,也很有帮助。
参考网址:
curl网站开发指南:http://www.ruanyifeng.com/blog/2011/09/curl.html
Http状态吗详解:http://tool.oschina.net/commons?type=5
cur是强大的,支持多种协议,以http为例,可以模拟多种方式的提交(GET/POST Form/Multipart/Json)。
下面结合服务器端的配置,以及SpringMVC,熟练一些 curl 命令的使用,及返回错误Http状态码时的场景。
错误描述 | 错误原因 |
curl: (7) Couldn't connect to server | 如果由于本地网络的原因,不能连接外网,则报此错误 |
curl: (7) Failed to connect to 127.0.0.1 port 8411: Connection refused | 如果应用还没有启动(判断依据:8411端口没有开启监听),则报此错误 |
Error 503 Service Unavailable | 如果应用已经启动(判断依据:8411端口已经开启监听),但是应用不正常,则可能获取到错误信息 |
错误 | Error 400 Required String parameter 'test' is not present |
SpringMVC 代码 | @ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestParam(value="test", required=false) String test) |
错误的 curl 代码 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --data test=中国 http://127.0.0.1:8411/test/test.do |
错误原因 | 请求时定义了“Entity Head Field”,Content-Type json,导致--data失效 |
正确的 curl 代码 | curl -X POST --form test=中国 http://127.0.0.1:8411/test/test.do curl -X POST --data test=中国 http://127.0.0.1:8411/test/test.do |
Web服务器开启了认证,而客户端没有传入认证信息,或者认证信息错误。最基本的是Basic 认证,截个图说明一下吧,如下:
虽然在各种Web服务器(Nginx,IIS等),很容易的配置BA认证,但由于用户名和密码都是作为明文传递的,所以并不安全。
Amazon的一种认证方法,相比较Basic认证,一样使用简单,但是安全的多,有一些公司在使用,相关文档如下:
http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
http://my.oschina.net/darcyzhu/blog/2724
错误 | Error 405 Request method 'GET' not supported |
SpringMVC 代码 | @ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestParam(value="test", required=false) String test) |
错误的 curl 代码 | curl -X GET --data test=中国 http://127.0.0.1:8411/test/test.do |
错误原因 | Http Method不匹配,服务端支持POST,客户端用GET发起请求 |
正确的 curl 代码 | curl -X POST --form test=中国 http://127.0.0.1:8411/test/test.do curl -X POST --data test=中国 http://127.0.0.1:8411/test/test.do |
错误 | Error 406 Not Acceptable |
SpringMVC 代码 | @ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestBody TestUserInfo userInfo) |
错误的 curl 代码 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --header "Accept:text/html,application/xhtml+xml,application/xml;q=0.9" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
错误原因 | 请求Accept和相应的媒体类型不一致 |
正确的 curl 代码 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --header "Accept:application/json" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
错误 | Error 415 Unsupported Media Type |
SpringMVC 代码 | @ResponseBody @RequestMapping(value = "/test/test", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") public String test(@RequestBody TestUserInfo userInfo) |
错误的 curl 代码 | curl -X POST --header "Accept:text/html,application/xhtml+xml,application/xml;q=0.9" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
错误原因 | 没有定义媒体类型,默认用text/plain,服务器端不支持 |
正确的 curl 代码 | curl -X POST --header "Content-Type:application/json;charset=utf-8" --header "Accept:application/json" -d '{"userId":2}' http://127.0.0.1:8411/test/test.do |
通过 curl 的使用,也加深了我们对 http 这种应用层协议的理解。
应用层协议,应用层面的规范,定义一套请求的规范,定义一套响应的规范,由于这是国际标准化组织的定义,以及工业上的广泛应用,造就了其广泛知名度,到达协议的标准。
我们日常工作中,也会定义一些规范;以前工作中也有这种场景,在Soap出来之前,见过牛人用Delphi写的Http通讯程序程序,也是基于类似于xml标签的方式,定义了一套请求和响应的规范,自己进行解析,当Soap出来后,发现很像;这些规范上升不到协议的程度,也是以上的原因;
我们把协议从高大上的位置,拽下来,和我们的日常规范一样的高度,相当于,把抽象的问题形象化,把微观的问题从宏观上来理解,对于协议的入门理解,很有好处。