Skip to content

Commit 7cc38b0

Browse files
committed
Api automated unit testing.
1 parent f39ddcc commit 7cc38b0

File tree

5 files changed

+132
-13
lines changed

5 files changed

+132
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ buildNumber.properties
1515
.project
1616
# JDT-specific (Eclipse Java Development Tools)
1717
.classpath
18+
/.idea

pom.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,19 @@
6060

6161
<!-- 只保留 GitHub Packages 配置 -->
6262
<distributionManagement>
63-
<!-- <repository>-->
64-
<!-- <id>github</id>-->
65-
<!-- <name>GitHub Json031 Apache Maven Packages</name>-->
66-
<!-- <url>https://maven.pkg.github.com/json031/mcunittests</url>-->
67-
<!-- </repository>-->
63+
<repository>
64+
<id>github</id>
65+
<name>GitHub Json031 Apache Maven Packages</name>
66+
<url>https://maven.pkg.github.com/json031/mcunittests</url>
67+
</repository>
6868
<snapshotRepository>
6969
<id>ossrh</id>
7070
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
7171
</snapshotRepository>
72-
<repository>
73-
<id>ossrh</id>
74-
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
75-
</repository>
72+
<!-- <repository>-->
73+
<!-- <id>ossrh</id>-->
74+
<!-- <url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>-->
75+
<!-- </repository>-->
7676
</distributionManagement>
7777

7878
<build>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package io.github.json031.JavaBean;
2+
3+
public class HighConcurrencyResult {
4+
public final int total;
5+
public final int success;
6+
public final int failed;
7+
public final long avgResponseTimeMillis;
8+
9+
public HighConcurrencyResult(int total, int success, int failed, long avgResponseTimeMillis) {
10+
this.total = total;
11+
this.success = success;
12+
this.failed = failed;
13+
this.avgResponseTimeMillis = avgResponseTimeMillis;
14+
}
15+
16+
@Override
17+
public String toString() {
18+
return "=== Load Test Result ===\n" +
19+
"Total Requests: " + total + "\n" +
20+
"Successful: " + success + "\n" +
21+
"Failed: " + failed + "\n" +
22+
"Avg Time (ms): " + avgResponseTimeMillis;
23+
}
24+
}

src/main/java/io/github/json031/MCApiTests.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,40 @@ public class MCApiTests {
1414
*
1515
* @param url 完整的 API 地址(包括 http/https)
1616
* @param timeout 最大允许超时时间(秒)
17+
* @return durationMillis 响应时间(毫秒)
1718
*/
18-
public void assertApiRespondsWithinTimeout(String url, long timeout) {
19+
public long assertApiRespondsWithinTimeout(String url, long timeout, boolean verbose) {
20+
return this.assertApiRespondsWithinTimeoutMillis(url, timeout * 1000, verbose);
21+
}
22+
23+
/**
24+
* 通用测试方法,验证给定 API 是否能在 timeout 秒内响应
25+
*
26+
* @param url 完整的 API 地址(包括 http/https)
27+
* @param timeoutMillis 最大允许超时时间(毫秒)
28+
* @return durationMillis 响应时间(毫秒)
29+
*/
30+
public long assertApiRespondsWithinTimeoutMillis(String url, long timeoutMillis, boolean verbose) {
1931
try {
20-
Assertions.assertTimeout(Duration.ofSeconds(timeout), () -> {
21-
String response = restTemplate.getForObject(url, String.class);
32+
long start = System.nanoTime(); // 记录开始时间
33+
34+
String response = this.restTemplate.getForObject(url, String.class);
35+
36+
long end = System.nanoTime(); // 记录结束时间
37+
long durationMillis = (end - start) / 1_000_000;
38+
if (verbose) {
2239
System.out.println("API Response: " + response);
23-
}, "API did not respond within " + timeout + " seconds");
40+
System.out.println("Response time: " + durationMillis + " ms");
41+
}
42+
43+
if (durationMillis >= timeoutMillis) {
44+
Assertions.fail("API did not respond within " + timeoutMillis + " milliseconds, url: " +url);
45+
}
46+
47+
return durationMillis;
2448
} catch (Exception e) {
2549
Assertions.fail("Connection refused when trying to access: " + url);
2650
}
51+
return -1;
2752
}
2853
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package io.github.json031;
2+
3+
import io.github.json031.JavaBean.HighConcurrencyResult;
4+
import org.junit.jupiter.api.Assertions;
5+
import org.springframework.web.client.RestTemplate;
6+
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.concurrent.*;
10+
import java.util.concurrent.atomic.AtomicInteger;
11+
import java.util.function.Supplier;
12+
13+
public class MCHighConcurrencyTests {
14+
15+
private final RestTemplate restTemplate = new RestTemplate();
16+
private final MCApiTests mcApiTests = new MCApiTests();
17+
18+
/**
19+
* 运行并发测试
20+
* @param url 请求地址
21+
* @param threadCount 并发线程数
22+
* @return 统计结果
23+
*/
24+
public HighConcurrencyResult highConcurrencyTest(String url, int threadCount, long timeoutMillis, boolean verbose) {
25+
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
26+
List<Future<Long>> futures = new ArrayList<>();
27+
AtomicInteger successCount = new AtomicInteger();
28+
AtomicInteger failCount = new AtomicInteger();
29+
30+
for (int i = 0; i < threadCount; i++) {
31+
futures.add(executor.submit(() -> {
32+
long start = System.nanoTime();
33+
try {
34+
long rsptime = this.mcApiTests.assertApiRespondsWithinTimeoutMillis(url, timeoutMillis, verbose); // 执行请求
35+
System.out.println("API Response time: " + rsptime);
36+
if (rsptime >= timeoutMillis) {
37+
failCount.incrementAndGet();
38+
} else {
39+
successCount.incrementAndGet();
40+
}
41+
} catch (Exception e) {
42+
failCount.incrementAndGet();
43+
}
44+
return (System.nanoTime() - start) / 1_000_000;
45+
}));
46+
}
47+
48+
executor.shutdown();
49+
try {
50+
executor.awaitTermination(60, TimeUnit.SECONDS);
51+
} catch (Exception e) {
52+
Assertions.fail("High concurrency test failed for url: " + url);
53+
}
54+
55+
long totalTime = 0;
56+
int completed = 0;
57+
for (Future<Long> future : futures) {
58+
try {
59+
long time = future.get();
60+
totalTime += time;
61+
completed++;
62+
} catch (Exception ignored) {
63+
}
64+
}
65+
66+
long avg = completed > 0 ? totalTime / completed : -1;
67+
return new HighConcurrencyResult(threadCount, successCount.get(), failCount.get(), avg);
68+
}
69+
}

0 commit comments

Comments
 (0)