CI/CD

How to Set Up CI/CD Quality Gates (Selenium + Jenkins Guide)

18 March 20267 min readBy Assurix QA Team

A CI/CD quality gate is a defined threshold — test pass rate, code coverage percentage, zero critical security findings — that a build must satisfy before it proceeds to the next pipeline stage. Failing a quality gate stops a broken build from reaching staging or production.

Quality gates are one of the most effective shift-left testing mechanisms available. They move the consequence of a failing test from "production incident discovered by a customer" to "blocked pipeline caught during development."

What makes a good quality gate?

A quality gate should be:

  • Measurable. A pass/fail outcome based on a specific numeric threshold, not a subjective review.
  • Blocking. The pipeline stops if the gate fails. A gate that can be bypassed is not a gate.
  • Proportionate. Set thresholds that catch real regressions, not thresholds so strict that every minor change triggers a failure. Start conservative and tighten over time.
  • Fast. Gates that take 45 minutes to run will be skipped. Aim for smoke test gates under 10 minutes on every PR.

Setting up a quality gate in Jenkins with Selenium

Step 1: Configure your Selenium test suite to output JUnit XML

Jenkins reads test results from JUnit-format XML files. Configure your test runner to produce this output:

# Maven + TestNG example
mvn test -Dsurefire.useFile=true

TestNG and JUnit both produce compatible XML output by default when run via Maven Surefire. Ensure your test output path is consistent — typically target/surefire-reports/.

Step 2: Add the JUnit plugin to Jenkins

In your Jenkinsfile, add a post-build step to publish test results:

post {
  always {
    junit 'target/surefire-reports/**/*.xml'
  }
}

Step 3: Set a quality gate threshold

Use the Jenkins JUnit plugin's built-in threshold configuration, or write a script stage that reads the XML and fails the build if pass rate drops below your threshold:

stage('Quality Gate') {
  steps {
    script {
      def testResults = junit testResults: 'target/surefire-reports/**/*.xml'
      def passRate = (testResults.passCount / testResults.totalCount) * 100
      if (passRate < 95) {
        error "Quality gate failed: pass rate ${passRate}% is below threshold of 95%"
      }
    }
  }
}

Step 4: Add the SonarQube quality gate (optional but recommended)

If you use SonarQube for static analysis, the SonarQube Jenkins plugin adds a native quality gate step:

stage('SonarQube Analysis') {
  steps {
    withSonarQubeEnv('SonarQube') {
      sh 'mvn sonar:sonar'
    }
  }
}
stage('Quality Gate') {
  steps {
    timeout(time: 5, unit: 'MINUTES') {
      waitForQualityGate abortPipeline: true
    }
  }
}

Setting up quality gates in GitHub Actions

For teams using GitHub Actions instead of Jenkins, the same pattern applies with different syntax:

- name: Run Selenium tests
  run: mvn test

- name: Check quality gate
  run: |
    PASS=$(grep -o 'tests="[0-9]*"' target/surefire-reports/*.xml | awk -F'"' '{sum+=$2} END{print sum}')
    FAIL=$(grep -o 'failures="[0-9]*"' target/surefire-reports/*.xml | awk -F'"' '{sum+=$2} END{print sum}')
    RATE=$(echo "scale=2; ($PASS - $FAIL) * 100 / $PASS" | bc)
    if (( $(echo "$RATE < 95" | bc -l) )); then
      echo "Quality gate failed: pass rate $RATE%"
      exit 1
    fi

What thresholds should you set?

Recommended starting thresholds for most SaaS teams:

  • Smoke test pass rate: 100% — if any critical path test fails, block the build
  • Full regression pass rate: 95% — allows for known flaky tests while blocking genuine regressions
  • Code coverage (if tracked): no drop of more than 2% from baseline per PR
  • Critical security findings: 0 — any critical SAST finding blocks the build

Start loose. A gate that blocks too many valid builds will be disabled by developers within a week. Start at 90% pass rate, fix flaky tests systematically, then tighten to 95% and eventually 98%.

Common pitfalls

  • Flaky tests defeating the gate. If 5% of your tests fail randomly, a 95% gate will block every build. Fix flaky tests before raising thresholds — or tag flaky tests and exclude them from gate calculations until fixed.
  • Gates on main only. Quality gates on main are too late. Gate on every PR branch so failures are caught before merge, not after.
  • No visibility. If developers don't see gate results clearly in their PR, they won't learn from failures. Ensure Jenkins or GitHub Actions surfaces the failure reason prominently.

Frequently Asked Questions

Should quality gates run on every commit or only on PRs?

At minimum, run quality gates on every PR merge attempt. For fast smoke tests (under 5 minutes), consider running on every push to a feature branch as well — earlier feedback shortens fix time.

How do quality gates work with parallel test execution?

Parallel execution reduces gate runtime significantly. In Jenkins, use the parallel step with multiple agents. In GitHub Actions, use a matrix strategy. Aggregate results into a single JUnit XML before the gate step.

Setting up quality gates is one of the fastest ROI improvements available to a QA programme. If you'd like Assurix to audit your current pipeline and recommend specific gate configurations for your stack, learn about our CI/CD integration service or talk to a QA lead directly.

Ready to improve your release quality?

Assurix embeds dedicated QA engineers into SaaS, fintech, and healthtech teams. Start in 2–3 weeks.

Talk to an Assurix QA lead →