Search code examples
rr-packagetestthat

How can I apply a testthat test to all functions in my package that match a certain naming pattern?


I have a package that contains a number of functions that are named viz_foo(), viz_bar() and so on.

I want to test that each of these functions produces an object of class gg. This would be simple with two functions, as in:

testthat::test_that("viz_ functions produce a plot", {
    testthat::expect_s3_class(viz_foo(), "gg")
    testthat::expect_s3_class(viz_bar(), "gg")
})

But in practice I have many functions with this naming convention, and new functions are added all the time by package contributors. I want to make sure that any new functions are tested in this way, without having to explicitly add them to the unit test.

The janky way I had thought to deal with this was:

testthat::test_that("viz_ funcs produce a plot", {
  viz_funcs <- ls("package:mypackage", pattern = "viz_")
  
  eval_func <- function(func_name) {
    suppressMessages(
      eval(str2lang(paste0(func_name, "()")))
    )
  }
  
  plots <- lapply(viz_funcs, eval_func)
  
  lapply(plots, testthat::expect_s3_class, "gg")
  
})

This works when running the test with devtools::test() but not in R CMD check.

Is there a way to apply a test to all functions within a package that contain a certain pattern in their name?


Solution

  • getNamespaceExports may be a more suitable function to support package reflection

    for (f in base::getNamespaceExports("mypackage")) {
      if (grepl("viz_", f)) {
        testthat::expect_s3_class(get(paste0("mypackage::", f))())
      }
    }