Lab 1: Add JaCoCo to Maven Project โ
Objective: Configure JaCoCo for Java code coverage
Time: 25 minutes
Exercise 1.1: Configure JaCoCo Plugin
1
Open Your Maven Project
cd $env:USERPROFILE\Desktop\testing-demo\calculator
2
Update pom.xml with JaCoCo
notepad pom.xml
Add JaCoCo plugin to the <build><plugins> section:
<build>
<plugins>
<!-- Existing surefire plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- JaCoCo Coverage Plugin -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</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.70</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Save and close (Ctrl+S, Alt+F4)
3
Understanding JaCoCo Configuration
Three Executions:
prepare-agent - Sets up coverage monitoring
report - Generates coverage report after tests
check - Enforces minimum coverage (70% in this example)
4
Run Tests with Coverage
mvn clean test
[INFO] --- jacoco:0.8.11:prepare-agent (prepare-agent) @ calculator ---
[INFO] --- maven-surefire-plugin:3.0.0:test (default-test) @ calculator ---
[INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- jacoco:0.8.11:report (report) @ calculator ---
[INFO] Loading execution data file: target\jacoco.exec
[INFO] Analyzed bundle 'calculator' with 1 classes
[INFO] BUILD SUCCESS
5
View Coverage Report
start target\site\jacoco\index.html
You'll see:
- Overall coverage percentage
- Coverage per package
- Coverage per class
- Green (covered) and red (uncovered) lines
โ
Checkpoint: JaCoCo configured and coverage report generated
Lab 2: Add Coverlet to .NET Project ๐ท
Objective: Configure Coverlet for .NET code coverage
Time: 20 minutes
Exercise 2.1: Install Coverlet
1
Navigate to .NET Project
cd $env:USERPROFILE\Desktop\testing-demo\CalculatorApp
2
Add Coverlet Package
dotnet add Calculator.Tests package coverlet.collector
info : PackageReference for package 'coverlet.collector' version '6.0.0' added
info : Committing restore...
dotnet add Calculator.Tests package coverlet.msbuild
3
Run Tests with Coverage
dotnet test --collect:"XPlat Code Coverage"
Passed! - Failed: 0, Passed: 10, Skipped: 0, Total: 10, Duration: 52 ms
Attachments:
C:\...\TestResults\abc-123\coverage.cobertura.xml
4
Generate HTML Report (Optional)
dotnet tool install -g dotnet-reportgenerator-globaltool
reportgenerator `
-reports:"Calculator.Tests\TestResults\**\coverage.cobertura.xml" `
-targetdir:"coveragereport" `
-reporttypes:Html
start coveragereport\index.html
5
View Coverage Details
In the HTML report, you'll see:
- Summary: Overall coverage percentage
- Assembly: Coverage per project
- Classes: Coverage per class
- Line-by-line: Green (covered) vs Red (uncovered)
โ
Checkpoint: Coverlet configured and coverage report generated
Lab 3: Improve Code Coverage ๐
Objective: Identify and test uncovered code
Time: 35 minutes
Exercise 3.1: Add Untested Method
1
Add New Method to Calculator (Java)
notepad src\main\java\com\example\Calculator.java
Add this method (no test yet):
public int modulo(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("Cannot modulo by zero");
}
return a % b;
}
Save and close
2
Run Coverage Without Test
mvn clean test
start target\site\jacoco\index.html
Observation: Coverage will be lower because modulo() method is not tested!
3
Add Test for New Method
notepad src\test\java\com\example\CalculatorTest.java
Add these tests:
@Test
@DisplayName("Test modulo operation")
void testModulo() {
assertEquals(1, calculator.modulo(7, 3));
assertEquals(0, calculator.modulo(6, 3));
assertEquals(2, calculator.modulo(8, 3));
}
@Test
@DisplayName("Test modulo by zero throws exception")
void testModulo_ByZero_ThrowsException() {
Exception exception = assertThrows(
IllegalArgumentException.class,
() -> calculator.modulo(5, 0)
);
assertEquals("Cannot modulo by zero", exception.getMessage());
}
Save and close
4
Run Coverage Again
mvn clean test
start target\site\jacoco\index.html
Observation: Coverage increases! modulo() method now shows green (covered)
5
Analyze Coverage Report
In the HTML report:
- Click on package name โ Click on Calculator class
- See line-by-line coverage
- Green background: Line was executed by tests โ
- Red background: Line never executed โ
- Yellow background: Partial branch coverage โ ๏ธ
โ
Checkpoint: Understand how to improve coverage by adding tests
Lab 4: Add Coverage to Azure Pipeline (Maven) ๐
Objective: Publish coverage reports to Azure DevOps
Time: 35 minutes
Exercise 4.1: Update Pipeline YAML
1
Open Pipeline File
notepad azure-pipelines.yml
2
Add Coverage Publishing
Replace content with complete pipeline:
trigger:
- main
pool:
vmImage: 'windows-latest'
steps:
- task: Maven@3
displayName: 'Run Tests with Coverage'
inputs:
mavenPomFile: 'pom.xml'
goals: 'clean test'
publishJUnitResults: true
testResultsFiles: '**/surefire-reports/TEST-*.xml'
javaHomeOption: 'JDKVersion'
jdkVersionOption: '1.11'
- task: PublishCodeCoverageResults@2
displayName: 'Publish Code Coverage'
inputs:
summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/jacoco.xml'
pathToSources: '$(System.DefaultWorkingDirectory)/src/main/java'
codecoverageTool: 'JaCoCo'
failIfCoverageEmpty: true
Save and close
3
Commit and Push
git add .
git commit -m "Add JaCoCo coverage to pipeline"
git push
4
Monitor Pipeline Execution
- Go to Azure DevOps โ Pipelines
- Watch pipeline run
- See "Publish Code Coverage" task execute
- Pipeline completes successfully
5
View Coverage in Azure DevOps
- In pipeline run, click "Code Coverage" tab
- See coverage summary (e.g., 85.7%)
- View coverage per file
- Click files to see line-by-line coverage
- Green = Covered, Red = Not covered
โ
Checkpoint: Coverage reports visible in Azure DevOps
Lab 5: Add Coverage to .NET Pipeline ๐ท
Objective: Publish .NET coverage to Azure DevOps
Time: 30 minutes
Exercise 5.1: Update .NET Pipeline
1
Open Pipeline File
cd $env:USERPROFILE\Desktop\testing-demo\CalculatorApp
notepad azure-pipelines.yml
2
Complete .NET Coverage Pipeline
trigger:
- main
pool:
vmImage: 'windows-latest'
steps:
- task: DotNetCoreCLI@2
displayName: 'Restore NuGet Packages'
inputs:
command: 'restore'
- task: DotNetCoreCLI@2
displayName: 'Build Solution'
inputs:
command: 'build'
arguments: '--configuration Release'
- task: DotNetCoreCLI@2
displayName: 'Run Tests with Coverage'
inputs:
command: 'test'
projects: '**/*Tests.csproj'
arguments: '--configuration Release --collect:"XPlat Code Coverage"'
publishTestResults: true
- task: PublishCodeCoverageResults@2
displayName: 'Publish Code Coverage'
inputs:
summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'
codecoverageTool: 'Cobertura'
failIfCoverageEmpty: true
Save and close
3
Commit and Push
git add .
git commit -m "Add coverage to .NET pipeline"
git push
4
View .NET Coverage in Azure DevOps
- Pipeline runs automatically
- Click "Code Coverage" tab
- See .NET project coverage
- Drill down into assemblies and classes
โ
Checkpoint: .NET coverage integrated in pipeline
Lab 6: Enforce Coverage Thresholds ๐ฆ
Objective: Fail builds when coverage drops below threshold
Time: 25 minutes
Exercise 6.1: Set Minimum Coverage (Maven)
1
Already Configured!
In Lab 1, we added the check execution with minimum 70%:
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.70</minimum>
</limit>
2
Test Coverage Enforcement
Option A: Delete some tests to lower coverage
notepad src\test\java\com\example\CalculatorTest.java
Comment out 2-3 tests to reduce coverage below 70%
Run Maven:
mvn clean test
[ERROR] Coverage check failed:
Rule violated for bundle calculator:
lines covered ratio is 0.65, but expected minimum is 0.70
[INFO] BUILD FAILURE
3
Fix Coverage
Uncomment the tests or add more tests, then run again:
mvn clean test
[INFO] BUILD SUCCESS
Exercise 6.2: Coverage Threshold in Pipeline (Alternative)
1
Add BuildQualityChecks Task
Add after PublishCodeCoverageResults:
- task: BuildQualityChecks@8
displayName: 'Check Coverage Threshold'
inputs:
checkCoverage: true
coverageFailOption: 'build'
coverageType: 'lines'
coverageThreshold: '80'
๐ก Note: BuildQualityChecks is from marketplace extension.
JaCoCo's built-in check is simpler and recommended.
โ
Checkpoint: Coverage thresholds enforce quality standards
Lab 7: Track Coverage Trends ๐
Objective: Monitor coverage improvements over time
Time: 20 minutes
Exercise 7.1: View Coverage History
1
Access Analytics
- Go to Azure DevOps โ Pipelines
- Select your pipeline
- Click "Analytics" tab
2
View Coverage Trends
You can see:
- Coverage percentage over time (line graph)
- Increases and decreases highlighted
- Compare coverage across builds
- Identify when coverage dropped
3
Compare Build Coverage
- Click on different pipeline runs
- Compare Code Coverage tab
- See which files improved/degraded
Exercise 7.2: Gradual Coverage Improvement
1
Strategy for Legacy Code
Don't aim for 80% immediately!
Gradual approach:
- Week 1: Measure current coverage (e.g., 40%)
- Week 2: Set goal at 45%, write tests
- Week 4: Increase to 50%
- Week 8: Reach 60%
- Week 16: Target 80%
โ
Checkpoint: Understand coverage trends and improvement strategies
๐ฏ Lab Summary
What You've Accomplished:
- โ
Configured JaCoCo for Java projects
- โ
Configured Coverlet for .NET projects
- โ
Generated coverage reports locally
- โ
Published coverage to Azure DevOps
- โ
Set coverage thresholds
- โ
Viewed coverage trends
- โ
Improved coverage by adding tests
Key Concepts Mastered:
- Code Coverage: Percentage of code tested
- JaCoCo: Java coverage tool with Maven integration
- Coverlet: .NET coverage tool
- Coverage Reports: HTML, XML formats
- Thresholds: Minimum coverage enforcement
- Trends: Tracking coverage over time
Next Steps:
- ๐ Day 14: Advanced test reporting and artifacts
- ๐ฏ Aim to increase coverage to 80%+
- ๐ Review coverage reports weekly
- ๐งช Add tests for uncovered critical code
- ๐ Track coverage in team dashboards
๐ง Troubleshooting Guide
| Issue |
Solution |
| No jacoco.xml generated |
Verify JaCoCo plugin in pom.xml
Check target/site/jacoco/ directory exists
Run: mvn clean test
|
| Coverage shows 0% |
Ensure tests actually ran and passed
Check jacoco.exec file exists in target/
Verify source path is correct
|
| Coverage not in Azure DevOps |
Verify PublishCodeCoverageResults task added
Check summaryFileLocation path is correct
Ensure codecoverageTool matches (JaCoCo or Cobertura)
|
| .NET coverage file not found |
Check coverlet.collector package installed
Use: --collect:"XPlat Code Coverage"
Look in: TestResults/**/coverage.cobertura.xml
|
| Build fails on coverage check |
Coverage below minimum threshold
Add more tests or lower threshold temporarily
Review uncovered code in report
|
๐ Quick Reference Commands
Maven / JaCoCo:
mvn clean test
start target\site\jacoco\index.html
mvn clean verify
.NET / Coverlet:
dotnet test --collect:"XPlat Code Coverage"
reportgenerator `
-reports:"**/coverage.cobertura.xml" `
-targetdir:"coveragereport" `
-reporttypes:Html
start coveragereport\index.html
Coverage Files:
target\site\jacoco\index.html
target\site\jacoco\jacoco.xml
target\jacoco.exec
TestResults\{guid}\coverage.cobertura.xml
coveragereport\index.html
๐ Day 13 Labs Complete!
You've successfully implemented code coverage tracking!
Ready for Day 14: Advanced Test Reporting & Artifacts
๐ Skills Acquired:
- JaCoCo configuration and usage
- Coverlet configuration for .NET
- Coverage report generation
- Coverage publishing to Azure DevOps
- Setting and enforcing thresholds
- Coverage trend analysis