0
0
JUnittesting~15 mins

Code quality gates in JUnit - Build an Automation Script

Choose your learning style9 modes available
Verify code quality gate enforcement in build pipeline
Preconditions (3)
Step 1: Commit code with a known code smell or bug to the repository
Step 2: Trigger the build pipeline manually or via commit
Step 3: Wait for the build and code analysis to complete
Step 4: Check the build status in the pipeline dashboard
Step 5: Verify that the build fails due to code quality gate violation
Step 6: Fix the code issue and commit the corrected code
Step 7: Trigger the build pipeline again
Step 8: Verify that the build passes and quality gate is successful
✅ Expected Result: The build fails when code quality gate conditions are not met and passes after fixing issues, enforcing code quality standards automatically.
Automation Requirements - JUnit 5
Assertions Needed:
Assert that build status is 'FAILED' when code quality gate is violated
Assert that build status is 'SUCCESS' after fixing code issues
Assert that quality gate status is 'FAILED' or 'PASSED' accordingly
Best Practices:
Use API calls to trigger and check build pipeline status
Use explicit waits or retries to wait for build completion
Separate test logic from build interaction using helper methods or classes
Use clear and descriptive assertion messages
Automated Solution
JUnit
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.

Common Mistakes - 3 Pitfalls
Using fixed Thread.sleep without checking build status
Hardcoding build IDs or statuses
Not asserting HTTP response codes
Bonus Challenge

Now add data-driven testing with 3 different code commit scenarios: one with critical issues, one with minor issues, and one clean commit.

Show Hint