天天看点

自动化测试,HttpClient调用Rest服务

前言

在项目中需要开发一个新功能:对Rest服务进行自动化测试。

由于服务的接口定义和测试用例(包括参数名词和值以及返回值)是可以获取的,在测试时可以根据接口定义和测试用例信息构建ajax请求,发送到web服务器(可以是代理服务器)来完成服务的测试。

Rest服务接口参数可以是query(跟在浏览器url地址?后面的),path(跟在浏览器地址/后面的),cookie,header,form,requestBody等类型。然而,理想是丰满的,现实是骨干的,发现浏览器对跨域资源请求是有限制的,本文中主要是浏览器对自定义header参数有约束。因此,只能换方式,构建ajax请求发送到java后端,由java发送rest请求,处理完请求后返回数据给前段,由前段解析数据对比预期返回值来判读测试是否成功。

HttpClient

java后端发起url请求的构件有好几个,由于项目已经包含了HttpClient 4.2的依赖,很自然的使用该构件了。

由于以前没有使用过,第一反应是上网查看HttpClient使用实例,发现没有一个行得通,实例的HttpClient版本和我使用的不一致,没办法,上官网吧。好在HttpClient是apache的项目,文档比较全,每个版本的api和demo都很方便的找到,因此不费吹灰之力就搞定了。

package com.service.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

Import java.io.serializable 

@Controller
@RequestMapping("/service/Automation")
public class AutomationServiceController {
	
	@RequestMapping("/run")
	@ResponseBody
	public JsonResponse RunCase(HttpServletRequest request, HttpServletResponse response){
		try{
			String url = request.getParameter("url");
			String methodDefinition = request.getParameter("methodDefinition");
			JSONObject method = JSONObject.parseObject(methodDefinition);
						
			Map<String,String> headerParams= new HashMap<String,String>();		
			Map<String,String> formParams = new HashMap<String,String>();
			Map<String,String> bodyParams = new HashMap<String,String>();
			Map<String,String> cookieParams = new HashMap<String,String>();
			//参数预处理
			if(method.containsKey("params")){
				JSONArray params = JSONObject.parseArray(method.getString("params"));
				for(int i=0;i<params.size();i++){
					JSONObject param = params.getJSONObject(i);
					String paramName = param.getString("name");
					String paramSource = param.getString("source");
					String paramValue = param.getString("value");
					switch(paramSource){
						case "query":
							if(url.indexOf("?")==-1){
								url= url+"?"+paramName+"="+paramValue;
							}else{
								url= url+"&"+paramName+"="+paramValue;
							}
							break;
						case "path":
							int paramPathIndex = url.indexOf("{"+paramName+"}");
							if(paramPathIndex!=-1){
								String tempprefix = url.substring(0,paramPathIndex);
								String temppost="";
								if(url.length() > paramPathIndex+paramName.length()+2){
									temppost = url.substring(paramPathIndex+paramName.length()+2);
								}
								url = tempprefix+paramValue+temppost;
							}
							break;
						case "header":
							headerParams.put(paramName , paramValue);
							break;
						case "cookie":
							cookieParams.put(paramName , paramValue);
							break;
						case "form":
							formParams.put(paramName , paramValue);
							break;
						case "requestbody":
							bodyParams.put(paramName , paramValue);
							break;
						default:
							break;
					}
				}
			}
			String methodType = method.getString("type");
			String methodConsume = method.getString("consumes");
			String data;
//根据方法类型get/post调用不同的处理方法
			if("get".equals(methodType)){
				data=get(url,headerParams,cookieParams);
			}else if ("post".equals(methodType)){
				data=post(url,headerParams,formParams,bodyParams,cookieParams,methodConsume);
			}else{
				return JsonResponse.failure(404, "请求方法出错");
			}
			
			if(data!=null){
				return JsonResponse.success(data);
			}else{
				return JsonResponse.failure(500, "运行case出错");
			}
		}catch(Exception e){
			return JsonResponse.failure(500, "运行case出错");
		}
	}
	
	
	private String get(String url,Map<String,String> headers,Map<String,String> cookies){
        HttpGet get = new HttpGet(url);
        return executeHttpRequest(get,headers,cookies);
	}
	
	private String post(String url,Map<String,String> headers,Map<String,String> forms,
			Map<String,String> bodys,Map<String,String> cookies,String consume){
        HttpPost post = new HttpPost(url);
        
        if(forms!=null && forms.size()>0){
        	List<NameValuePair> valuePairs = new ArrayList<NameValuePair>();
        	for(Map.Entry<String,String> form : forms.entrySet()){
        		NameValuePair nameValuePair = new BasicNameValuePair(form.getKey(), String.valueOf(form.getValue()));
				valuePairs.add(nameValuePair);
        	}
        	try {
     			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(valuePairs, "UTF-8");
     			post.setEntity(formEntity);
     		} catch (UnsupportedEncodingException e) {
     			e.printStackTrace();
     		}
        }else{
//目前只支持一个requestBody来源的参数
        	if(bodys!=null && bodys.size()>0){
//参数类型是form表单行的,requestBody的值是key-value键值对
        		if("form".equals(consume)){
        			List<NameValuePair> valuePairs = new ArrayList<NameValuePair>();
                	for(Map.Entry<String,String> body : bodys.entrySet()){
                		NameValuePair nameValuePair = new BasicNameValuePair(body.getKey(), String.valueOf(body.getValue()));
        				valuePairs.add(nameValuePair);
        				try {
        	     			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(valuePairs, "UTF-8");
        	     			post.setEntity(formEntity);
        	     		} catch (UnsupportedEncodingException e) {
        	     			e.printStackTrace();
        	     		}
        				break;
                	}
        		}else if ("json".equals(consume)){
//参数类型是json类型的,需要设置Content-Type
        			StringEntity strEntity = null;
                	post.getParams().setParameter("Content-Type", "application/json");
                	for(Map.Entry<String,String> body : bodys.entrySet()){
                		ContentType type = ContentType.create("application/json", Charset.forName("UTF-8"));
    					strEntity = new StringEntity(body.getValue(),type);
                		post.setEntity(strEntity);
        				break;
                	}
        		}else if ("xml".equals(consume)){
//参数类型是xml类型的,需要设置Content-Type
        			StringEntity strEntity = null;
                	post.getParams().setParameter("Content-Type", "application/xml");
                	for(Map.Entry<String,String> body : bodys.entrySet()){
                		ContentType type = ContentType.create("application/xml", Charset.forName("UTF-8"));
    					strEntity = new StringEntity(body.getValue(),type);
                		post.setEntity(strEntity);
        				break;
                	}
        		}
            }
        }
        return executeHttpRequest(post, headers, cookies);
	}
	
	//发起http请求,解析响应内容
	private String executeHttpRequest(HttpRequestBase request,
			Map<String,String> headers, Map<String,String> cookies){
		DefaultHttpClient client = new DefaultHttpClient();
		String response = null;
        try {
            if(headers!=null && headers.size()>0){
            	for(Map.Entry<String,String> head : headers.entrySet()){
            		request.addHeader(head.getKey(), head.getValue());
            	}
            }
            
            if(cookies!=null && cookies.size()>0){
            	StringBuilder cookieValuePair = new StringBuilder();
            	for(Map.Entry<String, String> cookie : cookies.entrySet()){
            		cookieValuePair.append(cookie.getKey()).append("=").append(cookie.getValue()).append(";");
            	}
            	request.addHeader("Cookie", cookieValuePair.toString());
            }
            HttpResponse httpResponse = client.execute(request);
            if(httpResponse==null){
            	return null;
            }
            
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
            	HttpEntity entity = httpResponse.getEntity();
            	response = EntityUtils.toString(entity, "UTF-8");
            	return response;
            }else{
            	return null;
            }
        } catch (IOException ex) {
            logger.error("get请求失败" + request.getURI().toString(), ex);
            ex.printStackTrace();
            return null;
        } finally {
        	request.releaseConnection();
        }

//static class JsonReponse here, implements serializable
	}
           

继续阅读