r-lib / covr

Test coverage reports for R
https://covr.r-lib.org
Other
336 stars 117 forks source link

Test coverage for a single file #543

Open hadley opened 1 year ago

hadley commented 1 year ago

devtools::test_coverage_active_file() is proving increasingly useful in our workflow where there's (in most cases) there's a one-to-one relationship between files in R/ and in tests/testthat/. However, because covr environment_coverage() calls sys.source() rather than testthat::test_file() we have to recreate much of the test_file() infrastructure in test_coverage_active_file(). And that's fragile and continues to cause problems (see https://github.com/r-lib/devtools/pull/2537 for a recent example).

Could we have a variant of environment_coverage() (either a new argument or a new function) that'd call testthat::test_file()?

Or maybe something like this?

with_coverage <- function(code,
                          env = parent.frame(),
                          line_exclusions = NULL,
                          function_exclusions = NULL) {
  exec_env <- new.env(parent = env)
  trace_environment(env)
  on.exit({
    reset_traces()
    clear_counters()
  })
  withr::with_envvar(c(R_COVR = "true"), code)

  coverage <- as_coverage(.counters)
  exclude(
    coverage,
    line_exclusions = line_exclusions,
    function_exclusions = function_exclusions,
    path = NULL
  )
}
jimhester commented 1 year ago

I think the one tricky bit with with_coverage() as you have it is making sure that the code is executed in the execution environment that has the traces.

I tried playing around with this a bit today and wasn't able the get it working with the time I allotted to the task, I think there is a bit of a chicken and egg problem with defining the test environment and instrumenting it for coverage. If you can work out a POC that uses test_file() or with_coverage() that would fit your needs I would be happy to merge it.