如何统一接口测试的功能、自动化和性能测试用例

news2024/11/25 7:01:13

服务端的测试,大多数内容都围绕着接口展开。对于接口测试,无非也是功能、自动化、性能测试为主,偶然想到一个问题,如果能写一个用例,在功能、自动化、性能三者的测试场景中重复使用,肯定能省去非常多的时间。

总体思路跟之前的接口和性能框架一样,通过总的测试项目中把接口功能封装好,留出来测试参数。功能测试就写方法调用然后人肉检查,自动化的话把接口响应拿出来,然后验证各种数据,性能直接使用性能框架直接调用该方法即可。

花了点时间,做了一个Demo,分享给大家。

这是一个简易的接口请求方法,其中main方法里面是功能测试执行代码,用例是文档形式,这里就不写了:



public class Headgear extends NajmBase {




    public Headgear(NajmBase najmBase) {
        this.loginKey = najmBase.loginKey;
        this.args = najmBase.args;
        this.user_id = najmBase.user_id;
    }


    private static NajmBase base = NajmBase.getBase(0);


    public static Headgear drive = new Headgear(base);




    /**
     * 当前正在使用的头套
     */


    public int usingHeadgearId;


    //	public JSONObject headgearInfo = new JSONObject();
    public Map<Integer, Long> headgearInfo = new HashMap<>();


    public static void main(String[] args) {
//		NajmBase.getUserBalance(base.user_id);
//		int type = 1, id = 36, packageId = 60, num = 1, price = 1;
//		NajmBase base1 = new NajmBase(V580User.getUserName(0));
//		Headgear headgear = new Headgear();
//		headgear.switchHeadgear(34);
//		output(headgear.getHeadgearInfo());
//		output(headgear.getUsingHeadgearId());
//		output(base1.loginResponse);
//		drive.getAllHeadgear();
//		new MallBase(base).buy(type, id, packageId, num, price);
//		drive.getUserHeadgearInfo();
//		NajmBase.getUserBalance(base.user_id);
//		drive.getUserHeadgearInfo();
//		drive.getOnsaleHeadgear();
        int times = 0;
        while (true) {
            times++;
            int type = 1, id = getRandomInt(2) == 1 ? 34 : 36, packageId = id == 34 ? 56 : 60, num = 1, price = 1;
            long deadtime1 = drive.getHeadgearInfo().get(id);
            Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, num, price));
            drive.getUserHeadgearInfo();
            long deadtime2 = drive.getHeadgearInfo().get(id);
            if (deadtime2 - deadtime1 != DAY) break;
        }
        output("一共进行了:" + times);
//		output(drive.getHeadgearInfo());
//		output(drive.usingHeadgear);
//		output(drive.loginKey);
//		output(drive.args);
//		output(base.loginResponse.getJSONObject(DATAINFO).getJSONObject("headGear").getInt("id"));
        testOver();
    }


    /**
     * 获取所有头套信息,包括下架的
     *
     * @return
     */
    public JSONObject getAllHeadgear() {
        String url = HOST + HeadgearApiPath.GET_ALL_HEADGEAR;
        HttpGet httpGet = getHttpGet(url);
        JSONObject response = getHttpResponseEntityByJson(httpGet);
        output(response);
        return response;
    }


    /**
     * 用户切换头套接口
     *
     * @param hid
     * @return
     */
    public JSONObject switchHeadgear(int hid) {
        String url = HOST + HeadgearApiPath.SWITCH_HEADGEAR + hid + changeJsonToArguments(args);
        HttpPost httpPost = getHttpPost(url);
        JSONObject response = getHttpResponseEntityByJson(httpPost);
//		output(response);
        return response;
    }


    /**
     * 获取用户头套信息
     *
     * @return
     */
    public JSONObject getUserHeadgearInfo() {
        sleep(1);
        String url = HOST + HeadgearApiPath.GET_USER_HEADGEAR;
        JSONObject response = getHttpResponseEntityByJson(getHttpGet(url, args));
        output(response);
        if (isRightResponse(response)) {
            headgearInfo.clear();
            JSONArray jsonArray = response.getJSONArray(DATAINFO);
            jsonArray.forEach(json -> {
                    JSONObject jsonObject = JSONObject.fromObject(json.toString()) ;
                    String name = jsonObject.getString("name") ;
                    long deadTime = jsonObject.getLong("deadlineTime") ;
                    int headgearId = jsonObject.getInt("goodId") ;
                    int use = jsonObject.getInt("isUse") ;
            if (use == 1) usingHeadgearId = headgearId;
            headgearInfo.put(headgearId, deadTime);
            output(name, headgearId, getTimeByTimestamp(deadTime));
        } );
        }
        return response;
    }


    /**
     * 获取在售的头套的列表
     *
     * @return
     */
    public JSONObject getOnsaleHeadgear() {
        String url = HOST + HeadgearApiPath.GET_ONSALE_HEADGEAR;
        JSONObject response = getHttpResponseEntityByJson(getHttpGet(url, args));
        output(response);
        return response;
    }


    public int getUsingHeadgearId() {
        getUserHeadgearInfo();
        return usingHeadgearId;
    }


    public Map<Integer, Long> getHeadgearInfo() {
        getUserHeadgearInfo();
        return headgearInfo;
    }


}

下面是基于该功能的自动化测试用例,main方法里面是调试用例的过程,执行用例的方法在之前的文章写过,利用反射去记录用例信息和执行测试用例,并保存测试结果,输出测试报告,异常预警等等:

/**
 * 用户0-10
 */
public class HeadgearCase extends SourceCode {
	static HeadgearCase headgearCase = new HeadgearCase();
	static NajmBase base = new NajmBase(V580User.getUserName(0));
	static Headgear drive = new Headgear(base);


	public static void main(String[] args) {
//		headgearCase.testDemo001();
//		headgearCase.testDemo002();
//		headgearCase.testDemo003();
//		headgearCase.testDemo004();
		headgearCase.testDemo005();
//		headgearCase.testDemo006();
		ApiLibrary.testOver();
	}


	/**
	 * 获取所有头套信息用例
	 */
	public void testDemo001() {
		String label = "获取所有头套信息用例" + TAB + Thread.currentThread().getStackTrace()[1];
		Verify verify = new Verify(drive.getAllHeadgear());
		JSONObject result = new JSONObject();
		result.put("状态码为0", verify.isRight());
		result.put("包含数组", verify.isArray("heads"));
		result.put("包含已下架的头套", verify.isContains("自动化专用3"));
		result.put("包含正在出售的头套", verify.isContains("自动化专用1"));
		MySqlTest.saveTestResult(label, result);
	}


	/**
	 * 获取在售的头套用例
	 */
	public void testDemo002() {
		String label = "获取在售的头套用例" + TAB + Thread.currentThread().getStackTrace()[1];
		Verify verify = new Verify(drive.getOnsaleHeadgear());
		JSONObject result = new JSONObject();
		result.put("状态码为0", verify.isRight());
		result.put("包含数组", verify.isArray("dataInfo"));
		result.put("不包含已下架的头套", !verify.isContains("自动化专用3"));
		result.put("包含正在出售的头套", verify.isContains("自动化专用1"));
		result.put("包含描述信息", verify.isContains("测试10天"));
		MySqlTest.saveTestResult(label, result);
	}


	/**
	 * 获取用户头套信息用例
	 */
	public void testDemo003() {
		String label = "获取用户头套信息用例" + TAB + Thread.currentThread().getStackTrace()[1];
		Verify verify = new Verify(drive.getUserHeadgearInfo());
		JSONObject result = new JSONObject();
		result.put("状态码为0", verify.isRight());
		result.put("用户头套正常", verify.isContains("自动化专用1"));
		result.put("用户佩戴正常", verify.isContains("\"isUse\":1"));
		result.put("头套套餐正常", verify.isContains("测试1天"));
		MySqlTest.saveTestResult(label, result);
	}


	/**
	 * 余额不足购买用例
	 */
	public void testDemo004() {
		String label = "余额不足购买用例" + TAB + Thread.currentThread().getStackTrace()[1];
		NajmBase base = new NajmBase(V580User.getUserName(1));
		int type = 1, id = 36, packageId = 60, num = 1, price = 1;
		Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, num, price));
		JSONObject result = new JSONObject();
		result.put("状态码为35", 35 == verify.getCode());
		MySqlTest.saveTestResult(label, result);
	}


	/**
	 * 正常购买用例
	 */
	public void testDemo005() {
		String label = "正常购买用例" + TAB + Thread.currentThread().getStackTrace()[1];
		int type = 1, id = getRandomInt(2) == 1 ? 34 : 36, packageId = id == 34 ? 56 : 60, num = 1, price = 1;
		int balance = NajmBase.getUserBalance(drive.user_id);
		long deadtime1 = drive.getHeadgearInfo().get(id);
		Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, num, price));
		drive.getUserHeadgearInfo();
		long deadtime2 = drive.getHeadgearInfo().get(id);
		int balance1 = NajmBase.getUserBalance(drive.user_id);
		JSONObject result = new JSONObject();
		result.put("状态码为0", verify.isRight());
		result.put("截止日期正确", (deadtime2 + EMPTY).equals(verify.getValue("deadlineTime")));
		result.put("头套日期增加正常", deadtime2 - deadtime1 == DAY);
		result.put("用户余额减少正常", balance - balance1 == 1);
		MySqlTest.saveTestResult(label, result);
	}


	/**
	 * 用户切换头套用例
	 */
	public void testDemo006() {
		String label = "用户切换头套用例" + TAB + Thread.currentThread().getStackTrace()[1];
		drive.getAllHeadgear();
		int id1 = drive.getUsingHeadgearId() == 34 ? 36 : 34;
		Verify verify = new Verify(drive.switchHeadgear(id1));
		int id2 = drive.getUsingHeadgearId();
		JSONObject result = new JSONObject();
		result.put("状态码为0", verify.isRight());
		result.put("头套切换成功", id1 == id2);
		MySqlTest.saveTestResult(label, result);
	}
}

下面是一个针对其中某个功能的性能测试用例(测试用例分两种,一类是HTTP单次请求的,我才用了获取请求的HttpRequestBase对象然后去重新发送并发请求,一类是多接口或者非HTTP请求,如dubbo,mysql,redis,消息队列等等,直接调用的方法进行压测):

简单HTTP请求:

class CancelReason extends OkayBase{


    public static void main(String[] args) {
        def argsUtil = new ArgsUtil(args)
        def thread = argsUtil.getIntOrdefault(0, 2)
        def times = argsUtil.getIntOrdefault(1, 5)


        def base = getBase()
        
        Headgear drive = new Headgear(base);
        drive.getAllHeadgear()
        def request = FanLibrary.getLastRequest()


        def timesthread = new RequestThreadTimes(request, times)
        new Concurrent(timesthread, thread,"获取所有头套,内容流转二期压测接口").start()


        allOver()
    }
}

非简单HTTP请求的请参考之前写过的性能测试框架Demo:性能测试框架第二版。这类方法写起来比较简单,使用范围很高,但是需要根据不同的业务需求解决多线程数据和对象的安全问题。

整个项目放在git上,功能测试在本地,自动化项目和性能项目在服务器,采用Groovy脚本运行,也可以在本地调试。自动化项目采取定时或者间隔固定时间自动运行,性能项目收到输入命令groovy filename.groovy来运行。

 总结:

感谢每一个认真阅读我文章的人!!!

我个人整理了我这几年软件测试生涯整理的一些技术资料,包含:电子书,简历模块,各种工作模板,面试宝典,自学项目等。欢迎大家点击下方名片免费领取,千万不要错过哦。

   Python自动化测试学习交流群:全套自动化测试面试简历学习资料获取点击链接加入群聊【python自动化测试交流】:http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DhOSZDNS-qzT5QKbFQMsfJ7DsrFfKpOF&authKey=eBt%2BF%2FBK81lVLcsLKaFqnvDAVA8IdNsGC7J0YV73w8V%2FJpdbby66r7vJ1rsPIifg&noverify=0&group_code=198408628

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/716383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

webpack相关面试题

webpack面试题 1.webpack和vite区别2.如何优化webpack打包速度&#xff1f;3.说说webpack中常见的Plugin&#xff1f;解决了什么问题4.说说如何借助webpack来优化前端性能&#xff1f;如何优化JS代码压缩CSS代码压缩Html文件代码压缩文件大小压缩图片压缩Tree ShakingusedExpor…

中小企业的数字化热情,从未像今年618这样滚烫

一年一度的618大促告一段落&#xff0c;我们可以总结一个趋势&#xff1a;C端消费者对大促的热情在消退&#xff0c;而B端企业&#xff0c;尤其是中小企业&#xff0c;对大促的热情则以肉眼可见的速度提升。 普通消费者也好&#xff0c;广大中小企业也罢&#xff0c;参与大促的…

SSMP整合案例(11) 在界面中实现添加操作

上文 SSMP整合案例(10) vue端调整项目环境 发送请求 基本界面编写我们搭建了基本的页面结构 然后 我们来做个新增的功能 首先 新增 我们肯定是用户点击了这个新建之后 我们再来处理这个逻辑 我们之前的代码 新增是有绑定 一个事件的 但是这个 AddBook中并没有内容 首先 我们…

想要经营好抖音小店,你还需要了解这些活动方法

抖音小店作为抖音上的新零售业务形态&#xff0c;旨在为用户提供更加便捷的购物体验&#xff0c;同时也为商家提供了一个新的销售渠道。在使用抖音小店的过程中&#xff0c;有一些主流的玩法&#xff0c;今天不若与众科技就来介绍一下。 1. 抖音小店开通直播带货服务 开通直播…

PowerToys工具介绍及使用

目录 介绍下载使用和功能介绍1.安装后的效果2.始终置顶3.唤醒4.颜色选择器5.FancyZones 窗口分屏器6.File Locksmith7.文件资源管理器加载项8.Host文件编辑器9.图像大小调整器10.键盘管理器11.速览12.PowerRename13.文本提取器 介绍 PowerToys 是微软最初发布于 Windows 95 平…

计算机毕业论文选题推荐|软件工程|小程序系列选题

文章目录 导文题目导文 计算机毕业论文选题推荐|软件工程 (***语言)==使用其他任何编程语言 例如:基于(***语言)门窗账务管理系统的设计与实现 得到:基于JAVA门窗账务管理系统的设计与实现 基于vue门窗账务管理系统的设计与实现 等等 题目 基于微信小程序和深度学习的宠物…

Minio设置文件链接永久有效的完整步骤

目录 前言1.下载MinIO Client2.运行MinIO Client3.添加一个云存储服务4.验证5.policy命令 - 管理存储桶策略总结 前言 minio分享文件的链接&#xff0c;最多支持分享七天 通过 MinIO客户端 管理存储桶策略的方式实现文件链接永久有效 1.下载MinIO Client 采用 Docker 方式 …

拓展销售渠道是客户管理系统的重要功能

随着市场竞争的加剧&#xff0c;人们对于未来的期望和追求越来越高。科技的飞速发展和全球化的趋势&#xff0c;使得我们的生活方式和工作方式都发生了翻天覆地的变化。企业需要不断拓展销售渠道&#xff0c;以吸引更多的客户和提高销售额。客户管理系统&#xff08;CRM&#x…

性能测试岗位常见面试题及答案,希望可以帮到你

目录 前言 一、基础篇 二、工具篇 三、系统架构篇 四、服务器&中间件篇 五、数据库篇 七、案例篇 总结&#xff1a; 前言 最近有童鞋找我问一些性能测试相关的问题&#xff0c;其中问的次数最多的&#xff0c;还是面试性能测试岗位&#xff0c;一般会问哪些问题&am…

Nacos架构与原理 -服务网格生态

文章目录 背景什么是服务网格单体架构向微服务体系架构的演进服务发现负载均衡熔断限流可观测 &#xff08;监控告警&#xff09;认证鉴权其他....小结 微服务体系架构的传统解决方案下⼀代微服务架构——服务网格 服务网格明星产品 Istio什么是 IstioEnvoyEnvoy 和 Istio Isti…

将Python的py文件打包成exe可执行文件

安装依赖包&#xff1a;pip install Pyinstaller pip install Pyinstaller 切换你要打包程序的路径 打开路径文件夹&#xff0c;在路径输入cmd即可 3.执行命令 pip install Pyinstaller 会在当前的py文件夹下生成一个dist文件&#xff0c;里面有一个exe文件

【java面试题】java那些经典的面试题,你还记得吗,少年加油,java八股文

java八股文&#xff0c;你能答对95%以上吗&#xff1f;少年 还有更多文档&#xff1a; 需要给我留言&#xff0c;我发给你。 java八股文&#xff0c;你能答对95%以上吗&#xff1f;少年 感恩于心&#xff0c;回报于行。 面试宝典系列-Java 第一章 内容介绍 ...................…

7.5 内存交换空间(swap)之创建

安装时一定需要的两个 partition &#xff0c;一个是根目录&#xff0c;另外一个就是 swap&#xff08;内存交换空间&#xff09;。 一般来说&#xff0c;如果硬件的配备资源足够的话&#xff0c;那么 swap 应该不会被我们的系统所使用到&#xff0c;swap 会被利用到的时刻通常…

const函数和assert函数:提高代码质量的利器

前言 在C中&#xff0c;const函数和assert函数是非常重要的概念。它们可以帮助我们确保代码的正确性和可靠性。那么在本期&#xff0c;我们将深入探讨这两个概念的作用和用法 目录 前言 一、如何写出优秀的代码&#xff1f; 二、assert 三、const const左修饰&#xff1a;…

halcon实现对点云的平移、旋转、线性运动等动画效果操作

一、点云从点A沿直线运动至B点 过程为&#xff1a; 1、读取点云 本例子用凸包算子convex_hull_object_model_3d生成点云&#xff0c;这个步骤可以换成自己的&#xff0c;直接读取点云即可。 2、设置旋转的角度 3、对点云进行转化 4、显示 5、带动画效果的移动代码 dev_…

3D机器视觉市场现状及未来发展趋势

原创 | 文 BFT机器人 当前&#xff0c;3D机器视觉市场正在经历快速发展阶段。多年来&#xff0c;该技术的应用领域也在不断扩大&#xff0c;特别是在工业制造和安防监控等多个领域具有广泛应用。这一持续发展得益于行业技术的不断进步。 3D机器视觉是指利用计算机视觉技术实现对…

关于开源项目 Tinywebserver的使用与配置fatal error: mysql.h: No such file or directory

Tinywebserver的配置和使用可以先看这篇文章配置 但是编译如果报错&#xff1a;fatal error: mysql.h: No such file or directory 文中提示是apt-get install libmysqlclient-dev 如果你执行了上面这条指令后还是编译报出同样错&#xff0c;请继续往下看。 根据提示是没找到m…

广东省21个地市谷歌卫星影像公开下载

广东省21个地市离线谷歌卫星影像数据资源&#xff08;mbt格式&#xff09;&#xff0c;精度在18级0.5米左右分辨率&#xff0c;网盘下载链接&#xff1a;https://pan.baidu.com/s/1gsRNvz_Q1sPooCDdZMqpAw?pwd6666 提取码&#xff1a;6666

基于Zstack协议栈的智慧农业

界面演示 实物演示 包含两个终端节点以及一个协调器&#xff0c;协调器与上位机通过串口线连接&#xff0c;协调器与终端节点树形组网 硬件 cc2530 DHT11 超声波传感器 MQ-2 LED 三极管 直流电机 软件 Qt IAR Sqlyug Mysql 项目架构 智慧农业系统分为上位机和下位机&…

nvm安装后出现node不是内部或外部命令,也不是可运行的程序

nvm作为node管理工具可以在前端开发时&#xff0c;在本地安装多个node版本从来适应不同的工程代码&#xff0c;是比较推荐使用的&#xff01;&#xff01; 注意&#xff1a;在安装使用nvm时&#xff0c;需确保本地没有安装任意版本的nodejs&#xff08;防止环境路径覆盖&#x…