本文目录导读:

我来为您提供一个完整的JMeter Java测试案例,包括自定义Java请求和JUnit测试。
自定义Java请求测试类
Maven依赖配置
<dependencies>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>5.6.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.6.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.43</version>
</dependency>
</dependencies>
自定义Java Sampler实现
package com.example.jmeter;
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 org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class TestHttpSampler extends AbstractJavaSamplerClient {
private String requestUrl;
private String requestBody;
private CloseableHttpClient httpClient;
@Override
public void setupTest(JavaSamplerContext context) {
httpClient = HttpClients.createDefault();
System.out.println("Setup test...");
}
@Override
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("URL", "http://localhost:8080/api/test");
params.addArgument("requestBody", "{\"name\":\"test\"}");
params.addArgument("timeout", "5000");
return params;
}
@Override
public SampleResult runTest(JavaSamplerContext context) {
String url = context.getParameter("URL");
String requestBody = context.getParameter("requestBody");
int timeout = Integer.parseInt(context.getParameter("timeout", "5000"));
SampleResult result = new SampleResult();
result.setSampleLabel("Java Http Test");
result.setDataType(SampleResult.TEXT);
try {
// 记录开始时间
result.sampleStart();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "application/json");
httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String responseBody = EntityUtils.toString(entity, StandardCharsets.UTF_8);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
result.setSuccessful(true);
result.setResponseCode("200");
result.setResponseMessage("Success");
} else {
result.setSuccessful(false);
result.setResponseCode(String.valueOf(statusCode));
}
result.setResponseData(responseBody, "UTF-8");
result.setResponseHeaders(response.getStatusLine().toString());
} catch (Exception e) {
result.setSuccessful(false);
result.setResponseMessage("Exception: " + e.getMessage());
e.printStackTrace();
} finally {
result.sampleEnd();
}
return result;
}
@Override
public void teardownTest(JavaSamplerContext context) {
try {
if (httpClient != null) {
httpClient.close();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Teardown test...");
}
}
JUnit测试示例
待测试的业务类
package com.example.jmeter;
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public double divide(double a, double b) {
if (b == 0) {
throw new IllegalArgumentException("Division by zero");
}
return a / b;
}
}
JUnit测试类
package com.example.jmeter;
import static org.junit.Assert.*;
import org.junit.Test;
public class TestCalculator {
private Calculator calculator = new Calculator();
@Test
public void testAdd() {
int result = calculator.add(2, 3);
assertEquals(5, result);
}
@Test
public void testSubtract() {
int result = calculator.subtract(10, 5);
assertEquals(5, result);
}
@Test
public void testDivide() {
double result = calculator.divide(10.0, 2.0);
assertEquals(5.0, result, 0.001);
}
}
使用JUnit进行接口测试
package com.example.jmeter;
import static org.junit.Assert.*;
import org.junit.Test;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class TestAPIWithJUnit {
@Test
public void testGetRequest() throws Exception {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet httpGet = new HttpGet("https://api.github.com/users/octocat");
HttpResponse response = httpClient.execute(httpGet);
assertEquals(200, response.getStatusLine().getStatusCode());
String body = EntityUtils.toString(response.getEntity());
assertTrue(body.contains("octocat"));
}
}
@Test
public void testPostRequest() throws Exception {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost("https://httpbin.org/post");
// 构建JSON请求体
String jsonBody = "{\"name\":\"John\",\"age\":30}";
httpPost.setHeader("Content-Type", "application/json");
httpPost.setEntity(new StringEntity(jsonBody));
HttpResponse response = httpClient.execute(httpPost);
assertEquals(200, response.getStatusLine().getStatusCode());
String body = EntityUtils.toString(response.getEntity());
assertTrue(body.contains("\"name\":\"John\""));
}
}
}
集成测试示例
package com.example.jmeter;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class TestAPIIntegration {
private OkHttpClient client;
private String baseUrl = "https://jsonplaceholder.typicode.com";
@BeforeClass
public void setup() {
client = new OkHttpClient();
}
@Test
public void testGetUser() throws Exception {
Request request = new Request.Builder()
.url(baseUrl + "/users/1")
.get()
.build();
try (Response response = client.newCall(request).execute()) {
assertEquals(200, response.code());
assertNotNull(response.body());
JSONObject jsonObject = JSONObject.parseObject(response.body().string());
assertEquals("Leanne Graham", jsonObject.getString("name"));
}
}
@Test
public void testGetAllUsers() throws Exception {
Request request = new Request.Builder()
.url(baseUrl + "/users")
.get()
.build();
try (Response response = client.newCall(request).execute()) {
assertEquals(200, response.code());
String body = response.body().string();
assertTrue(body.contains("users"));
assertTrue(body.length() > 100);
}
}
@Test
public void testCreatePost() throws Exception {
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
String json = "{\"userId\":1,\"title\":\"Test Post\",\"body\":\"This is test content\"}";
Request request = new Request.Builder()
.url(baseUrl + "/posts")
.post(RequestBody.create(mediaType, json))
.build();
try (Response response = client.newCall(request).execute()) {
assertEquals(201, response.code());
JSONObject jsonObject = JSONObject.parseObject(response.body().string());
assertNotNull(jsonObject.get("id"));
}
}
}
JMeter测试脚本文件(.jmx示例)
创建 test_plan.jmx 文件:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="API Test Plan" enabled="true">
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="server" elementType="Argument">
<stringProp name="Argument.name">server</stringProp>
<stringProp name="Argument.value">example.com</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="HTTP Request Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">100</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">50</stringProp>
<stringProp name="ThreadGroup.ramp_time">10</stringProp>
<boolProp name="ThreadGroup.scheduler">true</boolProp>
<stringProp name="ThreadGroup.duration">60</stringProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="GET Request" enabled="true">
<stringProp name="HTTPSampler.domain">example.com</stringProp>
<stringProp name="HTTPSampler.port">443</stringProp>
<stringProp name="HTTPSampler.protocol">https</stringProp>
<stringProp name="HTTPSampler.path">/api/test</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<stringProp name="HTTPSampler.embedded_url_re">.*\.(css|js|png|jpg)</stringProp>
</HTTPSamplerProxy>
<hashTree/>
<ResultCollector guiclass="SummaryReportGui" testclass="ResultCollector" testname="Summary Report" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
</value>
</objProp>
</ResultCollector>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
最佳实践
性能测试优化示例
package com.example.jmeter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class TestOptimization {
private static ConcurrentHashMap<String, AtomicInteger> requestCount =
new ConcurrentHashMap<>();
public static void incrementRequestCount(String apiName) {
requestCount.computeIfAbsent(apiName, k -> new AtomicInteger(0))
.incrementAndGet();
}
public static int getRequestCount(String apiName) {
return requestCount.getOrDefault(apiName, new AtomicInteger(0)).get();
}
// 缓存优化
private static ConcurrentHashMap<String, Object> cache =
new ConcurrentHashMap<>();
public static Object getFromCache(String key) {
return cache.get(key);
}
public static void putToCache(String key, Object value) {
cache.put(key, value);
}
}
运行方式
# 编译 mvn clean package # 运行JMeter测试 jmeter -n -t test_plan.jmx -l results.jtl -e -o report/ # 运行JUnit测试 mvn test # 生成测试报告 jmeter -g results.jtl -o report/
这些示例包含了完整的测试实现,您可以根据实际需求进行调整和扩展,主要包括:
- 自定义Java的Sampler实现
- JUnit测试用例
- 接口集成测试
- JMeter测试脚本配置
- 性能优化建议