ExUnitJSON.Coverage (ex_unit_json v0.4.2)

Copy Markdown View Source

Coverage collection for ExUnitJSON.

Note: Unit tests for this module directly manipulate :cover state. They work fine with coverage OFF (default) but conflict with --cover. Run with: mix test.json test/ex_unit_json/coverage_test.exs

Provides functions to start, collect, and stop code coverage analysis using Erlang's :cover module. Outputs machine-readable coverage data that can be merged into JSON test output.

Usage

Coverage is typically managed by the mix test.json task:

# Coverage off by default (faster)
mix test.json

# Enable coverage
mix test.json --cover

Direct Usage

ExUnitJSON.Coverage.start()
# ... run tests ...
coverage = ExUnitJSON.Coverage.collect()
ExUnitJSON.Coverage.stop()

Summary

Functions

Collects coverage data from instrumented modules.

Starts cover instrumentation for local modules.

Stops cover and clears all coverage data.

Functions

collect(ignore_modules \\ [])

@spec collect(ignore_modules :: [module()]) :: map()

Collects coverage data from instrumented modules.

Returns a map with coverage statistics suitable for JSON output. Accepts an optional list of module names to ignore.

Options

  • ignore_modules - List of modules to exclude from coverage report

Return Value

%{
  "total_percentage" => 96.96,
  "total_lines" => 330,
  "covered_lines" => 320,
  "modules" => [
    %{
      "module" => "ExUnitJSON.Formatter",
      "file" => "lib/ex_unit_json/formatter.ex",
      "percentage" => 92.68,
      "uncovered_lines" => [45, 67, 89]
    }
  ]
}

start()

@spec start() :: :ok | {:error, term()}

Starts cover instrumentation for local modules.

Compiles all modules in the project for coverage analysis. Uses :cover.local_only/0 to avoid distributed coverage.

Returns :ok on success, {:error, reason} on failure.

stop()

@spec stop() :: :ok

Stops cover and clears all coverage data.

Call this after collecting coverage to clean up resources. Safe to call even if cover is not running.

Note: :cover.stop() can kill linked processes, so we run it in a separate unlinked process to avoid killing the caller.