testng+HttpClient项目实战(一)

发布时间 2023-04-12 10:20:20作者: 导火线叨叨

参考文档:

https://www.cnblogs.com/yingyingja/p/9973960.html

https://www.cnblogs.com/yingyingja/p/9974181.html

https://www.cnblogs.com/yingyingja/p/9974183.html

https://www.cnblogs.com/yingyingja/p/9974186.html

https://www.cnblogs.com/yingyingja/p/9974189.html

(本文的接口用的是Apifox示例项目的新建宠物信息接口)

前置:maven需要在pom.xml中加入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Creams</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.4</version>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.8.8</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>

</project>

 一、实现从Excel读取测试用例,发送post请求,获取响应并进行断言

1、创建测试用例APIcase.xls,在excel中写入接口测试信息,并在src/test下新建resources文件夹,将创建的Excel文件放在文件夹下,测试用例如下所示:

 2、src/main/resources文件下创建新的文件:config.properties,用于存放配置路径文件;

Host=http://127.0.0.1:4523
testData=/src/test/resources/APIcase.xls

 3、读取Excel中的数据并存储:

在/src/java文件夹下新建文件夹:com.test.utils,在文件夹下新建java类ExcelProcess,读取非空的行和列,将获取的数据存入二维数组中:

package com.test.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.File;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelProcess {

    public static Object[][] processExcel(String filePath,int sheetId) throws IOException{
        //数据流读入excel
        File directory = new File(".");
        File file=new File(directory.getCanonicalPath()+filePath);
       // File file=new File(System.getProperty("user.dir")+filePath);
        FileInputStream fis=new FileInputStream(file);
        XSSFWorkbook wb=new XSSFWorkbook(fis);

        //读取特定表单并计算行列数
        XSSFSheet sheet=wb.getSheetAt(sheetId);
        int numberOfRow=sheet.getPhysicalNumberOfRows();
        int numberOfCell=sheet.getRow(0).getLastCellNum();

        //将表单数据处理存入dtt对象
        Object[][] dtt=new Object[numberOfRow][numberOfCell];
        for(int i=0;i<numberOfRow;i++){
            if(sheet.getRow(i)==null || sheet.getRow(i).equals("")){
                continue;
            }
            for(int j=0;j<numberOfCell;j++){
                if(null==sheet.getRow(i).getCell(j) || "".equals(sheet.getRow(i).getCell(j))){
                    continue;
                }
                XSSFCell cell=sheet.getRow(i).getCell(j);
                cell.setCellType(CellType.STRING);
                dtt[i][j]=cell.getStringCellValue();
            }
        }
        return dtt;
    }
}

4、在/src/mian/java文件夹下创建com.test.client文件夹,在文件夹下创建Java类RestfulClient,用来对响应做预处理;

package com.test.client;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.Header;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class RestfuClient {
    CloseableHttpClient httpClient;
    HttpGet httpGet;
    HttpPost httpPost;
    CloseableHttpResponse httpResponse;
    int responseCode;
    JSONObject responseBodyJson;
    HashMap<String,String> hashMap;

    //根据HttpClient获取请求的反馈
    public void getResponse(String url) throws ClientProtocolException,IOException{
        httpClient=HttpClients.createDefault();
        httpGet=new HttpGet(url);
        httpResponse = httpClient.execute(httpGet);
    }

    public void sendPost(String url, List<NameValuePair> params,HashMap<String,String> headers) throws ClientProtocolException,IOException{
        httpClient=HttpClients.createDefault();
        //创建post请求对象
        httpPost =new HttpPost(url);

        //设置请求主体格式
        httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));

        //设置头部信息,Iterator是迭代器,keyset返回hashmap中所有key组成的set视图
        Set<String> set=headers.keySet();
        for(Iterator<String> iterator=set.iterator();iterator.hasNext();){
            String key=iterator.next();
            String value=headers.get(key);
            httpPost.addHeader(key,value);
        }
        httpResponse=httpClient.execute(httpPost);
    }

    //以Json格式获取到反馈的主体
    public JSONObject getBodyInJSON() throws ParseException,IOException{
        HttpEntity responseBody= httpResponse.getEntity();
        String responseBodyString= EntityUtils.toString(responseBody);
        responseBodyJson=JSON.parseObject(responseBodyString);
        System.out.println("This is your response body" + responseBodyJson);
        return responseBodyJson;
    }

    //以哈希图的方式获取到响应头
    public HashMap<String,String> getHeaderInHash(){
        Header[] responseHeader=httpResponse.getAllHeaders();

        HashMap<String,String> hashMap=new HashMap<>();
        for(Header header:responseHeader){
            hashMap.put(header.getName(),header.getValue());
        }
        System.out.println("This is your response header" +hashMap);
        return hashMap;
    }

    //获取响应码
    public int getResponseCode(){
        responseCode=httpResponse.getStatusLine().getStatusCode();
        System.out.println("This is your response code" +responseCode);
        return responseCode;
    }
}

 5、在/src/main/java/utils下新建JSONPath类,获取响应中特定值,并判断是否与预期一致;

package com.test.utils;

import net.minidev.json.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;

public class JSONPath {
    public boolean isResponseCorrect(JSONObject jo,String checkPoint,String passValue){
        //用jsonpath处理json,获取result中特定键值
        ReadContext context= JsonPath.parse(jo);
        JSONArray result=context.read("$.data.."+checkPoint);
        String resultString=result.get(0).toString();
        if(resultString.equals(passValue)){
            return true;
        }
        else{
            return false;
        }
    }
}

6、在/src/main/java/utils下新增TestApi类,获取config.properties中配置的Excel及host地址,并将Excel和host地址设置为成员变量,后续通过测试类继承它的变量及方法;

package com.test.common;

import java.io.FileInputStream;
import java.util.Properties;

public class TestApi {
    public Properties prop;
    public String excelPath;
    public String host;

    //构造函数
    public TestApi(){
        try{
            prop=new Properties();
            //System.getProperty("user.dir"):获得工作目录(根目录)
            FileInputStream fis=new FileInputStream(System.getProperty("user.dir")+"/src/main/resources/config.properties");
            prop.load(fis);
        }catch (Exception e){
            e.printStackTrace();
        }

        host=prop.getProperty("Host");
        excelPath=prop.getProperty("testData");
    }
}

7、在/src/test/java下新建测试类TestPost,继承TestApi类;

package com.test.api;


import com.alibaba.fastjson.JSONObject;
import com.test.client.RestfuClient;
import com.test.common.TestApi;
import com.test.utils.ExcelProcess;
import com.test.utils.JSONPath;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.message.BasicNameValuePair;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class TestPost extends TestApi {
    RestfuClient client;
    JSONObject responseBody;
    int responseCode;
    String url;
    String postBody;
    Object[][] excelData;
    HashMap<String,String> hashHead;

    @BeforeTest
    public void setUp() throws ClientProtocolException, IOException {
        //读取用例Excel
        excelData= ExcelProcess.processExcel(excelPath,0);

        //实例化client
        client=new RestfuClient();

        //设置好请求头部
        hashHead=new HashMap<String,String>();
        hashHead.put("Content-Type","application/x-www-form-urlencoded");
    }

    @Test
    public void testPostRequest() throws ClientProtocolException, IOException{
        //从第二行开始遍历列表,跳过表头
        for(int i=1;i<excelData.length;i++){
            //从特定位置读取测试数据
            String address=excelData[i][3].toString();
            url=host+address;
            String checkPoint=excelData[i][4].toString();
            String checkValue=excelData[i][5].toString();
            //用NameValuePair存储所有请求参数
            List<NameValuePair> keys=new ArrayList<>();
            for(int j=7;j<excelData[i].length-2;j=j+2){
                //因为每个请求参数个数不一致,所以需要进行非空判断
                if(excelData[i][j]==null){
                    break;
                }
                NameValuePair pair=new BasicNameValuePair(excelData[i][j].toString(),excelData[i][j+1].toString());
                keys.add(pair);
            }

            //发送请求
            client.sendPost(url,keys,hashHead);

            responseBody=client.getBodyInJSON();
            responseCode=client.getResponseCode();

            JSONPath jPath=new JSONPath();
            boolean result= jPath.isResponseCorrect(responseBody,checkPoint,checkValue);

            //断言判断结果
            Assert.assertTrue(result,"失败1");
            Assert.assertEquals(responseCode,201,"失败2");

        }
    }
}

至此便完成了一次post的接口测试