jmeter实行接口的压力测试
jmeter 环境配置, 用的环境系 apache-jmeter-3.1
1. 把解压后的lib 引用到java 的库里面使用
示例代码
package test; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; 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; /** * @author author : Minwei * @date create_at : 2017年2月7日 上午10:27:51 * @version 1.0 * @parameter * @since * @return */ public class TestDemo extends AbstractJavaSamplerClient { private SampleResult results; private String testStr; public SampleResult runTest(JavaSamplerContext arg0) { System.out.println("test"); int len = 0; results.sampleStart(); // 定义一个事务,表示这是事务的起始点,类似于LoadRunner的lr.start_transaction len = testStr.length(); results.sampleEnd(); // 定义一个事务,表示这是事务的结束点,类似于LoadRunner的lr.end_transaction if (len < 5) { System.out.println(testStr); results.setSuccessful(false); // 用于设置运行结果的成功或失败,如果是"false"则表示结果失败,否则则表示成功 } else results.setSuccessful(true); return results; } @Override public void setupTest(JavaSamplerContext context) { results = new SampleResult(); testStr = context.getParameter("testString", ""); if (testStr != null && testStr.length() > 0) { results.setSamplerData(testStr); } } @Override public void teardownTest(JavaSamplerContext context) { super.teardownTest(context); } public Arguments getDefaultParameters() { Arguments params = new Arguments(); params.addArgument("testString", ""); // 定义一个参数,显示到Jmeter的参数列表中,第一个参数为参数默认的显示名称,第二个参数为默认值 return params; } public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException { TestDemo service = new TestDemo(); Arguments params = new Arguments(); params.addArgument("testString", "hehe"); JavaSamplerContext context = new JavaSamplerContext(params); service.setupTest(context); SampleResult res = service.runTest(context); System.out.println("test is success:" + res.isSuccessful() + " used:" + (res.getEndTime() - res.getStartTime()) + "ms " + " result:" + res.getSampleLabel() + ":" + res.getSamplerData()); service.teardownTest(context); System.out.println("res.getEndTime() = " + res.getEndTime()); System.out.println("res.getStartTime() = " + res.getStartTime()); System.exit(0); } }
注 : main 方法用于测试代码是否正确, 或者用户单线程的测试, 然后打包到jar 就可以放到apache-jmeter-3.1 使用
传入参数的时候可以使用txt文件 就是 csv data 来获取批量的参数多线程测试
如果不用csv多线程 tearDown 和setup都只会运行一次, 如果用csv data 就会有多个tearDown 和setup 运行, 获取csvdata 文件的时候需要本地的全文件路径。
附: java 发post 请求带中文的方法
/** * 向指定 URL 发送POST方法的请求 * * @param url * 发送请求的 URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Minwei"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; }
排序map参数
/** * 自定义加密匹配 * * @param 参数列表 * @return 字符串 * @throws UnsupportedEncodingException */ public static String myEncodeParam(Map<String, String> paramsMap) throws NoSuchAlgorithmException, UnsupportedEncodingException { // 排序 List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(paramsMap.entrySet()); Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() { public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) { return (o1.getKey()).toString().compareTo(o2.getKey()); } }); StringBuilder sb = new StringBuilder(); for (int i = 0; i < infoIds.size(); i++) { Map.Entry<String, String> entry = infoIds.get(i); sb.append(entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), "UTF-8") + "&"); } String md5Code = sb.toString() + "key=" + TestHelper.code; String lol = TestHelper.md5(md5Code); sb.append("lol=" + lol); return sb.toString(); }
软件上添加线程组,然后添加自定义的需要测试的请求方法, 这里用java请求,然后选择jar包中的class 参数那里如果用的是csv 就用{param}的写法写入参数。然后添加监视器来检测java代码中出现的访问时间,exception需要自己在代码里面控制输出到 返回data中。
jmeter测试的说明
说明:
Label:每个 JMeter 的 element (例如 HTTP Request )都有一个 Name 属性,这里显示的就是 Name 属性的值
#Samples:表示你这次测试中一共发出了多少个请求,我的测试计划模拟 10 个用户,每个用户迭代 10 次,因此这里显示 100
Average:平均响应时间 —— 默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,也可以以 Transaction 为单位显示平均响应时间
Median:中位数,也就是 50 %用户的响应时间
90% Line: 90 %用户的响应时间
Min: 最小响应时间
Max: 最大响应时间
Error%:本次测试中出现错误的请求的数量 / 请求的总数
Throughput:吞吐量 —— 默认情况下表示每秒完成的请求数( Request per Second ),当使用了 Transaction Controller 时,也可以表示类似 LoadRunner 的 Transaction per Second 数
KB/Sec:每秒从服务器端接收到的数据量,相当于 LoadRunner 中的 Throughput/Sec