4

所以我决定将我的几个 R 函数放入一个包中,我正在阅读/学习编写 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 包添加依赖项。

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

4

2 回答 2

4

您将单元测试放在哪里?您可能不想将它们放入R目录中。更标准的方法是将它们放在inst\unitTests. 看看这个关于配置的 R-wiki 页面。

或者,您可以指定将在您的 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:

来自“编写 R 扩展”

请注意,包中的所有用户级对象都应记录在案;如果包 pkg 包含仅供“内部”使用的用户级对象,它应该提供一个文件 pkg-internal.Rd 记录所有此类对象,并明确说明这些对象不应由用户调用。例如,请参阅 R 发行版中的 package grid 的源代码。请注意,广泛使用内部对象的包应在不需要记录这些对象时将这些对象隐藏在名称空间中(请参阅包名称空间)。

您可以使用 pkg-internal.Rd 文件作为一种选择,但如果您打算拥有许多隐藏对象,这通常在 NAMESPACE 中的声明中处理。

于 2009-12-10T12:32:39.690 回答
1

你加载RUnit包了吗?

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

于 2009-12-10T12:23:10.657 回答