有一個任務,需要頻繁發送訂單請求,並分析訂單請求中有沒有存在重復訂單號,思路是用jmeter 發送http請求,使用正則表達式獲取到訂單號,並把訂單號和線程號作為參數提供給java請求,在java請求中把訂單號寫到包括有線程號的命名文件中。完成出來的樣子是這樣的
步驟如下:
1、Jmeter 發送http請求
1) 右鍵點擊線程組> 添加 > 配置元件 > HTTP信息頭管理器 ,新建HTTP信息頭管理器
2) 右鍵點擊線程組> 添加 > Sampler > HTTP請求,新建HTTP請求
2,在下單過后返回部分信息如下:"msg":"下單成功","result":"1","sendCode":"96828628","weektm":"星期二,12:00"
右鍵點擊線程組> 添加 > 后置處理器 > 正則表達式提取器,新建 正則表達式提取器 ,獲取sendCode 后面的值96828628 正則表達式填寫:"sendCode":"(\d{8}),這樣訂單號就保存在變量sendCode中
3、到此,訂單號sendCode已經獲取到,需要把這個訂單號保存到文件中,可以采用“保存響應到文件” 把響應保存到以線程命名的文件中,但是不好的是一個文件只能保存一個結果,不能往結果中追加結果,對於后期匯總不方便
這里使用了java請求來處理,按線程文件名命名,把同一個線程所有的響應結果保存到同一個文件中,n個線程就保存n個文件,這樣就使用了java請求,java請求需要做的有
1)新建一個java項目,在java項目里面新建一個java類AppendFile 功能是往文件中追加內容,另外一個方法是找重復內容,如果內容有重復,就保存到另外一個文件中
package editFile; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.RandomAccessFile; import java.util.HashSet; import java.util.Set; public class AppendFile { public static void main(String[] args) { AppendFile a = new AppendFile(); /* a.appendFile("E:\\dd.txt", "222222222222222"); a.appendFile(""E:\\jmeter\\sameText.txt"", "333333333");*/ String allSendCode = a.read("E:\\jmeter\\sameText.txt"); // System.out.println(allSendCode); } public void appendFile(String fileName, String content) { try { // 打開一個隨機訪問文件流,按讀寫方式 RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw"); // 文件長度,字節數 long fileLength = randomFile.length(); // 將寫文件指針移到文件尾。 randomFile.seek(fileLength); randomFile.writeBytes(content + "\r\n"); randomFile.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 讀取文件,並判斷文件中是否有重復內容,如果有重復內容,把重復內容保存到另外一個文件 * @param filePath * @return */ @SuppressWarnings({ "rawtypes", "unchecked" }) public String read(String filePath) { BufferedReader br = null; String line = null; StringBuffer buf = new StringBuffer(); Set set = new HashSet(); try { br = new BufferedReader(new FileReader(filePath)); int lineCount = 0; while ((line = br.readLine()) != null) { buf.append(line + "\r\n"); lineCount = lineCount + 1; if(!set.add(line)){ AppendFile a = new AppendFile(); a.appendFile("E:\\jmeter\\sameTextRepeat.txt", line); } System.out.println(lineCount+":"+line); } } catch (Exception e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { br = null; } } } return buf.toString(); } }
2)java項目里面添加java請求類WriteResult ,作用是從jmeter獲取訂單號和線程號,並使用訂單號和線程號 寫人文件,同時jmeter 性能測試的java請求也是這樣來實現的,按照格式在runTest 中做各種請求。
package editFile;
import org.apache.jmeter.config.Arguments; import org.apache.jmeter.protocol.java.sampler.JavaSamplerClient; import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; import org.apache.jmeter.samplers.SampleResult; public class WriteResult implements JavaSamplerClient { private SampleResult results; private String senCode; private String threadNumber; // 設置從jmeter傳入參數 public Arguments getDefaultParameters() { Arguments params = new Arguments(); params.addArgument("senCode", "0");// 設置senCode參數 params.addArgument("threadNumber", "0");// 設置threadNumber return params; } // 初始化方法,性能測試時只執行一次 public void setupTest(JavaSamplerContext arg0) { } // 重復執行測試的地方 public SampleResult runTest(JavaSamplerContext arg0) { senCode = arg0.getParameter("senCode"); // 獲取jmeter傳入的參數值, threadNumber = arg0.getParameter("threadNumber"); // 獲取jmeter傳入的參數值, results = new SampleResult(); results.sampleStart();// jmeter 開始統計響應時間標記 AppendFile.appendFile("E:\\jmeter\\"+threadNumber+".txt", senCode); if(senCode.length() ==8){ results.setSuccessful(true); results.setResponseData("threadNumber:"+threadNumber+"|senCode:"+senCode, null); }else{ results.setSuccessful(false); results.setResponseData("threadNumber:"+threadNumber+"|沒有獲取到驗證碼 ", null); } results.sampleEnd();// jmeter 結束統計響應時間標記 return results; } // 結束方法,實際運行時每個線程僅執行一次,在測試方法運行結束后執行 public void teardownTest(JavaSamplerContext arg0) { } public static void main(String[] args) { // TODO Auto-generated method stub } }
把java項目文件導出jar包,放在jmeter 的lib/ext 文件夾中
打開jmeter添加一個jmeter 的java請求, 右鍵點擊線程組> 添加 > Sampler > java請求, 選中測試類,會自動顯示2個參數 sendCode 和threadNumber(這2個參數是在java請求類的的方法中設置:public Arguments getDefaultParameters()
sendCode = ${sendcode}
threadNumber = ${__threadNum}
使用3個線程執行多次,結果如下:
另外使用bean shell 也能保存文件,右鍵點擊線程組> 添加 > 后置處理器 > BeanShell PostProcessor 新建beanshell,需要在bean shell中寫代碼
import editFile.*;
import org.apache.jmeter.threads.JMeterContextService; int threadNumber = JMeterContextService.getNumberOfThreads(); String sendCode = vars.get("sendcode"); //把獲取的sendcode 變成bean shell變量值 AppendFile.appendFile("E:\\jmeter\\result"+threadNumber+".txt", sendCode); System.out.println("finished");
但是 獲取的線程號代碼都是1,因此所有的訂單號都保存在同一個文件中,不知道這樣會不會都在寫同一個文件導致文件不全,要測試下才知道