JMeter Java案例

wen java案例 2

本文目录导读:

JMeter Java案例

  1. 自定义Java请求测试类
  2. JUnit测试示例
  3. 使用JUnit进行接口测试
  4. 集成测试示例
  5. JMeter测试脚本文件(.jmx示例)
  6. 最佳实践
  7. 运行方式

我来为您提供一个完整的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测试脚本配置
  • 性能优化建议

抱歉,评论功能暂时关闭!