Reuse a Single Test Case for Functional, Automation, and Performance Scenarios in Java
This article demonstrates how to design a reusable Java test case that can serve functional verification, automated validation, and performance benchmarking of backend APIs, providing a complete demo with source code, test scripts, and execution guidelines.
Overview
The article demonstrates how to consolidate server‑side API interaction into a single Java wrapper so that the same logic can be reused for functional, automated, and performance testing. By exposing configurable parameters and centralising request handling, test cases become shorter, easier to maintain, and can be executed in different test pipelines without duplication.
API Wrapper – Headgear
The Headgear class extends NajmBase and encapsulates all headgear‑related endpoints:
getAllHeadgear() – GET HOST + HeadgearApiPath.GET_ALL_HEADGEAR, returns a JSONObject containing every headgear, including those off‑sale.
switchHeadgear(int hid) – POST to HOST + HeadgearApiPath.SWITCH_HEADGEAR + hid with common arguments, returns the server response.
getUserHeadgearInfo() – GET HOST + HeadgearApiPath.GET_USER_HEADGEAR, parses the JSON array DATAINFO, populates headgearInfo (a Map<Integer, Long> of headgear ID to expiration timestamp) and records the currently used headgear ID.
getOnsaleHeadgear() – GET HOST + HeadgearApiPath.GET_ONSALE_HEADGEAR, returns the list of headgear currently on sale.
getUsingHeadgearId() and getHeadgearInfo() are convenience methods that refresh user data before returning the cached values.
Instance fields: usingHeadgearId – ID of the headgear the user is wearing. headgearInfo – Map of headgear IDs to their deadlineTime.
Example of a functional loop that repeatedly purchases a random headgear until the expiration time no longer increases by one day:
public static void main(String[] args) {
int times = 0;
while (true) {
times++;
int type = 1;
int id = getRandomInt(2) == 1 ? 34 : 36;
int packageId = (id == 34) ? 56 : 60;
long deadtime1 = drive.getHeadgearInfo().get(id);
Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, 1, 1));
drive.getUserHeadgearInfo();
long deadtime2 = drive.getHeadgearInfo().get(id);
if (deadtime2 - deadtime1 != DAY) break;
}
output("Total iterations: " + times);
testOver();
}Automation Test Cases
The HeadgearCase class extends a generic SourceCode helper and defines JUnit‑style methods. Each method:
Builds a descriptive label that includes the test name and stack trace.
Calls the corresponding Headgear method.
Wraps the response in a Verify utility to assert status codes, array presence, and specific field values.
Collects the results in a JSONObject and persists them with MySqlTest.saveTestResult.
Key test cases:
testDemo001 – Verifies that getAllHeadgear() returns code 0, contains an array named heads, and includes both off‑sale and on‑sale items.
testDemo002 – Checks getOnsaleHeadgear() for code 0, presence of dataInfo array, absence of off‑sale items, and presence of description fields.
testDemo003 – Validates user headgear info: correct status, expected headgear name, wear flag "isUse":1, and package description.
testDemo004 – Simulates a purchase with insufficient balance and asserts that the server returns error code 35.
testDemo005 – Performs a normal purchase, then checks that the response code is 0, the returned deadlineTime matches the updated value, the expiration date increased by one day, and the user balance decreased by one unit.
testDemo006 – Switches the user’s headgear and asserts that the switch succeeded (the new ID matches the expected one).
public void testDemo005() {
String label = "Normal purchase" + TAB + Thread.currentThread().getStackTrace()[1];
int type = 1;
int id = getRandomInt(2) == 1 ? 34 : 36;
int packageId = (id == 34) ? 56 : 60;
int balanceBefore = NajmBase.getUserBalance(drive.user_id);
long deadtime1 = drive.getHeadgearInfo().get(id);
Verify verify = new Verify(new MallBase(base).buy(type, id, packageId, 1, 1));
drive.getUserHeadgearInfo();
long deadtime2 = drive.getHeadgearInfo().get(id);
int balanceAfter = NajmBase.getUserBalance(drive.user_id);
JSONObject result = new JSONObject();
result.put("codeZero", verify.isRight());
result.put("deadlineCorrect", (deadtime2 + EMPTY).equals(verify.getValue("deadlineTime")));
result.put("deadlineIncreased", deadtime2 - deadtime1 == DAY);
result.put("balanceReduced", balanceBefore - balanceAfter == 1);
MySqlTest.saveTestResult(label, result);
}Performance Test Example
A Groovy script CancelReason demonstrates how to reuse the same API wrapper for load testing. The script:
Parses command‑line arguments to obtain thread count and request repetitions.
Creates a Headgear instance using the shared Base configuration.
Calls drive.getAllHeadgear() once to capture the underlying HttpRequestBase object via FanLibrary.getLastRequest().
Wraps the request in a RequestThreadTimes object that repeats the request the specified number of times.
Starts a Concurrent runner with the desired number of threads.
class CancelReason extends OkayBase {
public static void main(String[] args) {
def argsUtil = new ArgsUtil(args)
def thread = argsUtil.getIntOrdefault(0, 2)
def times = argsUtil.getIntOrdefault(1, 5)
def base = getBase()
Headgear drive = new Headgear(base)
drive.getAllHeadgear()
def request = FanLibrary.getLastRequest()
def timesthread = new RequestThreadTimes(request, times)
new Concurrent(timesthread, thread, "Get all headgear – load test").start()
allOver()
}
}Running the script locally or on a CI server is as simple as:
groovy CancelReason.groovy -t 4 -n 100The project is stored in a Git repository; functional tests run on a developer machine, while automation and performance suites are executed on a dedicated server using the same wrapper code. Automation jobs can be scheduled at fixed intervals, and performance tests are triggered on demand via the Groovy command shown above.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
