Coverage measurement
Skill almasumdev/awesome-mobile-testing-agent-skills/.github/skills/reports_and_ci/coverage-measurement
Measure code coverage honestly across mobile stacks — JaCoCo (JVM), llvm-cov (iOS), lcov (Flutter), Jest (RN) — and report it to Codecov / Coveralls without chasing meaningless numbers. Use when setting up coverage or when asked to raise a coverage gate.From its SKILL.md
npx -y skills add almasumdev/awesome-mobile-testing-agent-skills --skill coverage-measurementAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.3 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Coverage Measurement
Instructions
Coverage is a trend, not a target number. A 90 % line-coverage suite full of assertion-free smoke tests is worse than a 60 % suite with sharp, behavior-focused tests. Measure coverage, publish the trend, let engineers see gaps — but do not weaponize a single percentage as a gate.
1. What Coverage Actually Tells You
- Line / statement coverage — did each line execute? Cheap, widely supported, easy to fake.
- Branch coverage — did both sides of each conditional execute? More signal than line coverage.
- Modified-lines coverage (diff coverage) — of the lines this PR changed, what % is now covered? The single most useful metric for PR review.
Prefer branch + diff coverage over a single total-line percentage.
2. Android / Kotlin — JaCoCo
plugins { id 'jacoco' }
jacoco { toolVersion = '0.8.12' }
tasks.register('jacocoTestReport', JacocoReport) {
dependsOn 'testDebugUnitTest'
reports { xml.required = true; html.required = true }
sourceDirectories.setFrom(files(['src/main/java', 'src/main/kotlin']))
classDirectories.setFrom(files([
fileTree(dir: "$buildDir/tmp/kotlin-classes/debug", excludes: [
'**/R.class','**/R$*.class','**/BuildConfig.*','**/*_Factory*','**/Hilt_*'
])
]))
executionData.setFrom(fileTree(dir: buildDir, includes: ['**/*.exec','**/*.ec']))
}
For instrumented tests, add debug { testCoverageEnabled true } and merge .ec + .exec in the same report.
3. iOS — llvm-cov / xccov
Enable in the test scheme: Test → Options → Code Coverage.
Extract from .xcresult in CI:
xcrun xccov view --report --json DerivedData/Build/Logs/Test/<uuid>.xcresult > coverage.json
Convert to lcov for Codecov:
xcresultparser --output-format cobertura *.xcresult > coverage.xml
Exclude generated sources (Mock files, *.pbobjc.*, *.swift-generated.*) via .codecov.yml.
4. Flutter / Dart — lcov
flutter test --coverage
genhtml coverage/lcov.info -o coverage/html
Filter out generated files:
lcov --remove coverage/lcov.info \
'*/generated/*' '*.g.dart' '*.freezed.dart' '*.mocks.dart' \
-o coverage/lcov.info
5. React Native — Jest
// package.json
"scripts": { "test:coverage": "jest --coverage" },
"jest": {
"coverageReporters": ["lcov", "text-summary", "cobertura"],
"collectCoverageFrom": [
"src/**/*.{ts,tsx}",
"!src/**/*.d.ts",
"!src/**/__generated__/**"
]
}
6. Publishing
- Codecov — the
codecov/codecov-action@v4uploader handles lcov, cobertura, and jacoco XML. - Coveralls — similar; pick one, not both.
- Upload after every test job; distinguish unit, integration, and UI coverage with the
flags:feature so each layer's contribution is visible.
.codecov.yml sketch:
coverage:
status:
project:
default:
target: auto
threshold: 0.5% # allow small drops, forbid big ones
patch:
default:
target: 80% # diff-coverage gate
ignore:
- "**/generated/**"
- "**/*.g.dart"
- "**/*Tests*/**"
7. Exclusions — The Honest List
Exclude from coverage (via tool config, not via @SuppressLint):
- Generated code (Dagger/Hilt, KSP,
freezed, protobuf, Moshi adapters). data classauto-generated methods.- Trivial view bindings (
onClick { callback() }). - Main entry points (
main(),AppDelegateboot,App.tsxroot).
Do not exclude your own untested code to make the number look better. That is fraud against your future self.
8. Diff Coverage in PRs
Show diff coverage prominently on PRs. A PR that drops project coverage by 0.1 % but has 95 % coverage on the lines it changed is healthy. A PR with 100 % project coverage and 0 % diff coverage is adding dead weight.
9. Coverage Is Not Quality
Covered lines with no assertions are worthless. Run mutation testing occasionally to sanity-check assertion strength:
- Kotlin:
pitestviainfo.solidsoft.pitestplugin. - Dart:
mutation_testorgutenberg. - TS:
stryker-mutator.
Mutation scores of 70 %+ on core logic are a stronger signal than any line-coverage number.
10. Honest Goals
Good guidance to post in your repo:
- New files: aim for high diff coverage on business logic; UI glue can be lower.
- Overall trend: never regress for two consecutive releases without a written reason.
- Branch coverage on core modules (state machines, pricing, auth): > 80 %.
- Everything else: track, do not gate.
11. Checklist
- Coverage is captured for unit, integration, and UI layers separately and flagged in Codecov.
- Diff coverage is shown on every PR.
- Generated files are excluded at the tooling layer, not by tagging real code.
- No absolute project percentage is used as a blocking gate.
- Branch coverage is tracked for core modules, not just line coverage.
- Mutation testing runs at least nightly on critical packages.
- Coverage trend is reviewed in release retros.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.