首页 > 其他分享 >testng+HttpClient项目实战(一)

testng+HttpClient项目实战(一)

时间:2023-04-12 10:26:18浏览次数:56  
标签:实战 java testng org apache import com public HttpClient

参考文档:

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的接口测试

标签:实战,java,testng,org,apache,import,com,public,HttpClient
From: https://www.cnblogs.com/dhxdaodao/p/17306761.html

相关文章

  • (之前的项目复习)我的Java项目实战--校园餐饮商户外卖系统03
    开发笔记三分类管理业务开发公共字段自动填充问题分析前面我们已经完成了后台系统的员工管理功能开发,在新增员工时需要设置创建时间、创建人、修改时间、修改人等字段,在编辑员工时需要设置修改时间和修改人等字段。这些字段属于公共字段,也就是很多表中都有这些字段,如下:能......
  • 学习笔记396—自定义Docker镜像推送到Docker Hub实战
    自定义Docker镜像推送到DockerHub实战云原生探索的必经之路—容器化,而容器化目前最主流的技术莫过于Docker了,因为之前也大量的输出过Docker相关的技术博客,如果感兴趣的话可以直接访问专栏:​​《探索云原生》​​,按需学习哦。这篇文章还是从Docker入手,从0开始讲述下如何将自己的D......
  • ansible模块实战练习
    ansible模块实战练习Cloud研习社 Cloud研习社 2023-04-0110:55 发表于山东收录于合集#一站式教程220个#计算机185个#ansible22个#云计算196个#linux209个教程每周二、四、六更新今天我们练习一下ansible模块的用法,也算是一个小复习:准备三个节点:其中一个作......
  • 15.6二叉排序树删除实战
    #include<stdio.h>#include<stdlib.h>typedefintKeyType;typedefstructBSTNode{KeyTypekey;structBSTNode*lchild,*rchild;}BSTNode,*BiTree;//非递归的创建二叉查找数intBST_Insert(BiTree&T,KeyTypek){BiTreeTreeNew=(BiTree)cal......
  • 15.5二叉排序树原理及建树实战
    #include<stdio.h>#include<stdlib.h>typedefintKeyType;typedefstructBSTNode{KeyTypekey;structBSTNode*lchild,*rchild;}BSTNode,*BiTree;//非递归的创建二叉查找数intBST_Insert(BiTree&T,KeyTypek){BiTreeTreeNew=(BiTree)cal......
  • 程序员下班做什么副业好?实战方法新手小白可上手!1000多字总结
    以前我就是个程序员,所以,现在有做副业的想法是很不错的,可以多点收入,而且以下方法即使不是程序员,新手小白也可以干。我来分享一下做副业的经验和看法;现在我已经往运营方向发展了。作为一个网站开发工程师,我在上家公司干了3年的活,做过javaweb,前端html、js、css,asp.net we......
  • 前端工程化实战:React 的模块化开发、性能优化和组件化实践
    前端工程化实战是指通过组织工作流程、使用工具和技术来提高前端开发效率和质量的一种方法。常见的前端工程化实践包括模块化开发、自动化构建、代码检查和测试、性能优化等。下面将简要介绍模块化开发、性能优化和组件化实践。模块化开发在React中实现模块化开发的方式有两种:Com......
  • Linux的3种特殊权限场景实战:SUID、SGID、SBIT
    3种特殊权限在Linux系统中,有3种特殊权限,它们分别是Setuid(SUID)、Setgid(SGID)和StickyBit。Setuid权限:通过Setuid权限,普通用户可以在执行某些特定程序时,拥有与程序所有者相同的权限。也就是说,该程序在执行时,会自动获取其所有者的权限,而不是执行者的权限。这通常用于一些需要r......
  • 15.4折半查找原理及实战
    #include<stdio.h>#include<stdlib.h>#include<time.h>typedefintElemType;typedefstruct{ElemType*elem;//整型指针intTableLen;//存储动态数组里边元素的个数}SSTable;//init进行了随机数生成,折半查找没有使用哨兵voidST_Init(SSTable&ST,i......
  • 15.3顺序查找及实战
    #include<stdio.h>#include<stdlib.h>#include<time.h>typedefintElemType;typedefstruct{ElemType*elem;//整型指针,申请的堆空间的起始地址存入elemintTableLen;//存储动态数组里边元素的个数}SSTable;voidST_Init(SSTable&ST,intlen){//......