服務端的測試,大多數內容都圍繞着接口展開。對於接口測試,無非也是功能、自動化、性能測試爲主,偶然想到一個問題,若是能寫一個用例,在功能、自動化、性能三者的測試場景中重複使用,確定能省去很是多的時間。java
整體思路跟以前的接口和性能框架同樣,經過總的測試項目中把接口功能封裝好,留出來測試參數。功能測試就寫方法調用而後人肉檢查,自動化的話把接口響應拿出來,而後驗證各類數據,性能直接使用性能框架直接調用該方法便可。mysql
花了點時間,作了一個Demo,分享給你們。git
這是一個簡易的接口請求方法,其中main方法裏面是功能測試執行代碼,用例是文檔形式,這裏就不寫了:redis
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方法裏面是調試用例的過程,執行用例的方法在以前的文章寫過,利用反射去記錄用例信息和執行測試用例,並保存測試結果,輸出測試報告,異常預警等等:sql
/** * 用戶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請求:json
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
來運行。瀏覽器