如何将 testthat 测试应用于包中与特定命名模式匹配的所有函数?

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

我有一个包,其中包含许多名为 viz_foo()viz_bar() 等的函数。

我想测试这些函数中的每一个都生成一个 class gg 的对象。这将很简单,有两个函数,如:

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

但在实践中我有很多函数都采用这种命名约定,并且包贡献者一直在添加新函数。我想确保以这种方式测试任何新功能,而不必将它们显式添加到单元测试中。

我认为处理这个问题的简陋方法是:

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")
  
})

这适用于 运行 使用 devtools::test() 而不是 R CMD check 的测试。

有没有办法对名称中包含特定模式的包中的所有函数应用测试?

getNamespaceExports可能是更适合支持包反射的函数

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