Skip to content

Coverage

Jordan Samhi edited this page Oct 23, 2026 · 1 revision

Coverage compares the probes observed in a runtime log with the probes expected from the original APK and selected scope. It measures what the supplied execution recorded.

Select the measurements

Option Unit counted
-c Distinct classes with a matching class observation
-m Distinct methods with a matching method observation
-s Distinct eligible Jimple statements with a matching statement observation
-cp Distinct activities, services, broadcast receivers, and content providers with matching component observations
-mc Call relationships; this is separate from coverage percentages

Select the same options when instrumenting and reporting. Class and component counts use their own observations; enabling statement coverage does not implicitly enable the other categories. Component totals are derived from selected APK code and its component types, rather than simply counting manifest entries.

For each selected coverage category:

coverage = distinct observed probes / baseline probes in the selected scope

Repeated execution of the same probe does not increase coverage. A zero denominator is displayed as n/a in the terminal; the established JSON format uses "0.0%".

Statement coverage

The report displays Jimple, Soot's intermediate representation of APK bytecode. One Java or Kotlin source line can correspond to several Jimple statements. The displayed listing numbers are not original source-line numbers.

A statement probe is inserted before the eligible statement. For example:

int result = numerator / denominator;

If execution reaches the corresponding division with a zero denominator, its probe can be recorded even though the division throws. Covered means reached, not completed successfully.

The same rule applies to conditional branches, unconditional jumps, switch statements, loop conditions, and explicit throws. Instrumentation redirects incoming control flow through the destination probe. This measures statement arrival; it does not distinguish every branch outcome or path.

Exclusions

These Jimple statement types are excluded from the statement denominator:

Statement type Examples
Identity statements Parameter binding, this, caught-exception binding
Returns Return with a value or return without a value
Monitor statements Monitor entry and exit used for synchronization

AndroLog's runtime helpers are excluded from its statement instrumentation. Framework and native method bodies outside the APK are not instrumented by this workflow.

Read the code colors

State Meaning
Covered A matching probe record was found
Not observed A baseline probe exists, but no matching record was found
Excluded The statement is excluded from measurement
Not measured Statement coverage was not enabled, or no matching baseline probe exists

Not observed does not prove that code is unreachable or never executed. The test may not have exercised it, logging may have started too late, or records may be missing. Check the troubleshooting guide before interpreting unexpected gaps.

Choose a meaningful scope

Bundled APK libraries are included by default. -n excludes libraries recognized by the library classifier. -pkg com.example.app selects classes by package prefix. It does not automatically discover all code belonging to an application, particularly after obfuscation.

Scope changes both the denominator and the inserted probes. Compare runs only when their APK versions, probes, and scope agree. An Android component outside the chosen scope will not contribute to its totals.

Cumulative coverage

Use -pam instead of -pa to group newly observed probes by minute and accumulate their coverage. --capture includes this timeline automatically. The timeline is not a count of method invocations or statement executions per minute.

Use ordinary adb logcat -v threadtime timestamps. The current minute extractor expects MM-DD HH:mm at the beginning of the line. Year-prefixed logs can contribute to aggregate coverage but do not populate minute buckets. Preserve chronological order for a meaningful first-observation timeline; see JSON and Logs.

Older instrumented APKs

Older AndroLog instrumentation placed statement probes after statements, which could miss observations around control transfers and exceptions. Existing logs remain readable, but regenerating HTML alone cannot repair those missing observations. Reinstrument the original APK and capture a new execution to use the current before-statement behavior.

Clone this wiki locally