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”,禁止第三方(腾讯云除外)转载、发表。

    技术类文章精选

    非技术文章精选

  • 相关阅读:
    Oracle SQL语句大全—查看表空间
    Class to disable copy and assign constructor
    在moss上自己总结了点小经验。。高手可以飘过 转贴
    在MOSS中直接嵌入ASP.NET Page zt
    Project Web Access 2007自定义FORM验证登录实现 zt
    SharePoint Portal Server 2003 中的单一登录 zt
    vs2008 开发 MOSS 顺序工作流
    VS2008开发MOSS工作流几个需要注意的地方
    向MOSS页面中添加服务器端代码的另外一种方式 zt
    状态机工作流的 SpecialPermissions
  • 原文地址:https://www.cnblogs.com/FunTester/p/12151542.html
Copyright © 2011-2022 走看看