Design and Implementation of the Huajiao Test Platform for Integrated API and Stress Testing
The article details the architecture, core objectives, and implementation of the Huajiao testing platform, describing how it lowers code barriers for testers, provides visual case management, integrates API and pressure testing, and outlines backend services built with Springboot, Mybatis, and related tooling.
The Huajiao testing platform was created with two primary goals: reducing the code expertise required for interface testing and offering visual management of test cases, execution, and results.
Its overall framework consists of three major components, with a focus on integrating API testing and stress testing. The web platform, built with JSP (and some Vue components), serves as the core UI, while the backend uses Springboot and Mybatis, secured by Shiro for fine‑grained permission control.
Case Management handles creation, modification, and online execution of various case types (API, scenario, BVT). API cases store detailed metadata such as environment, module, priority, token, request parameters, and expected validation.
Example interaction flow: a user browses a case, edits it, saves it, and the server validates permissions before persisting changes to the database.
Batch execution is supported through multithreaded processing. The following code shows the controller for single‑case execution:
@ResponseBody
@RequestMapping(value = "/js_case_execute", method = RequestMethod.POST)
public Response js_case_execute(Case hjcase, HttpServletRequest request) {
RequestUtil.preResetField(request, hjcase);
try {
List
resultList = new ArrayList<>();
CaseResult hjresult = new CaseResult(hjcase.getId(), hjcase.getCasename(), -1, "");
executeCase(hjcase, hjresult);
resultList.add(hjresult);
RedisService.addToMyFavCase(SecurityUtils.getSubject().getSession().getAttribute(Const.SESSION_USER), hjcase.getId() + "_" + hjcase.getCasename());
return new Response(resultList);
} catch (ParamFormatException e) {
return new Response(1, e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Response(1, "Exception---" + e.getMessage());
}
}Batch execution logic is illustrated below:
@ResponseBody
@RequestMapping(value = "case/batchExecCase")
public Response batchExecCase(Case hjcasesrc, HttpServletRequest request) {
RequestUtil.preResetField(request, hjcasesrc);
if (hjcasesrc.getCasetype() == 2) {
try {
List
subCases = caseService.findByIds(hjcasesrc.getCaseids());
hjcasesrc.setSubCases(subCases);
} catch (Exception e) {
e.printStackTrace();
}
}
Response response = new Response();
try {
List
keyinfos = hjcasesrc.getBatchKeyInfos();
httpUtils utils = new httpUtils();
for (BatchKeyInfo keyinfo : keyinfos) {
if (!keyinfo.isToken()) continue;
// ... omitted user info retrieval
break;
}
response.put(Response.TOTAL, totalBatch);
List
threadPool = new ArrayList<>();
for (int i = 0; i < threadnum; i++) {
httpUtils httputils = new httpUtils();
CaseRunner runner = new CaseRunner(hjcasesrc, keyinfos, httputils, response);
runner.setRunTime(totalBatch);
Thread runnerThread = new Thread(runner);
threadPool.add(runnerThread);
}
long starttime = System.currentTimeMillis();
for (Thread worktask : threadPool) {
worktask.start();
worktask.join();
}
long endtime = System.currentTimeMillis();
float avgTPS = (float) totalBatch / ((endtime - starttime) / 1000.0f);
response.put("Comsume", endtime - starttime);
response.put("avgTPS", String.valueOf(avgTPS));
} catch (Exception e) {
e.printStackTrace();
}
return new Response(response.getResultJSON());
}Scenario cases model a series of related API calls (e.g., a user initiating a live stream connection) and enforce execution order with variable sharing. BVT case sets group related API cases for module‑level validation and can be scheduled via crontab.
Test suites allow creation, editing, ordering, and batch execution of cases, exposing endpoints such as inter/getSuiteLists , inter/getSuiteInfo , and inter/execSuiteList for external integration.
Tool management includes uploadable executable JARs and lightweight online utilities (e.g., byte‑string conversion) to aid testing efficiency.
Pressure Test Management enables defining pressure‑test scenes that bind existing API cases, configure user counts, concurrency, and execution parameters. The platform’s pressure‑test service runs on any Java‑capable server, listening for commands, spawning threads, and reporting per‑second statistics.
Listener service code example:
if(cmd.equals("TaskStart")){
int content = Integer.parseInt(params[1]);
if(CommonTaskData.getSTATE() == CommonTaskData.RUNNING || CommonTaskData.getSTATE() == CommonTaskData.PAUSE){
if(CommonTaskData.getId() == content){
CaseHelper casehelper = CaseHelper.getInstance();
StressTaskHistory taskhistory = casehelper.getTaskHistory(content);
CommonTaskData.setTask(taskhistory.parseStressTask());
System.out.println("从暂停状态中恢复~~");
for(CaseRunner runner : caseRunners){
runner.setState(CommonTaskData.RUNNING);
}
CommonTaskData.setSTATE(CommonTaskData.RUNNING);
continue;
} else {
System.out.println("不同TaskId Start ----先清理之前线程");
for(CaseRunner runner : caseRunners){
runner.setState(CommonTaskData.STOP);
}
for(Thread worktask : threadPool){
try { worktask.join(); } catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
Statistics.startSampling();
// ... prepare data and start threads
CommonTaskData.setSTATE(CommonTaskData.RUNNING);
for(int i=0;iTask handling and statistics collection are performed by CaseRunner and Statistic classes, which record request/response times, success/failure counts, and compute per‑second TPS metrics.
Future plans include deeper CI integration, full lifecycle quality management (from requirement to release), and expanding the platform’s capabilities beyond basic automation.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.