在以前的博文中,Jmeter二次開發——基於Java請求,已介紹了Jmeter二次開發的基礎狀況,上次分享的是java請求開發,今天來分享下Jmeter中的函數開發。聊到Jmeter的函數,知道Jmeter使用的博友確定很熟悉。Jmeter自帶一個函數庫,有不少的函數,好比:__P,__Random,函數助手給咱們提供了不少的方便之處。函數助手使用以下所示:
html
但有些時候,自帶的函數知足不了真實的測試場景,好比:生成隨機手機號。常規作法,應該是設定手機號區號的固定值,再經過__Random函數生成8位隨機數,從而拼接成一個手機號,這樣的作法的確能夠知足,但要想手機號的區段也是隨機的呢,是否是就不太好處理了。那就用函數二次開發試試。java
這個是特別須要注意點,以.functions結尾,正常建立包便可。dom
二次開發時,新建的類,須要繼承AbstractFunction,這個也是須要注意的。至於爲何須要繼承AbstractFunction,看源碼就能明白,源碼以下所示:ide
public abstract class AbstractFunction implements Function { public AbstractFunction() { } public abstract String execute(SampleResult var1, Sampler var2) throws InvalidVariableException; public String execute() throws InvalidVariableException { JMeterContext context = JMeterContextService.getContext(); SampleResult previousResult = context.getPreviousResult(); Sampler currentSampler = context.getCurrentSampler(); return this.execute(previousResult, currentSampler); } public abstract void setParameters(Collection<CompoundVariable> var1) throws InvalidVariableException; public abstract String getReferenceKey(); protected JMeterVariables getVariables() { return JMeterContextService.getContext().getVariables(); } protected void checkParameterCount(Collection<CompoundVariable> parameters, int min, int max) throws InvalidVariableException { int num = parameters.size(); if (num > max || num < min) { throw new InvalidVariableException(this.getReferenceKey() + " called with wrong number of parameters. Actual: " + num + (min == max ? ". Expected: " + min + "." : ". Expected: >= " + min + " and <= " + max)); } } protected void checkParameterCount(Collection<CompoundVariable> parameters, int count) throws InvalidVariableException { int num = parameters.size(); if (num != count) { throw new InvalidVariableException(this.getReferenceKey() + " called with wrong number of parameters. Actual: " + num + ". Expected: " + count + "."); } } protected void checkMinParameterCount(Collection<CompoundVariable> parameters, int minimum) throws InvalidVariableException { int num = parameters.size(); if (num < minimum) { throw new InvalidVariableException(this.getReferenceKey() + " called with wrong number of parameters. Actual: " + num + ". Expected at least: " + minimum + "."); } } protected final void addVariableValue(String value, CompoundVariable[] values, int index) { if (values.length > index) { String variableName = values[index].execute().trim(); if (StringUtils.isNotEmpty(variableName)) { JMeterVariables vars = this.getVariables(); if (vars != null) { vars.put(variableName, value); } } } } }
獲取界面所要顯示的參數說明函數
函數的主體業務測試
獲取函數的名稱this
設置參數,接收用戶傳遞的參數線程
檢測參數數量是否準確3d
名稱自定義,以下所示:調試
private static final String key = "__XXX";
這裏須要注意的是:函數開頭是以2個下劃線開頭。
名稱定義好了,那如何獲取呢?就用咱們剛纔說的方法獲取便可,以下所示:
@Override public String getReferenceKey() { return key; }
在Jmeter的函數助手中,對應函數都有對應的參數說明,以下所示:
那如何配置能實現呢?代碼以下:
private final static List<String> args = new LinkedList<String>(); static{ args.add("界面參數"); }
若是有多個參數怎麼辦?多個參數,多個args.add便可
獲取參數名稱,一樣用剛纔介紹的方法獲取便可,以下所示:
@Override public List<String> getArgumentDesc() { return args; }
@Override public void setParameters(Collection<CompoundVariable> args0) throws InvalidVariableException { //檢測用戶調用函數時,檢查參數個數,個數不對則報錯 checkParameterCount(args0,3); Object[] params = args0.toArray(); //轉換隻爲string telNum = ((CompoundVariable)params[0]).execute(); start = ((CompoundVariable)params[1]).execute(); end = ((CompoundVariable)params[2]).execute(); }
獲取參數值中,能夠檢測函數的入參個數是否準確,不許確則會報錯,報錯信息以下所示:
介紹到這,就是函數的核心內容了,該函數要實現什麼功能,就是在該方法中處理,示例代碼以下所示:
@Override public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException { SampleResult sampleResult1 = new SampleResult(); try { sampleResult1.sampleStart(); int index=getNum(0,telFirst.length-1); String telNum = telFirst[index]; String two = String.valueOf(getNum(1, 888) + 10000).substring(1); String three = String.valueOf(getNum(1, 9100) + 10000).substring(1); tel = telNum + two + three; logger.info("手機號區段:"+ telNum +" 隨機生成的手機號是:" + tel); if (varName != null) { JMeterVariables vars = getVariables(); final String varTrim = varName.execute().trim(); if (vars != null && varTrim.length() > 0) { vars.put(varTrim, telNum); } } sampleResult1.setResponseData("手機號區段:"+ telNum +" 隨機生成的手機號是:" + tel,"utf-8"); sampleResult1.setSuccessful(true); }catch (Exception e){ sampleResult.setSuccessful(false); e.printStackTrace(); }finally { sampleResult1.sampleEnd(); } return tel; }
寫到這裏,基本完成了,但仍是得測試下,功能是否正常,若是先打jar包,丟到Jmeter中,發現有bug的話,來來回回處理,就折騰了,因此仍是須要先測試下的。
在test下新建測試類,示例代碼以下所示:
import org.junit.Test; public class Function_Test { @Test public void phoneTest() throws Exception { RandomPhoneJmeterFunctions randomPhone= new RandomPhoneJmeterFunctions(); String phoneString = randomPhone.execute(); System.out.println("隨機手機號:" + phoneString); } }
測試代碼很簡單,運行測試類,沒有報錯並打印出手機號,則說明沒有問題。運行後的結果以下所示:
生成jar包就不重複講了,能夠看之前的博文,IDEA的基本操做——導入導出jar包
代碼寫好後,天然是要在jmeter中驗證下功能的,咱們將生成的jar包放到jmeter的\lib\ext文件夾下,若是jmeter已啓用,則須要重啓哦,否則不會生效。
打開jmeter後,使用函數助手,看新開發的函數是否有展現,以下所示:
生成函數變量,操做以下所示:
新建線程組,並添加http請求,驗證碼生成的手機號是否是隨機的,運行後,查看結果樹,以下所示:
也能夠經過日誌查看,開發的時候,加了響應日誌,以下所示:
到此,就說明功能沒問題了。函數開發按上述步驟就能夠完成,遇到不知足測試場景的時候,就能夠本身diy一個了。
最後附上完整代碼,以下所示:
private static Logger logger = LogManager.getLogger(RandomPhoneJmeterFunctions.class.getName()); private String tel; //定義函數名稱 private static final String KEY = "__RandomPhone"; //定義函數界面顯示的參數名稱 private static final List<String> desc = new LinkedList<String>(); static{ desc.add("界面參數"); } private static final String[] telFirst = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153 ".split(","); private CompoundVariable varName; //業務主邏輯 @Override public String execute(SampleResult sampleResult, Sampler sampler) throws InvalidVariableException { SampleResult sampleResult1 = new SampleResult(); try { sampleResult1.sampleStart(); int index=getNum(0,telFirst.length-1); String telNum = telFirst[index]; String two = String.valueOf(getNum(1, 888) + 10000).substring(1); String three = String.valueOf(getNum(1, 9100) + 10000).substring(1); tel = telNum + two + three; logger.info("手機號區段:"+ telNum +" 隨機生成的手機號是:" + tel); if (varName != null) { JMeterVariables vars = getVariables(); final String varTrim = varName.execute().trim(); if (vars != null && varTrim.length() > 0) { vars.put(varTrim, telNum); } } sampleResult1.setResponseData("手機號區段:"+ telNum +" 隨機生成的手機號是:" + tel,"utf-8"); sampleResult1.setSuccessful(true); }catch (Exception e){ sampleResult.setSuccessful(false); e.printStackTrace(); }finally { sampleResult1.sampleEnd(); } return tel; } //獲取參數值 @Override public void setParameters(Collection<CompoundVariable> args0) throws InvalidVariableException { //檢測用戶調用函數時,檢測參數個數 checkParameterCount(args0,1); Object[] params = args0.toArray(); if (params.length > 0) { varName = (CompoundVariable) params[0]; } else { varName = null; } } //獲取函數的名稱 @Override public String getReferenceKey() { return KEY; } //獲取界面所要顯示的參數說明 @Override public List<String> getArgumentDesc() { return desc; } private static int getNum(int start,int end) { return (int)(Math.random()*(end-1)); }