Code quality gates in JUnit - Build an Automation Script
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.URI; import java.time.Duration; public class CodeQualityGateTest { private static final String BUILD_TRIGGER_URL = "https://ci.example.com/api/build/trigger"; private static final String BUILD_STATUS_URL = "https://ci.example.com/api/build/status"; private static final HttpClient client = HttpClient.newHttpClient(); private String triggerBuild() throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(BUILD_TRIGGER_URL)) .POST(HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); assertEquals(200, response.statusCode(), "Build trigger request failed"); // Assume response body contains build ID return response.body(); } private String waitForBuildCompletion(String buildId) throws Exception { String status = "IN_PROGRESS"; int retries = 30; while (retries-- > 0 && status.equals("IN_PROGRESS")) { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(BUILD_STATUS_URL + "?id=" + buildId)) .GET() .build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); assertEquals(200, response.statusCode(), "Failed to get build status"); status = parseStatusFromResponse(response.body()); if (status.equals("IN_PROGRESS")) { Thread.sleep(5000); // wait 5 seconds before retry } } return status; } private String parseStatusFromResponse(String responseBody) { // Simplified parsing assuming JSON like {"status":"FAILED"} if (responseBody.contains("FAILED")) return "FAILED"; if (responseBody.contains("SUCCESS")) return "SUCCESS"; return "IN_PROGRESS"; } @Test public void testBuildFailsOnQualityGateViolation() throws Exception { // Step 1: Commit code with issue is assumed done manually or by separate process // Step 2: Trigger build String buildId = triggerBuild(); // Step 3 & 4: Wait for build completion and get status String status = waitForBuildCompletion(buildId); // Step 5: Assert build failed due to quality gate assertEquals("FAILED", status, "Build should fail due to code quality gate violation"); } @Test public void testBuildPassesAfterFixingIssues() throws Exception { // Step 6: Fix code issues assumed done manually or by separate process // Step 7: Trigger build again String buildId = triggerBuild(); // Step 8: Wait for build completion and get status String status = waitForBuildCompletion(buildId); // Assert build passes assertEquals("SUCCESS", status, "Build should pass after fixing code quality issues"); } }
This test class uses JUnit 5 to automate verification of code quality gates in a build pipeline.
The triggerBuild() method sends an HTTP POST request to start a build and returns the build ID. It asserts the trigger request succeeds.
The waitForBuildCompletion() method polls the build status endpoint every 5 seconds up to 30 times (about 2.5 minutes) until the build finishes with either FAILED or SUCCESS. It asserts each status request succeeds.
The testBuildFailsOnQualityGateViolation() test assumes a commit with code issues was made. It triggers the build, waits for completion, and asserts the build status is FAILED, indicating the quality gate blocked the build.
The testBuildPassesAfterFixingIssues() test assumes the code issues were fixed. It triggers the build again, waits for completion, and asserts the build status is SUCCESS, showing the quality gate passed.
This approach uses clear separation of concerns, explicit waits, and meaningful assertions to ensure reliable and readable tests.
Now add data-driven testing with 3 different code commit scenarios: one with critical issues, one with minor issues, and one clean commit.
Practice
code quality gate in a JUnit testing process?Solution
Step 1: Understand the role of quality gates
Quality gates are checkpoints that verify if code meets certain quality criteria before it is merged into the main branch.Step 2: Relate to JUnit testing
JUnit tests provide results that quality gates use to decide if the code passes or fails the quality standards.Final Answer:
To check if the code meets predefined quality standards before merging -> Option AQuick Check:
Quality gate purpose = Check code quality before merge [OK]
- Confusing quality gates with deployment steps
- Thinking quality gates write tests automatically
- Assuming quality gates only format code
Solution
Step 1: Recall JUnit 5 assertion syntax
The correct method to check equality isassertEquals(expected, actual);with the expected value first.Step 2: Check method names and parameter order
Method name must beassertEquals(notassertEqual) and parameters order matters: expected first, actual second.Final Answer:
assertEquals(expected, actual); -> Option BQuick Check:
assertEquals(expected, actual) is correct [OK]
- Using assertEqual instead of assertEquals
- Swapping expected and actual parameters
- Missing parentheses or semicolons
calculateSum(2, 3) returns 6?import static org.junit.jupiter.api.Assertions.assertEquals;
@Test
void testSum() {
assertEquals(5, calculateSum(2, 3));
}Solution
Step 1: Understand the assertion
The test expectscalculateSum(2, 3)to return 5, but it returns 6 instead.Step 2: Determine test outcome
Since the actual value (6) does not match the expected value (5), the assertion fails and the test fails with an assertion error.Final Answer:
Test fails with assertion error -> Option AQuick Check:
Expected != Actual causes failure [OK]
- Assuming test passes if values differ
- Thinking compilation error occurs
- Believing test is skipped automatically
@Test
void testIsPositive() {
int number = -1;
assertTrue(number > 0);
}Solution
Step 1: Analyze the assertion condition
The test asserts thatnumber > 0butnumberis -1, so the condition is false.Step 2: Understand test failure impact on quality gate
Because the assertion fails, the test fails and the quality gate will not pass.Final Answer:
The assertion condition is incorrect for the test data -> Option CQuick Check:
Assertion false causes test failure [OK]
- Thinking @BeforeEach is required for this test
- Believing method name must start with 'test'
- Assuming assertTrue is invalid in JUnit
- 1. All tests must pass
- 2. Code coverage must be above 80%
- 3. No critical bugs reported by static analysis
- 4. Code formatting checks are ignored
Solution
Step 1: Identify essential quality gate criteria
Tests passing, high code coverage, and no critical bugs are key to ensuring code quality before merge.Step 2: Evaluate code formatting importance
Ignoring code formatting (point 4) can reduce code quality and maintainability, so it should not be ignored.Final Answer:
1, 2, and 3 only -> Option DQuick Check:
Pass tests + coverage + no bugs = good quality gate [OK]
- Ignoring code formatting importance
- Assuming only tests passing is enough
- Thinking code coverage below 80% is acceptable
Ready to prove it?
Pass the test and this pattern moves unknown
