在R中测试统计函数的指南?

时间:2010-10-14 21:17:54

标签: unit-testing r function

问题:我正在测试我正在开发的软件包中的函数,并且想知道是否可以建议一些有关如何执行此操作的一般指导原则。这些功能包括大量的统计建模,转换,子集和绘图。是否有“标准”或足够的测试?

示例:提示我提出这个问题的测试,

函数dtheta:

dtheta <- function(x) {
  ## find the quantile of the mean
  q.mean <- mean(mean(x) >= x)
  ## find the quantiles of ucl and lcl (q.mean +/- 0.15)
  q.ucl  <- q.mean + 0.15
  q.lcl  <- q.mean - 0.15
  qs <- c(q.lcl, q.mean, q.ucl)
  ## find the lcl, mean, and ucl of the vector
  c(quantile(x,qs), var(x), sqrt(var(x))/mean(x))
}

第1步:制作测试数据:

set.seed(100) # per Dirk's recommendation
test <- rnorm(100000,10,1)

步骤2:将函数的预期输出与函数的实际输出进行比较:

 expected <- quantile(test, c(0.35, 0.65, 0.5))
 actual   <- dtheta(test)[1:3]
 signif(expected,2) %in% signif(actual,2)

第3步:也许再做一次测试

test2 <- runif(100000, 0, 100)
expected <- c(35, 50, 65)
actual   <- dtheta(test2)
expected %in% signif(actual,2)

步骤4:如果为true,请考虑函数'functional'

4 个答案:

答案 0 :(得分:6)

这取决于您想要测试的具体内容。在Dirks建议,svUnitRUnit包提到的VitoshKa旁边,我想添加一些内容:

  • 确实,设置种子,但要确保你尝试使用不同种子的功能。有些功能每十次尝试就会失败一次。特别是在涉及优化时,这变得至关重要。 replicate()是一个很好的函数,可以在这种情况下使用。
  • 仔细考虑您要测试的输入。您应该测试一些与“完美”数据集不相似的“奇怪”案例。我总是测试至少10个不同大小的(模拟)数据集。
  • 傻瓜式的功能:我也投入了一些不属于该功能的数据类型。错误的类型输入可能会在某一点发生,而您想要的最后一件事就是在没有警告的情况下返回虚假结果的函数。如果您稍后在其他代码中使用该函数,则可以并且将会调试该代码!太棒了去过那里,做完了,买了这件T恤......

关于数据集扩展测试的示例:在这些情况下,您希望将其视为输出?这是你期望的结果吗?不是根据你做的测试。

> test3 <- rep(12,100000) # data with only 1 value
> expected <- c(12, 12, 12)
> actual   <- dtheta(test3) 
Error in quantile.default(x, qs) : 'probs' outside [0,1]

>  test4 <- rbinom(100000,30,0.5) # large dataset with a limited amount of values
>  expected <- quantile(test4,c(0.35, 0.50, 0.65))
>  actual   <- dtheta(test4)
>  expected %in% signif(actual,2)
[1] FALSE  TRUE  TRUE

> test5 <- runif(100,0,100) # small dataset. 
> expected <- c(35, 50, 65)
> actual   <- dtheta(test5)
> expected %in% signif(actual,2)
[1] FALSE FALSE FALSE

编辑:更正的代码,因此测试更有意义。

答案 1 :(得分:6)

你需要写

  1. 测试表明,当您输入合理的值时,您会得到正确的答案

  2. 测试显示您输入废话时功能无法正常运行。

  3. 测试所有边界情况

  4. 关于测试软件的不同策略有大量文献;维基百科的software testing page就像开始一样好。

    看看你的例子:

    输入字符串/数据框/列表时会发生什么? 那么消极的x还是想象的x呢? 矢量/数组x怎么样? 如果只允许使用正x,那么x = 0会发生什么?

    请注意,子函数(仅由您的函数调用,而不是由用户调用)需要较少的输入检查,因为您可以更好地控制函数内容。

答案 2 :(得分:5)

好问题。

除了设置种子等一般性外,我建议您查看R源中的一些测试。源中的目录tests/具有丰富的这些目录; R Base中的一些软件包(例如工具)也有子目录tests/

答案 3 :(得分:3)

它已作为评论出现,但我会将其添加为真实的答案。 R确实有一些自动测试包来帮助解决这类问题,主要的两个是Runittestthat。我简单地使用了runit,最近开始更深入地使用testthat(虽然我不能真正给出一个优点/缺点!)。

自动化测试允许您设置这些测试用例,以及上面建议的其他测试用例;

  • 边界测试
  • 压力测试(不需要测试准确性,只需将数据投入其中并查看是否会失效)
  • 处理不同的输入
  • 处理不同的底层平台/区域设置