Java+Maven+TestNG interface (API) automation test tutorial

In the previous chapter, we wrote the first test class of get request. In this chapter, we will preliminarily optimize and encapsulate it.

6.1 separate request sending class

First of all, our interface automation testing framework will use a lot of http request sending functions in the future.

Then this part of processing can be separated. Later test classes only need to call the method of the request class to send requests and receive responses.

In our project directory src/main/java, create a new package named com.mytest.httpclient , create a new class named HttpClienUtil under the package.

In this class, we migrated and reconstructed the code written in the previous chapter for sending requests and handling feedback:

package com.mytest.httpclient; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.config.RequestConfig;  
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.client.methods.HttpPut; 
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; 
import org.apache.http.message.BasicNameValuePair; 
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON; 
import com.alibaba.fastjson.JSONObject; 

public class HttpClienUtil {
    private CloseableHttpClient httpClient; 
    private CloseableHttpResponse response; 
    private RequestConfig requestConfig; 
    public String HTTPSTATUS = "HttpStatus";
 
    public HttpClientUtil() {
        requestConfig = RequestConfig.custom().setConnectTimeout(5000).
        setConnectionRequestTimeout(1000).
        setSocketTimeout(10000).build();
    }
    /**
    *
    *	@param connectTimeout	Set the connection timeout in milliseconds.
    *	@param connectionRequestTimeout Set to get a Connection from the Connection manager
    *	Timeout in milliseconds. This property is a new one,
    Because the current version can share the connection pool.
    * @param socketTimeout	The timeout (response time) in milliseconds for the request to get data.
    *	If you access an interface and can't return data within a certain period of time, you will directly give up the call.
    */
    public HttpClientUtil(int connectTimeout, int connectionRequestTimeout,
    int socketTimeout) {
        requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout)
        .setConnectionRequestTimeout(connectionRequestTimeout)
        .setSocketTimeout(socketTimeout).build();
    }

    public JSONObject sendGet(String url, HashMap<String, String> params, HashMap<String,             
    String> headers) throws Exception {
        httpClient = HttpClients.createDefault();
        // Splicing url
        if (params != null) {
            List<NameValuePair> pairs = new ArrayList<NameValuePair>();
            for (Map.Entry<String, String> entry : params.entrySet()) { 
                String value = entry.getValue();
                if (!value.isEmpty()) {
                    pairs.add(new BasicNameValuePair(entry.getKey(),value));
                }
            }
            url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs), "UTF-8");
        }
        HttpGet httpGet = new HttpGet(url);
        try {
            httpGet.setConfig(requestConfig); 
            // Load request header to httpget object
            if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpGet.setHeader(entry.getKey(), entry.getValue());
            }
        }
        response = httpClient.execute(httpGet);
        // Get return parameters
        HttpEntity entity = response.getEntity(); String result = null;
        if (entity != null) {
            result = EntityUtils.toString(entity, "UTF-8");
        }
        // Release request, close connection
        EntityUtils.consume(entity);
        JSONObject jsonobj = JSON.parseObject(result);
        jsonobj.put(HTTPSTATUS,
        response.getStatusLine().getStatusCode());
        return jsonobj;
        } finally {
            httpClient.close(); response.close();
        }
    }

    public JSONObject sendGet(String url, HashMap<String, String> params)
    throws Exception {
        return this.sendGet(url, params, null);
    }

    public JSONObject sendGet(String url) throws Exception {
        return this.sendGet(url, null, null);
    }

}

After the code reconstruction, two constructors are added, one uses the default value and the other can pass the corresponding parameters to it, both of which are used to instantiate the RequestConfig object and set the timeout of the request; the other overloads two sendGet methods, both of which are used to send the get request and get the JSONObject object. For the convenience of use, only one or two parameters can be used sendGet method.

Notice this line of code:

jsonobj.put(HTTPSTATUS, response.getStatusLine().getStatusCode());

Here, the status code corresponding to the response is also pressed into the JSONObject object, so as to obtain the response status code directly through the JSONObject object.

Later, we call these methods of the class directly in the test class.

6.2 introducing JSON parsing tool class

To interpret and verify the response results, we use com.alibaba.fastjson The parseObject method of the JSON object in the package and the corresponding get + data type method of the JSON object to get the key value are shown in the following code:

responseBody = response.getEntity();
//Convert to string
String responseBodyString = EntityUtils.toString(responseBody, "utf-8");
// Create a Json object and serialize the above string into a Json object
JSONObject responseJson = JSON.parseObject(responseBodyString);
// json content parsing
int page = responseJson.getInteger("page");

But because the returned JSON string is not always in such a simple format, sometimes there are JSON arrays and nested JSON strings, so we write a separate class to interpret JSON objects.

Here is a screenshot of the response JSON data corresponding to this get request

The first red box "page" in the figure above is a JSON object. We can find the corresponding value as 2 according to the key "page", while the second red box "data" is a JSON array, not a JSON object. We can't get the value directly, so we need to traverse the array; the third red box "first"_ Name "is in a nested JSON string, which can be based on the" first "of the inner layer JSON object_ Name "to find the corresponding value" Michael ".

Next, we write a JSON parsing tool method class. If it is a JSON object like the first red circle, we directly return the corresponding value. If it is necessary to parse the value of a JSON object like the data array, we construct a method to parse the contents of the first element of the array by default.

 

Package in src/main/java project directory com.mytest.httpclient Next, create a new class file named Util. The code is as follows:

package com.mytest.httpclient; 

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

public class Util { 
 	/** 
 	 * 
 	 * @param responseJson ,This variable takes the response string and converts it into a json object through json 
 	 * @param jpath,This jpath refers to the path writing method that users want to query the value of the json object. For example, jpath writing method:
 	 * 1) per_page 
 	 * 2)data[1]/first_name,data Is a json array, [1] represents the index 
 	 * /first_name Indicates that the name of the json object under an element of the data array is
first_name 
 	 * @return,Back to first_name the value corresponding to the json object name 
 	 */ 


 	 public static String getValueByJPath(JSONObject responseJson, String jpath) { 
 	 	Object obj = responseJson; 
 	 	for (String s : jpath.split("/")) {  
 	 	 	if (!s.isEmpty()) { 
 	 	 	 	if (!(s.contains("[") || s.contains("]"))) { 
 	 	 	 	 	obj = ((JSONObject) obj).get(s); 
 	 	 	 	} else if (s.contains("[") || s.contains("]")) { 
 	 	 	 	 	  obj = ((JSONArray) ((JSONObject) obj).get(s.split("\\[")[0])) 	 	 	 	 	 
 	                  .get(Integer.parseInt(s.split("\\[")[1].replaceAll("]", ""))); 
 	 	 	 	}else if (s.contains("{") || s.contains("}")) { 
 	 	 	 	 	  obj = ((JSONArray) ((JSONObject) obj).get(s.split("\\{")[0])) 	 	 	 	 	 
 	                  .get(Integer.parseInt(s.split("\\{")[1].replaceAll("}", ""))); 
 	 	 	 	} 
 	 	 	} 
 	 	} 
 	 	return obj.toString(); 
 	} 	
} 	

Simply explain the above code. It mainly queries the values of three types of json objects:

The first is the simplest. This json object is in the first layer of the whole json string, such as per in the screenshot above_ Page, this per_page is passed in through the jpath parameter, and the returned result is 2;

The second kind of jpath query, for example, I want to query the first in the first user information under data_ The value of name. At this time, jpath is written as data[0]/first_name, the query result should be Michael;

The third is nested JSON queries, such as the JSON string below, which contains two nested braces. If you want to get the first_ The value of name. At this time, jpath is written as data/first_name.

 

Tags: JSON Apache Java

Posted on Sat, 20 Jun 2020 01:35:22 -0400 by helloise