Coverage measurement
Skill almasumdev/awesome-mobile-testing-agent-skills/.github/skills/reports_and_ci/coverage-measurement
Agent skills for unit, widget, UI, and end-to-end testing of mobile apps across platforms.
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.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
5.3 KB, 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.