【Jmeter測試】使用Java請求進行Dubbo介面的測試
阿新 • • 發佈:2019-02-13
- 使用json檔案來構造測試資料
- java程式只對json檔案進行解析
- 介面呼叫成功後,用json檔案中的期望資料來對介面返回資料進行比對,判斷呼叫是否成功
json檔案的定義
{ "Connection": { "URL": "101.219.255.73:50883", "SERVICE_NAME": "com.company.mdapi.sdk.material.export.MaterialApiService", "VERSION": "1.0.0", "METHOD": "queryUnboundListByPage", "HELPCLASS": "com.utils.common.helper.MaterialApiService.QueryUnboundListByPageHelper" }, "Random": false, "Args": { "sourceSystem": 2, "querySourceSystem": null, "materialCode": "MD_S6006", "materialName": null, "materialType": null, "pkId": null, "shipperCode": "ZA01", "storageCenterCode": "HZA1", "pager": { "page": 1, "rows": 5, "totalCount": null, "pageOffset": null, "sort": "ID", "order": "ASC", "totalPage": null, "pageCode": 7, "startPageIndex": null, "endPageIndex": null, "previewPage": null, "nextPage": null } }, "Verify": false }
引數具體定義:
- Connection:Dubbo服務的地址URL、服務名稱SERVICE_NAME、版本號VERSION、遠端介面呼叫的方法METHOD、
資料轉化處理的輔助類HELPCLASS。 - Random:用來是能隨機數設定,壓力測試類似Add資料庫操作時可以繞過資料庫預設好的唯一性校驗。
- Args:呼叫介面時,傳入的引數,這裡提供的引數需要在輔助類中轉換成介面引數,然後呼叫介面。
- Verify:保留值,暫無使用
Java程式實現資料轉換及介面呼叫
- 輔助的Help類,需要繼承SampleHelper類,同時實現其中的兩個抽象方法readJsonFile和callRemoteMethod,
分別用來讀取json配置檔案和呼叫遠端方法(實際測試人員只需要實現這兩個方法就可以進行Dubbo介面測試)。
public class AddMaterialListHelper extends SampleHelper<Result<List<FailData>>> { public static final String[] RANDOM_FIELD = {"materialCode","materialName"}; @Override public Map<String, Object> readJsonFile(String jsonPath) { JsonParser parser = new JsonParser(); try { JsonObject json=(JsonObject) parser.parse(new FileReader(jsonPath)); Map<String, Object> values = new HashMap<String, Object>(); UtilsHelper.getInstance().getConnectionArgument(values, json); JsonObject args=json.get("Args").getAsJsonObject(); if (!args.get("data").isJsonNull()) { String jsonArray = args.get("data").getAsJsonArray().toString(); //TODO Gson gson = new Gson(); @SuppressWarnings("serial") List<MaterialInterfaceDTO> dtoList = gson.fromJson(jsonArray, new TypeToken<List<MaterialInterfaceDTO>>() { }.getType()); RandomNum.setRandom(json , RANDOM_FIELD , dtoList); values.put("data", dtoList); } if (!args.get("sourceSystem").isJsonNull()) { values.put("sourceSystem", new Integer(args.get("sourceSystem").getAsInt())); } return values; } catch (JsonIOException e) { e.printStackTrace(); } catch (JsonSyntaxException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } @Override public Result<List<FailData>> callRemoteMethod(Object object, Map<String, Object> values) { MaterialInterfaceService service = (MaterialInterfaceService) object; @SuppressWarnings("unchecked") Result<List<FailData>> callResult = service.addMaterialList ( (int) values.get("sourceSystem"), (List<MaterialInterfaceDTO>) values.get("data")); return callResult; } }
- 這裡有個注意點,由於個博主所在的團隊把介面引數封裝成了一個可序列化的class類,所以需要進行資料轉化,有些公司的
介面引數直接傳json字串,那麼只需要把json轉換為字串進行傳參就可以。
引數封裝為序列化的class類:public class MaterialInterfaceDTO implements Serializable { private static final long serialVersionUID = -3725469669741557392L; private String materialCode; private String materialName; private Integer materialType; private Integer importFlag; private String sixNineCode; private Long expirationDate; private Long packingSpecification; private String basicUnit; private String minSaleUnit; private String basicUnitName; private String minSaleUnitName; private String materialImageUrl; private Integer transportFlag; private Integer sourceSystem; private String createName; private String updaterName; public MaterialInterfaceDTO() { } public String getMaterialCode() { return this.materialCode; } public void setMaterialCode(String materialCode) { this.materialCode = materialCode; } public String getMaterialName() { return this.materialName; } public void setMaterialName(String materialName) { this.materialName = materialName; } public Integer getMaterialType() { return this.materialType; }
- 在init中通過java反射機制,獲取json配置檔案中設定好的輔助類的物件,然後在runTest中呼叫對應輔助類中
callRemoteMethod,返回的結果解析後放到SampleResult的responeData,用來在jmeter中使用後置處理器進行
結果判斷。package com.utils.common; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ReferenceConfig; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient; import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; import org.apache.jmeter.samplers.SampleResult; import java.util.Map; public class RunMethodTest extends AbstractJavaSamplerClient { private static String JMX_PATH = null; private static String TAG = Thread.currentThread().getStackTrace()[1].getClassName(); private SampleHelper helper = null; private Map<String, Object> values = null; private Map<String, Object> config = UtilsHelper.getInstance().getConfigProperties(); private String ARGS_FILE; private Object object; public void setupTest(){ //定義測試初始值,setupTest只在測試開始前使用 System.out.println("setupTest"); } public void init() { // 當前應用配置 ApplicationConfig application = new ApplicationConfig(); application.setName(TAG); // 獲取具體引數配置路徑 if ("true".equals(config.get("DEBUG").toString())) { JMX_PATH = ARGS_FILE; } else { JMX_PATH = UtilsHelper.getInstance().getScriptPath(config.get("SCRIPT_HOME").toString(), ARGS_FILE); } Map<String, Object> helpArgs = UtilsHelper.getInstance().getHelpClassAndMethod(JMX_PATH); helper = (SampleHelper)UtilsHelper.getInstance().invokeStaticMethodByReflect( (String) helpArgs.get("HELPCLASS"), (String) helpArgs.get("HELPMETHOD") ) ; values = helper.readJsonFile(JMX_PATH); // 注意:ReferenceConfig為重物件,內部封裝了與註冊中心的連線,以及與服務提供方的連線 // 引用遠端服務,配置dubbo服務版本、服務名稱、url地址 ReferenceConfig reference = new ReferenceConfig(); // 此例項很重,封裝了與註冊中心的連線以及與提供者的連線,請自行快取,否則可能造成記憶體和連線洩漏 reference.setApplication(application); reference.setTimeout(20000); reference.setVersion(values.get("conn_version").toString()); reference.setInterface(values.get("conn_service_name").toString()); reference.setUrl(values.get("conn_url").toString()); // 和本地bean一樣使用xxxService object = reference.get(); // 注意:此代理物件內部封裝了所有通訊細節,物件較重,請快取複用\ } public SampleResult runTest(JavaSamplerContext arg0) { SampleResult sr = new SampleResult(); ; try { //獲取引數 ARGS_FILE = arg0.getParameter("ARGS_FILE"); //dubbo初始化 init(); //jmeter結果物件 // sr.setSampleLabel(TAG); sr.sampleStart(); sr.setSuccessful(true); String res = helper.handleResult(helper.callRemoteMethod(object, values)); sr.sampleEnd(); // jmeter 結束統計響應時間標記 if (res != null) { JsonObject response = new JsonParser().parse(res).getAsJsonObject(); System.out.println("\n*************測試返回值****************\n"); System.out.print(response.toString()+"\n"); if (response.get("code").getAsInt() != 0) { sr.setSuccessful(false); } sr.setResponseData(response.toString(), "UTF-8"); // if (null != response.get("data")) { // sr.setResponseData(response.get("data").toString(), "UTF-8"); // System.out.print(response.get("data").toString()+"\n"); // } else if (null != response.get("result")) { // sr.setResponseData( response.get("result").toString(), "UTF-8"); // } } else { System.out.print("handleResult return null\n"); } } catch (Exception e) { e.printStackTrace(); sr.setResponseCode("999"); sr.setResponseMessage(e.getMessage()); sr.setSuccessful(false); } return sr; } public Arguments getDefaultParameters(){ //引數定義,顯示在前臺,也可以不定義 Arguments params = new Arguments(); params.addArgument("ARGS_FILE", ""); return params; } public void teardownTest(JavaSamplerContext arg0){ super.teardownTest(arg0); } }