Bird
Raised Fist0
JUnittesting~15 mins

Code quality gates in JUnit - Build an Automation Script

Choose your learning style10 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

Practice

(1/5)
1. What is the main purpose of a code quality gate in a JUnit testing process?
easy
A. To check if the code meets predefined quality standards before merging
B. To automatically deploy code to production
C. To write new JUnit test cases
D. To format the source code automatically

Solution

  1. 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.
  2. 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.
  3. Final Answer:

    To check if the code meets predefined quality standards before merging -> Option A
  4. Quick Check:

    Quality gate purpose = Check code quality before merge [OK]
Hint: Quality gates stop bad code before merge [OK]
Common Mistakes:
  • Confusing quality gates with deployment steps
  • Thinking quality gates write tests automatically
  • Assuming quality gates only format code
2. Which of the following is the correct way to assert that two values are equal in a JUnit 5 test?
easy
A. assertEqual(expected, actual);
B. assertEquals(expected, actual);
C. assertEquals(actual, expected);
D. assertEqual(actual, expected);

Solution

  1. Step 1: Recall JUnit 5 assertion syntax

    The correct method to check equality is assertEquals(expected, actual); with the expected value first.
  2. Step 2: Check method names and parameter order

    Method name must be assertEquals (not assertEqual) and parameters order matters: expected first, actual second.
  3. Final Answer:

    assertEquals(expected, actual); -> Option B
  4. Quick Check:

    assertEquals(expected, actual) is correct [OK]
Hint: Use assertEquals(expected, actual) exactly [OK]
Common Mistakes:
  • Using assertEqual instead of assertEquals
  • Swapping expected and actual parameters
  • Missing parentheses or semicolons
3. Given the following JUnit test snippet, what will be the test result if calculateSum(2, 3) returns 6?
import static org.junit.jupiter.api.Assertions.assertEquals;

@Test
void testSum() {
    assertEquals(5, calculateSum(2, 3));
}
medium
A. Test fails with assertion error
B. Test is skipped
C. Test throws a compilation error
D. Test passes

Solution

  1. Step 1: Understand the assertion

    The test expects calculateSum(2, 3) to return 5, but it returns 6 instead.
  2. 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.
  3. Final Answer:

    Test fails with assertion error -> Option A
  4. Quick Check:

    Expected != Actual causes failure [OK]
Hint: Mismatch expected vs actual fails test [OK]
Common Mistakes:
  • Assuming test passes if values differ
  • Thinking compilation error occurs
  • Believing test is skipped automatically
4. Identify the error in this JUnit 5 test method that prevents the quality gate from passing:
@Test
void testIsPositive() {
    int number = -1;
    assertTrue(number > 0);
}
medium
A. The test method name must start with 'test'
B. The test method is missing the @BeforeEach annotation
C. The assertion condition is incorrect for the test data
D. assertTrue is not a valid JUnit assertion

Solution

  1. Step 1: Analyze the assertion condition

    The test asserts that number > 0 but number is -1, so the condition is false.
  2. Step 2: Understand test failure impact on quality gate

    Because the assertion fails, the test fails and the quality gate will not pass.
  3. Final Answer:

    The assertion condition is incorrect for the test data -> Option C
  4. Quick Check:

    Assertion false causes test failure [OK]
Hint: Check if assertion matches test data truth [OK]
Common Mistakes:
  • Thinking @BeforeEach is required for this test
  • Believing method name must start with 'test'
  • Assuming assertTrue is invalid in JUnit
5. In a continuous integration pipeline using JUnit tests and a code quality gate, which combination best ensures that only well-tested code is merged?
  • 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
hard
A. 2 and 4 only
B. 1 and 4 only
C. All 1, 2, 3, and 4
D. 1, 2, and 3 only

Solution

  1. Step 1: Identify essential quality gate criteria

    Tests passing, high code coverage, and no critical bugs are key to ensuring code quality before merge.
  2. Step 2: Evaluate code formatting importance

    Ignoring code formatting (point 4) can reduce code quality and maintainability, so it should not be ignored.
  3. Final Answer:

    1, 2, and 3 only -> Option D
  4. Quick Check:

    Pass tests + coverage + no bugs = good quality gate [OK]
Hint: Include tests, coverage, and bug checks for quality [OK]
Common Mistakes:
  • Ignoring code formatting importance
  • Assuming only tests passing is enough
  • Thinking code coverage below 80% is acceptable
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard