我们如何测试构建R包时未暴露的函数?

bri*_*ndk 15 tdd unit-testing r

我正在为R 开发一个图形分析包.我们正在尝试使用清洁代码测试驱动开发(TDD)中的原则.但是,我们遇到了一个概念问题.

你怎么测试未曝光的功能?

请考虑以下简化示例.Outer()是我们在包中构建的函数,我们通过将其列在NAMESPACE文件中将其公开给用户.Inner()是一个简短的(~5行)效用函数:

Outer <- function(...) {

  Inner <- function(...) {
    return(x)
  }

  return( Inner() )
}
Run Code Online (Sandbox Code Playgroud)

我们程序包中的大多数用户公开函数都是简短的单行为Inner()样式函数的集合,这些Outer()函数位于用户可以调用的单个函数的保护之下.Granova.ds.ggplot()就是一个例子.Clean Code强烈倡导这种模块化设计,我们对结果非常满意.但是我们不知道如何为它构建单元测试,因为我们想要测试的Granova.ds.ggplot()函数在我们设计它的方式之外的函数范围之外是不可访问的.

我们遇到了几个想法/解决方案:

  1. 测试应该只能访问公共API.由于Inner()设计的功能不是公开的(它们不会被导出NAMESPACE),我们甚至不应该尝试测试它们.
  2. Hadley Wickham的testthat 软件包维基说它支持使用R CMD check工作流程测试"非导出功能" .
  3. 如果所有其他方法都失败了,我们可能会以某种方式手动破坏我们的Outer()功能以进

到目前为止,这些解决方案都没有奏效

解决方案1似乎是一个警察.我们相信,特别是在R中,拥有一个称为各种简短,单一责任的实用方法的顶级函数是明智的.不能测试这样的方法似乎很愚蠢,就像那种类型的东西有一个解决方案,但我们还没有找到.

解决方案2可能会起作用,但到目前为止我们尚未开始工作.如果你尝试克隆我们的存储库,那么inst/dev.R我相信你会在测试输出中发现它找不到该函数InitializeGgplot(),即使所述函数是在613-615行中定义的granova.1w.ggplot().同样,R CMD check在终端上运行似乎根本不执行任何测试.它需要花费大量时间并向我们投掷侮辱性错误,但:-(

解决方案3在某种意义上是务实的,但与总是朝着项目目标状态的目标相反.这对我们没有意义.

什么是理想的解决方案

理想情况下,我们正在寻找一种方法来利用像testthat我们编码时快速提供反馈的包,并允许我们测试像Inner()这样的函数中存在函数Outer().更好的方法就是在不诉诸的情况下做到这一点R CMD check,由于我们的一些功能的三维复杂性每次运行几乎需要一分钟.

那么,我们缺少什么?TDD实践是否允许在R中测试外部/内部样式设置?如果他们这样做,我们怎样才能开发我们的包装?任何反馈都是受欢迎的,我会尽力回应任何不清楚的事情.

谢谢!

had*_*ley 7

如果Inner实现了您想要测试的非平凡功能,我建议移到Inner顶层,但不要导出它.一般来说,我正是出于这个原因而避免在其他函数中嵌套函数 - 它们很难测试.

您可以在开发期间使用通常的测试函数进行测试,因为您可能只是在所有R代码中获取并且不担心名称空间(至少我是如何开发的).然后R CMD check结合使用test_package以确保测试在构建时仍然有效 - test_packages在包命名空间中运行测试,以便它们可以测试未导出的函数.


mbq*_*mbq 6

IMO在这里没有问题 - Inner只是Outer的一个不可拆卸的部分,所以测试外部测试内部.你愿意测试匿名功能吗?同样在这里.