# Test Coverage Threshold Not Met
Introduction
This article covers troubleshooting steps and solutions for Test Coverage Threshold Not Met. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.
Symptoms
Common error messages include:
Coverage threshold not met. Lines: 75% (required: 80%)ERROR: Coverage check failed: Coverage is below minimum thresholdOverall line coverage: 72.5% (threshold: 80%)
ERROR: Quality gate failedCommon Causes
- Configuration misconfiguration
- Missing or incorrect credentials
- Network connectivity issues
- Version compatibility problems
- Resource exhaustion or limits
- Permission or access denied
Step-by-Step Fix
Common Error Patterns
Test coverage failures typically show:
Coverage threshold not met. Lines: 75% (required: 80%)ERROR: Coverage check failed: Coverage is below minimum thresholdOverall line coverage: 72.5% (threshold: 80%)
ERROR: Quality gate failedCoverage threshold violation: 50% < 80% minimumRoot Causes and Solutions
1. Insufficient Test Coverage
Not enough tests covering application code.
Solution:
Identify uncovered code:
```bash # Generate coverage report npm test -- --coverage
# View detailed report cat coverage/lcov-report/index.html
# For Jest jest --coverage --coverageDirectory=coverage
# For Python pytest --cov=src --cov-report=html coverage report -m ```
Focus on critical paths:
```bash # Check specific file coverage jest --coverage --collectCoverageFrom='src/utils/**' src/utils/test.ts
# Coverage for specific functions coverage report -m --include=src/main.py ```
Write tests for uncovered areas:
```javascript // Example: Testing uncovered utility function describe('formatDate', () => { it('should format date correctly', () => { expect(formatDate('2024-01-01')).toBe('January 1, 2024'); });
it('should handle invalid input', () => { expect(formatDate(null)).toBe('Invalid date'); }); }); ```
2. Coverage Configuration Incorrect
Coverage threshold configuration is wrong.
Solution:
Configure coverage thresholds:
// jest.config.json
{
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
},
"./src/utils/": {
"branches": 100,
"functions": 100,
"lines": 100
}
}
}For package.json:
{
"jest": {
"coverageThreshold": {
"global": {
"lines": 80
}
}
}
}For Istanbul/nyc:
// .nycrc
{
"check-coverage": true,
"lines": 80,
"branches": 80,
"functions": 80,
"statements": 80
}For Python pytest-cov:
```toml # pyproject.toml [tool.pytest.ini_options] addopts = "--cov --cov-fail-under=80"
[tool.coverage.run] source = ["src"]
[tool.coverage.report] fail_under = 80 ```
3. Coverage Exclusions Not Applied
Generated or external code counted in coverage.
Solution:
Exclude unnecessary files:
// jest.config.json
{
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts",
"!src/**/__tests__/**",
"!src/**/__mocks__/**",
"!src/**/index.ts",
"!src/types/**"
]
}For Istanbul/nyc:
// .nycrc
{
"include": ["src/**"],
"exclude": [
"src/**/*.d.ts",
"src/**/__tests__/**",
"src/types/**"
]
}For Python:
# pyproject.toml
[tool.coverage.omit]
paths = [
"*/tests/*",
"*/__init__.py",
"*/migrations/*"
]4. Coverage Tool Mismatch
Different coverage tools producing different results.
Solution:
Use consistent coverage tool:
```yaml # GitHub Actions - name: Run tests with coverage run: npm test -- --coverage --coverageReporters=json-summary
- name: Check coverage threshold
- run: |
- COVERAGE=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
- if [ "$COVERAGE" -lt 80 ]; then
- echo "Coverage $COVERAGE% is below threshold 80%"
- exit 1
- fi
`
For multiple reporters:
// jest.config.json
{
"coverageReporters": ["text", "lcov", "json-summary", "html"]
}5. CI Configuration Not Running Coverage
CI pipeline skips coverage step.
Solution:
Add coverage step to CI:
```yaml # GitHub Actions - name: Run tests run: npm test
- name: Generate coverage
- run: npm test -- --coverage
- name: Upload coverage
- uses: codecov/codecov-action@v4
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
- fail_ci_if_error: true
`
For GitLab CI:
test:
script:
- npm install
- npm test -- --coverage
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'For Jenkins:
stage('Test') {
steps {
sh 'npm test -- --coverage'
}
post {
always {
publishHTML target: [
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'coverage',
reportFiles: 'index.html',
reportName: 'Coverage Report'
]
}
}
}6. External Coverage Service Integration
Codecov/Coveralls integration failing.
Solution:
For Codecov:
# GitHub Actions
- name: Upload to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: true
verbose: trueFor Coveralls:
- name: Coveralls
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}Configure Codecov yaml:
```yaml # codecov.yml coverage: status: project: default: target: 80% threshold: 5% patch: default: target: 80%
ignore: - "src/types/**" - "**/*.d.ts" - "/__tests__/" ```
7. Coverage History/Delta Issues
Coverage decreased from previous commit.
Solution:
Configure coverage delta rules:
# codecov.yml
coverage:
status:
project:
default:
target: auto # Compare against previous commit
threshold: 5% # Allow 5% decreaseTrack coverage history:
```yaml # GitHub Actions - store coverage artifacts - name: Upload coverage artifact uses: actions/upload-artifact@v4 with: name: coverage-report path: coverage/
- name: Download previous coverage
- uses: actions/download-artifact@v4
- with:
- name: coverage-report
- path: previous-coverage/
`
8. Flaky Tests Affecting Coverage
Tests pass/fail inconsistently, affecting coverage.
Solution:
Detect flaky tests:
```bash # Run tests multiple times npm test -- --coverage --runInBand --detectOpenHandles
# Jest detect flaky tests jest --coverage --forceExit --detectOpenHandles ```
Exclude flaky tests:
// jest.config.json
{
"testPathIgnorePatterns": [
"/node_modules/",
"<rootDir>/src/flaky/"
]
}Coverage Tools Configuration
Jest Coverage
{
"jest": {
"collectCoverage": true,
"coverageDirectory": "coverage",
"coverageReporters": ["text", "lcov", "json"],
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": -10 # Allow 10 uncovered lines
}
},
"collectCoverageFrom": [
"src/**/*.{js,ts}",
"!src/**/*.d.ts"
]
}
}Istanbul/nyc Coverage
{
"nyc": {
"check-coverage": true,
"lines": 80,
"statements": 80,
"functions": 80,
"branches": 80,
"reporter": ["lcov", "text", "html"],
"exclude": ["test/**", "coverage/**"]
}
}pytest-cov Coverage
```toml [tool.pytest.ini_options] addopts = [ "--cov=src", "--cov-report=term-missing", "--cov-report=html", "--cov-fail-under=80" ]
[tool.coverage.run] branch = true source = ["src"] omit = ["tests/*", "*/__init__.py"]
[tool.coverage.report] show_missing = true fail_under = 80 ```
JaCoCo Coverage (Java)
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>Debugging Commands
```bash # Jest verbose coverage jest --coverage --verbose --debug
# Show uncovered lines jest --coverage --coverageReporters=text
# Coverage for specific file jest --coverage --collectCoverageFrom='src/file.ts' src/file.test.ts
# Istanbul detailed report nyc report --reporter=text
# Python coverage details coverage report -m --sort=cover coverage html open htmlcov/index.html
# Maven coverage report mvn jacoco:report ```
Verification
| Coverage Type | Target | Config |
|---|---|---|
| Lines | 80% | lines: 80 |
| Branches | 70-80% | branches: 80 |
| Functions | 80% | functions: 80 |
| Statements | 80% | statements: 80 |
Prevention
- 1.Set realistic coverage thresholds
- 2.Exclude generated/config files from coverage
- 3.Use coverage reporters for detailed reports
- 4.Track coverage history with services like Codecov
- 5.Set up coverage badges for visibility
- 6.Add coverage checks to PR requirements
Related Articles
- [GitHub Actions Workflow Failed](#)
- [Jenkins Build Failed](#)
- [NPM Install Failed in CI](#)
Related Articles
- [Technical troubleshooting: Fix Cicd Artifact Upload Failed Storage Issue in C](cicd-artifact-upload-failed-storage)
- [Technical troubleshooting: Fix Cicd Code Quality Gate Failed Sonarqube Issue ](cicd-code-quality-gate-failed-sonarqube)
- [Technical troubleshooting: Fix Cicd Deployment Failed Health Check Issue in C](cicd-deployment-failed-health-check)
- [Technical troubleshooting: Fix Cicd Github Actions Workflow Queue Timeout in ](cicd-github-actions-workflow-queue-timeout)
- [Technical troubleshooting: Fix Cicd Gitlab Runner Stuck Pending Issue in CI/C](cicd-gitlab-runner-stuck-pending)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Test Coverage Threshold Not Met", "description": "Resolve test coverage threshold failures in CI. Covers configuration, coverage tools, exclusion patterns, and reporting solutions.", "url": "https://www.fixwikihub.com/fix-cicd-test-coverage-threshold-not-met", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-20T19:08:42.807Z", "dateModified": "2025-11-20T19:08:42.807Z" } </script>