分发包含单元测试的R包

时间:2009-12-10 09:36:44

标签: unit-testing r software-distribution

所以我决定将我的几个R函数放入一个包中,然后我正在阅读/学习Writing R Extension

它显然抱怨了一些我做得不对的事情。

经过足够的谷歌搜索后,我在这里解决了几个问题,这个问题与测试风格有关:我正在使用RUnit,我喜欢测试尽可能接近被测试的代码。这样我就不会忘记测试,我将测试用作技术文档的一部分。

例如:

fillInTheBlanks <- function(S) {
  ## NA in S are replaced with observed values

  ## accepts a vector possibly holding NA values and returns a vector
  ## where all observed values are carried forward and the first is
  ## carried backward.  cfr na.locf from zoo library.
  L <- !is.na(S)
  c(S[L][1], S[L])[1 + cumsum(L)]
}

test.fillInTheBlanks <- function() {
  checkEquals(fillInTheBlanks(c(1, NA, NA, 2, 3, NA, 4)), c(1, 1, 1, 2, 3, 3, 4))
  checkEquals(fillInTheBlanks(c(1, 2, 3, 4)), c(1, 2, 3, 4))
  checkEquals(fillInTheBlanks(c(NA, NA, 2, 3, NA, 4)), c(2, 2, 2, 3, 3, 4))
}

R CMD check问题注释行,如下所示:

test.fillInTheBlanks: no visible global function definition for
  ‘checkEquals’

它抱怨我没有记录测试功能。

我真的不想为测试函数添加文档,我绝对不希望在RUnit包中添加依赖项。

您认为我应该如何看待这个问题?

2 个答案:

答案 0 :(得分:4)

你在哪里进行单元测试?您可能不希望将它们放入R目录中。更标准的方法是将它们置于inst\unitTests之下。看看this R-wiki page regarding the configuration.

或者,您可以指定将在NAMESPACE中导出哪些文件,以及扩展中应该和不应该记录哪些功能。

除此之外,理想情况下,当调用R CMD CHECK时,应该运行测试;这是设计的一部分。在这种情况下,您应该创建一个测试脚本,以便在单独的tests目录中调用您的测试。并且您需要在该脚本中加载RUnit包(但您不需要将其作为包的依赖项)。

编辑1:

关于你的失败,因为它找不到checkEquals函数:我会改变你的函数是这样的:

test.fillInTheBlanks <- function() {
  require(RUnit)
  checkEquals(fillInTheBlanks(c(1, NA, NA, 2, 3, NA, 4)), c(1, 1, 1, 2, 3, 3, 4))
  checkEquals(fillInTheBlanks(c(1, 2, 3, 4)), c(1, 2, 3, 4))
  checkEquals(fillInTheBlanks(c(NA, NA, 2, 3, NA, 4)), c(2, 2, 2, 3, 3, 4))
}

这样就可以在调用函数时加载包,也可以通知用户该包是必需的。

编辑2:

来自"Writing R Extensions"

  

请注意,应记录包中的所有用户级对象;如果包pkg包含仅供“内部”使用的用户级对象,则它应提供文件pkg-internal.Rd,该文件记录所有此类对象,并明确指出这些对象不应由用户调用。参见例如例如,R分布中的包网格的来源。请注意,广泛使用内部对象的包应该在名称空间中隐藏这些对象,而不需要记录它们(请参阅包名称空间)。

您可以将pkg-internal.Rd文件用作一个选项,但如果您打算使用许多隐藏对象,则通常在NAMESPACE中的声明中处理。

答案 1 :(得分:1)

您是否加载了RUnit包裹?

您最好的选择可能是使用RUnit查看包含现有代码的包。