zoukankan      html  css  js  c++  java
  • 如何统一接口测试的功能、自动化和性能测试用例

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

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

    花了点时间,做了一个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来运行。


    • 郑重声明:文章首发于公众号“FunTester”,禁止第三方(腾讯云除外)转载、发表。

    技术类文章精选

    非技术文章精选

  • 相关阅读:
    Canvas与Image互相转换示例以及利用该技术实现微信长按自动识别二维码功能
    chrome浏览器无法安装非应用商店插件的解决办法
    用canvas绘制android机器人
    TortoiseGit保存用户名和密码的方法
    event对象的兼容性
    利用jQuery无缝滚动插件liMarquee实现图片(链接)和文字(链接)向右无缝滚动(兼容ie7+)
    jQuery动画的hover连续触发动画bug处理
    用jquery实现平滑的页面滚动效果
    实现段落文字两端对齐的css样式
    前端构建工具gulpjs的使用介绍及技巧(转)
  • 原文地址:https://www.cnblogs.com/FunTester/p/12151542.html
Copyright © 2011-2022 走看看