You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对R包中符合指定命名规则的函数批量执行testthat测试

批量测试R包内指定命名规则函数的可靠方案

原代码R CMD check运行失败的核心原因

  • R CMD check的测试环境中,你的包不会默认加载到search()路径的顶层,直接调用ls("package:mypackage")会抛出找不到包环境的错误
  • 字符串拼接+eval()的调用方式会触发R CMD check的可疑代码检查,同时存在安全隐患
  • 没有错误捕获逻辑,一旦某一个函数调用失败,无法直接定位问题函数

可通过R CMD check的实现方案

假设你的所有viz_*函数无参数即可正常运行,如果部分函数需要必填入参,可以参考后续的扩展适配方案。

testthat::test_that("所有viz_开头函数返回gg类对象", {
  # 替换为你的实际包名
  pkg_name <- "mypackage"
  # 直接获取包命名空间,不依赖search路径加载状态
  pkg_ns <- asNamespace(pkg_name)
  # 匹配所有viz_开头的导出对象,过滤出函数
  viz_func_names <- ls(pkg_ns, pattern = "^viz_")
  viz_funcs <- Filter(function(name) is.function(pkg_ns[[name]]), viz_func_names)

  # 遍历测试每个函数
  for (func_name in viz_funcs) {
    # 从命名空间安全获取函数
    target_func <- getExportedValue(pkg_name, func_name)
    # 调用函数并捕获错误,方便定位问题
    plt <- tryCatch(
      suppressMessages(suppressWarnings(target_func())),
      error = function(e) {
        stop(sprintf("函数%s调用失败:%s", func_name, e$message))
      }
    )
    # 类型检查,附带函数名提示,失败时可直接定位问题
    testthat::expect_s3_class(plt, "gg", info = sprintf("当前测试函数:%s", func_name))
  }
})

扩展适配:处理带必填参数的函数

如果部分viz_*函数需要传入必填参数,可以提前定义参数映射列表,调用时使用do.call传参:

# 定义空值合并操作符,也可以直接使用rlang::`%||%`
`%||%` <- function(x, y) if (is.null(x)) y else x

testthat::test_that("所有viz_开头函数返回gg类对象", {
  pkg_name <- "mypackage"
  pkg_ns <- asNamespace(pkg_name)
  viz_func_names <- ls(pkg_ns, pattern = "^viz_")
  viz_funcs <- Filter(function(name) is.function(pkg_ns[[name]]), viz_func_names)

  # 预定义各函数的入参列表,无参数的函数可以不写
  func_param_map <- list(
    viz_foo = list(data = test_dataset, x = "date", y = "value"),
    viz_bar = list(group_col = "category", fill = "#2c3e50")
  )

  for (func_name in viz_funcs) {
    target_func <- getExportedValue(pkg_name, func_name)
    params <- func_param_map[[func_name]] %||% list()
    plt <- tryCatch(
      suppressMessages(suppressWarnings(do.call(target_func, params))),
      error = function(e) {
        stop(sprintf("函数%s调用失败:%s", func_name, e$message))
      }
    )
    testthat::expect_s3_class(plt, "gg", info = sprintf("当前测试函数:%s", func_name))
  }
})

内容的提问来源于stack exchange,提问作者Matt Cowgill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 22:30:04