欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

swagger接口转Jmeter,生成压测报告(一键式)

程序员文章站 2022-11-02 19:20:55
功能描述:swagger接口文档通过程序触发Jmeter压测并且生成压测报告环境:maven3.6.3,jdk1.8,Jmeter5.3三个工具方法:downloadFile(获取swagger接口信息) swaggerToJmeter(swagger接口解析) createJmeter(生成jmx文件)pom依赖

功能描述:swagger接口文档通过程序触发Jmeter压测并且生成压测报告

环境:maven3.6.3,jdk1.8,Jmeter5.3

三个工具方法:downloadFile(获取swagger接口信息)

                         swaggerToJmeter(swagger接口解析)

                         createJmeter(生成jmx文件)

pom依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.next</groupId>
  <artifactId>swagger-jmeter</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  	<packaging>jar</packaging>

	<name>swaggerToJmeter</name>
	<description>swagger接口转jmeter</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.1.RELEASE</version>
		<relativePath />
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<jmeter.version>2.12</jmeter.version>
	</properties>

	<dependencies>
		<dependency>
	      <groupId>log4j</groupId>
	      <artifactId>log4j</artifactId>
	      <version>1.2.17</version>
			<exclusions> 
            	 <exclusion>
                    <groupId>javax.mail</groupId>
                    <artifactId>mail</artifactId>
                </exclusion>
             	<exclusion>               
                	<groupId>javax.jms</groupId> 
                	<artifactId>jms</artifactId> 
            	 </exclusion> 
            	 <exclusion>                
                 	<groupId>com.sun.jdmk</groupId>           
                 	 <artifactId>jmxtools</artifactId> 
            	 </exclusion> 
             	<exclusion>             
                  	<groupId>com.sun.jmx</groupId> 
                  	<artifactId>jmxri</artifactId> 
             	</exclusion>
         	 </exclusions>
         	 <scope>runtime</scope>
	    </dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>
			<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.37</version>
		</dependency>
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>
		
		<!-- apache 工具类 -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.11</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>  
		    <groupId>net.sf.json-lib</groupId>   
		    <artifactId>json-lib</artifactId>   
		    <version>2.4</version>  
		    <classifier>jdk15</classifier>    
		</dependency>
		
		<dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>2.13</version>
        </dependency>
		<dependency>
			<groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_functions</artifactId>
            <version>2.13</version>
		</dependency>
		<dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_jdbc</artifactId>
            <version>2.13</version>
		</dependency>
		<dependency>
		<groupId>org.apache.jmeter</groupId>
		<artifactId>ApacheJMeter_http</artifactId>
            <version>2.13</version>
		</dependency>  
      <!--   <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_java</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.jmeter</groupId>
            <artifactId>ApacheJMeter_http</artifactId>
            <version>4.0</version>
        </dependency> -->
	</dependencies>
</project>

实体类SwaggerDo

public class SwaggerDo {
	private String url;
	private String UrlValue;
	private String reqestType;
	private String summary;
	private String ref;
	private JSONObject content;
	private String contentKey;
	private JSONObject refJson;
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getUrlValue() {
		return UrlValue;
	}
	public void setUrlValue(String urlValue) {
		UrlValue = urlValue;
	}
	public String getReqestType() {
		return reqestType;
	}
	public void setReqestType(String reqestType) {
		this.reqestType = reqestType;
	}
	public String getSummary() {
		return summary;
	}
	public void setSummary(String summary) {
		this.summary = summary;
	}
	public String getRef() {
		return ref;
	}
	public void setRef(String ref) {
		this.ref = ref;
	}
	public JSONObject getContent() {
		return content;
	}
	public void setContent(JSONObject content) {
		this.content = content;
	}
	public String getContentKey() {
		return contentKey;
	}
	public void setContentKey(String contentKey) {
		this.contentKey = contentKey;
	}
	public JSONObject getRefJson() {
		return refJson;
	}
	public void setRefJson(JSONObject refJson) {
		this.refJson = refJson;
	}
	
}

获取swagger.json文件

    //获取swagger.json文件
    public static boolean downloadFile(File file,String urlstr) {
        URL url = null;
        try {
        	//文件url
            url = new URL(urlstr);
            //将url链接下的图片以字节流的形式存储到 DataInputStream类中
            DataInputStream dataInputStream = new DataInputStream(url.openStream());
            //为file生成对应的文件输出流
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            //定义字节数组大小
            byte[] buffer = new byte[1024];
            int len = -1;
            //用流写入指定位置文件                
            while ((len = dataInputStream.read(buffer))!= -1) { 
                 fileOutputStream.write(buffer,0,len);
            }
            dataInputStream.close();
            fileOutputStream.close();

            return true;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

 swaggerToJmeter方法适配本项目会有些乱,可以仅供参考

private static final String DEFAULT_PROPERTIES = "/application.properties";

/**
 * 获取properties属性值
 * 
 * @param propKey
 * @return
 */
public static String getPropValue(String propKey) {
	try {
		Properties props = new Properties();
		InputStream inputStream = PropertiesUtil.class.getResourceAsStream(DEFAULT_PROPERTIES);
		// *.properties配置文件,要使用UTF-8编码,否则会现中文乱码问题
		BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
		props.load(bf);
		return props.getProperty(propKey);
	} catch (IOException e) {
		e.printStackTrace();
	}
	return null;
}

public static void swaggerToJmeter() {
	// properties获取配置信息
	String pathname = getPropValue("path");
	File file = new File(pathname);
	String urlstr = getPropValue("url");
	// 抓取swagger.js文件
	SwaggerUtil.downloadFile(file, urlstr);
	Reader reader = null;
	InputStream in = null;
	BufferedReader bufIn = null;
	OutputStream out = null;
	Writer writer = null;
	BufferedWriter bufOut = null;
	ArrayList<SwaggerDo> list = new ArrayList<SwaggerDo>();
	try {
		in = new FileInputStream(pathname);
		reader = new InputStreamReader(in, "Utf-8");
		bufIn = new BufferedReader(reader);
		String line = null;
		// swagger文件中有"integer"等需要替换成int类型数据
		String regex = "\"int[0-9a-z]+\"";
		StringBuffer sb = new StringBuffer();
		while ((line = bufIn.readLine()) != null) {
			sb.append(line);
		}
		// json格式转换
		JSONObject json = JSONObject.fromObject(new String(sb));
		String jsonStr = json.getString("paths");
		// paths节点json串
		json = JSONObject.fromObject(jsonStr);
		Iterator it = json.keys();
		// url:路径, value:路径的value,reqest:请求方式,summary:备注,reqStr:请求方式的value
		// 取url
		while (it.hasNext()) {
			SwaggerDo swagger = new SwaggerDo();
			swagger.setUrl((String) it.next());
			swagger.setUrlValue(json.getString(swagger.getUrl()));
			JSONObject valueJson = JSONObject.fromObject(swagger.getUrlValue());
			Iterator valueIt = valueJson.keys();
			// 取请求方式(POST,GET),备注
			while (valueIt.hasNext()) {
				swagger.setReqestType((String) valueIt.next());
				// 拿备注
				JSONObject reqJson = valueJson.getJSONObject(swagger.getReqestType());
				if (reqJson.has("summary")) {
					swagger.setSummary(reqJson.getString("summary"));
				}
				if ("post".equals(swagger.getReqestType())) {
					if (reqJson.has("requestBody")) {
						// swagger中不同的请求content-type不一致
						swagger.setContent(reqJson.getJSONObject("requestBody").getJSONObject("content"));
						Iterator contentIt = swagger.getContent().keys();
						while (contentIt.hasNext()) {
							swagger.setContentKey((String) contentIt.next());
							if ("multipart/form-data".equals(swagger.getContentKey())) {
								System.out.println("我是form");
								break;
							}
							swagger.setRef(swagger.getContent().getJSONObject(swagger.getContentKey())
									.getJSONObject("schema").getString("$ref"));
							swagger.setRef(swagger.getRef().substring(swagger.getRef().lastIndexOf("/") + 1));
							JSONObject schemas = JSONObject.fromObject(new String(sb)).getJSONObject("components")
									.getJSONObject("schemas");
							if (schemas.has(swagger.getRef())) {
								// swagger.setRefJson(schemas.getJSONObject(swagger.getRef()).getJSONObject("properties"));
								JSONObject properties = schemas.getJSONObject(swagger.getRef())
										.getJSONObject("properties");
								Iterator bodyDataIt = properties.keys();
								List<Map<String, Object>> bodyData = new ArrayList<Map<String, Object>>();
								JSONObject jsonObject = new JSONObject();
								while (bodyDataIt.hasNext()) {
									String bodyDataKey = (String) bodyDataIt.next();
									String type = properties.getJSONObject(bodyDataKey).getString("type");
									Map<String, Object> map = new HashMap<String, Object>();
									if ("integer".equals(type)) {
										map.put(bodyDataKey, 1);
									} else if ("string".equals(type)) {
										map.put(bodyDataKey, "1");
									} else if ("boolean".equals(type)) {
										map.put(bodyDataKey, true);
									}
									if (bodyDataKey.matches("[A-Za-z]*Time")) {
										map.put(bodyDataKey, "2020-07-24T09:45:44.496Z");
									}
									jsonObject.putAll(map);
								}
								swagger.setRefJson(JSONObject.fromObject(jsonObject));
							}
							break;
						}
					}
				}
			}
			// 接口过滤,创建删除等
			String reg = "Update";
			if ((swagger.getUrl().indexOf(reg) != -1) && "post".equals(swagger.getReqestType())) {
				list.add(swagger);
			}
		}
		// 写Jmeter文件
		JmeterUtil.createJmeter(list,
				"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6ImNlNDU2YjIxLWY5YmItNmQ2NC04NmFhLTM5ZjYwYjU3N2QzNCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkFkbWluIiwiaHR0cDovL3d3dy5hc3BuZXRib2lsZXJwbGF0ZS5jb20vaWRlbnRpdHkvY2xhaW1zL3RlbmFudElkIjoiMSIsInN1YiI6IjQiLCJqdGkiOiI1MjZiNmZkYS01YTU4LTQxMzMtOWExZC1iNDM5MWRkZjA0ZDQiLCJpYXQiOjE1OTU5MDU2OTMsIm5iZiI6MTU5NTkwNTY5MywiZXhwIjoxNTk1OTkyMDkzLCJpc3MiOiJGVEFQIiwiYXVkIjoiRlRBUCJ9.Xc8yprGG1tu63_XbEE3-ks-hUn3ix3mpbm5saTPxqv4");
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {
		try {
			bufIn.close();
			reader.close();
			in.close();
			bufOut.close();
			writer.close();
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

为Jmeter加载配置

static{

	JMeterUtils.setJMeterHome(new File("D:\\wxspace\\apache-jmeter-5.3").getAbsolutePath());

	JMeterUtils.loadJMeterProperties(new File("D:\\wxspace\\apache-jmeter-5.3\\bin\\jmeter.properties").getAbsolutePath());

	JMeterUtils.setProperty("saveservice_properties", "\\bin\\saveservice.properties");

	JMeterUtils.setProperty("user_properties", "D:\\wxspace\\apache-jmeter-5.3\\bin\\user.properties");

	JMeterUtils.setProperty("upgrade_properties", "D:\\wxspace\\apache-jmeter-5.3\\bin\\upgrade.properties");

	JMeterUtils.setProperty("system_properties", "D:\\wxspace\\apache-jmeter-5.3\\bin\\system.properties");

	////    JMeterUtils.setProperty("proxy.cert.directory", new File("").getAbsolutePath());

	JMeterUtils.setLocale(Locale.SIMPLIFIED_CHINESE);

	JMeterUtils.initLocale();

	}

createJmeter是为生成.jmx文件配置节点

	public static void createJmeter(ArrayList<SwaggerDo> list,String token) {
		ListedHashTree hashTreeHTTPSamplerProxy = new ListedHashTree();
		//生成jmx文件
		ListedHashTree hashTreeResultCollectorAndHeaderManager = new ListedHashTree();
		ResultCollector resultCollector1 = new ResultCollector();
		resultCollector1.setProperty(TestElement.GUI_CLASS, "ViewResultsFullVisualizer");
		resultCollector1.setProperty(TestElement.TEST_CLASS, "ResultCollector");
		resultCollector1.setProperty(TestElement.NAME, "View Results Tree");
		resultCollector1.setProperty(TestElement.ENABLED, "true");
		ResultCollector resultCollector2 = new ResultCollector();
		resultCollector2.setProperty(TestElement.GUI_CLASS, "StatVisualizer");
		resultCollector2.setProperty(TestElement.TEST_CLASS, "ResultCollector");
		resultCollector2.setProperty(TestElement.NAME, "Aggregate Report");
		resultCollector2.setProperty(TestElement.ENABLED, "true");
		hashTreeResultCollectorAndHeaderManager.add(resultCollector1);
		hashTreeResultCollectorAndHeaderManager.add(resultCollector2);
//			hashTreeResultCollectorAndHeaderManager.add(headerManager);
		//TestPlan
		TestPlan testPlan = new TestPlan("Test Plan");
		testPlan.setFunctionalMode(false);
		testPlan.setSerialized(false);
		testPlan.setTearDownOnShutdown(true);
                testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
	        testPlan.setProperty(TestElement.GUI_CLASS,"TestPlanGui");
		testPlan.setProperty(new BooleanProperty(TestElement.ENABLED, true));
		testPlan.setProperty(new StringProperty("TestPlan.comments", ""));
		testPlan.setProperty(new StringProperty("TestPlan.user_define_classpath", ""));
		Arguments arguments = new Arguments();
		testPlan.setProperty(new TestElementProperty("TestPlan.user_defined_variables",arguments));
	
		//ThreadGroup
		org.apache.jmeter.threads.ThreadGroup threadGroup = new org.apache.jmeter.threads.ThreadGroup();
		threadGroup.setNumThreads(10);
		threadGroup.setRampUp(3);
		threadGroup.setDelay(0);
		threadGroup.setDuration(0);
		threadGroup.setProperty(new StringProperty(org.apache.jmeter.threads.ThreadGroup.ON_SAMPLE_ERROR, "continue"));
		
		//main_controller
		LoopController loopController = new LoopController();
		loopController.setProperty("LoopController.loops", 1);
		loopController.setProperty("LoopController.continue_forever", false);
		TestElementProperty element = new TestElementProperty("ThreadGroup.main_controller",loopController);
		threadGroup.setProperty(element);
		threadGroup.setScheduler(false);
		threadGroup.setName("Thread Group");
		threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
		threadGroup.setProperty(TestElement.GUI_CLASS,"ThreadGroupGui");
		threadGroup.setProperty(new BooleanProperty(TestElement.ENABLED, true));

		//httpSampleProxy
		for(SwaggerDo swagger : list) {
			System.out.println("list-========"+list);
			HTTPSamplerProxy httpSamplerProxy = new HTTPSamplerProxy();
			Arguments HTTPsamplerArguments = new Arguments();
			HTTPArgument httpArgument = new HTTPArgument();
			httpArgument.setProperty(new BooleanProperty("HTTPArgument.always_encode",false));
			httpArgument.setProperty(new StringProperty("Argument.value", String.valueOf(swagger.getRefJson())));
			httpArgument.setProperty(new StringProperty("Argument.metadata","="));
			ArrayList<TestElementProperty> list1 = new ArrayList<>();
			list1.add(new TestElementProperty("",httpArgument));
			HTTPsamplerArguments.setProperty(new CollectionProperty("Arguments.arguments",list1));
			httpSamplerProxy.setProperty(new TestElementProperty("HTTPsampler.Arguments",HTTPsamplerArguments));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.domain", "10.206.32.39"));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.port", "8004"));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.protocol", "http"));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.path", swagger.getUrl()));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.method", swagger.getReqestType()));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.contentEncoding", "utf-8"));
			httpSamplerProxy.setProperty(new BooleanProperty("HTTPSampler.follow_redirects", true));
			httpSamplerProxy.setProperty(new BooleanProperty("HTTPSampler.postBodyRaw", true));
			httpSamplerProxy.setProperty(new BooleanProperty("HTTPSampler.auto_redirects", false));
			httpSamplerProxy.setProperty(new BooleanProperty("HTTPSampler.use_keepalive", true));
			httpSamplerProxy.setProperty(new BooleanProperty("HTTPSampler.DO_MULTIPART_POST", false));
			httpSamplerProxy.setProperty(new StringProperty("TestElement.gui_class", "org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui"));
			httpSamplerProxy.setProperty(new StringProperty("TestElement.test_class", "org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy"));
			httpSamplerProxy.setProperty(new StringProperty("TestElement.name", swagger.getUrl()));
			httpSamplerProxy.setProperty(new StringProperty("TestElement.enabled", "true"));
			httpSamplerProxy.setProperty(new BooleanProperty("HTTPSampler.postBodyRaw", true));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.embedded_url_re", ""));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.connect_timeout", ""));
			httpSamplerProxy.setProperty(new StringProperty("HTTPSampler.response_timeout", ""));
			httpSamplerProxy.setProperty(new StringProperty("TestPlan.comments", swagger.getSummary()));
			hashTreeHTTPSamplerProxy.add(httpSamplerProxy,hashTreeResultCollectorAndHeaderManager);
		}
		//HeaderManager
		Header header1 = new Header();
		Header header2 = new Header();
		Header header3 = new Header();
		header1.setProperty(new StringProperty("Header.name","Content-Type"));
		header1.setProperty(new StringProperty("Header.value","application/json"));
		header2.setProperty(new StringProperty("Header.name","Authorization"));
		header2.setProperty(new StringProperty("Header.value","Bearer "+token));
		header3.setProperty(new StringProperty("Header.name","Accept"));
		header3.setProperty(new StringProperty("Header.value","application/json,text/plain,*/*"));
		TestElementProperty HeaderElement1 = new TestElementProperty("",header1);
		TestElementProperty HeaderElement2 = new TestElementProperty("",header2);
		TestElementProperty HeaderElement3 = new TestElementProperty("",header3);
		ArrayList<TestElementProperty> list2 = new ArrayList<>();
		list2.add(HeaderElement1);
		list2.add(HeaderElement2);
		list2.add(HeaderElement3);
		HeaderManager headerManager = new HeaderManager();
		headerManager.setProperty(new CollectionProperty("HeaderManager.headers",list2));
		headerManager.setProperty(new StringProperty("TestElement.test_class","org.apache.jmeter.protocol.http.control.HeaderManager"));
		headerManager.setProperty(new StringProperty("TestElement.name","HTTP Header Manager"));
		headerManager.setProperty(new StringProperty("TestElement.enabled","true"));
		headerManager.setProperty(new StringProperty("TestElement.gui_class","org.apache.jmeter.protocol.http.gui.HeaderPanel"));

		//headerManager
		hashTreeHTTPSamplerProxy.add(headerManager);
		ListedHashTree hashTreeThreadGroup = new ListedHashTree();
		hashTreeThreadGroup.add(threadGroup,hashTreeHTTPSamplerProxy);
		ListedHashTree hashTreeTestPlan = new ListedHashTree();
		hashTreeTestPlan.add(testPlan,hashTreeThreadGroup);
		try {
			SaveService.saveTree(hashTreeTestPlan, new FileOutputStream("D:\\update.jmx"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

功能测试触发生成webReport测试报告文件

	//触发压测请求
	@Test 
	public void testCmd() throws IOException {
		JsonUtil.swaggerToJmeter();
		String command = "D:\\wxspace\\apache-jmeter-5.3\\bin\\jmeter -n -t D:\\update.jmx -l D:\\update.jtl -e -o D:\\WebReport";
		Runtime.getRuntime().exec("cmd.exe /C start " + command);
	}

 

本文地址:https://blog.csdn.net/l666661/article/details/107690606