我正在尝试在R脚本中测试单个函数,其中包含函数调用作为脚本的最后一个语句,即以下是R代码:
mul.R
#!/usr/bin/env Rscript
mul <- function(n, m) {
prod <- n * m
return (prod)
}
mul(4,5)
以下是测试脚本:
test_simpleProgram.R
#!/usr/bin/env Rscript
library('RUnit')
source("./../simpleProgram.R")
test.mul <- function() {
checkEqualsNumeric(mul(n= 2,m= 3), 4)
}
我使用以下命令执行测试脚本:
runTestFile(absFileName= file.path("test_simpleProgram.R"))
现在,当我发送R脚本时,我想测试mul.R
,因为最后一个语句已经调用mul
函数,所以执行整个脚本,然后运行测试脚本功能再次。这使得第一次执行(由于source(..)
)不需要用于测试目的。
有没有办法测试这样的脚本,而不是在测试脚本中获取脚本时运行脚本?
答案 0 :(得分:4)
使用parse
代替source
:
code <- parse("c:/R/mul.R") # actual file path may vary
这会将文件加载为未评估的表达式。它可以被视为:
# > as.list(code)
# [[1]]
# mul <- function(n, m) {
# prod <- n * m
# return(prod)
# }
#
# [[2]]
# mul(4, 5)
上面列表的第一个元素实际上是对'<-'
函数的调用:
# > as.list(code[[1]])
# [[1]]
# `<-`
#
# [[2]]
# mul
#
# [[3]]
# function(n, m) {
# prod <- n * m
# return(prod)
# }
第二个元素OTOH是对mul
函数的调用:
# > as.list(code[[2]])
# [[1]]
# mul
#
# [[2]]
# [1] 4
#
# [[3]]
# [1] 5
因此,如果您的文件由赋值和不需要的函数调用组成,我们可以通过检查上面列表中每个条目的第一个元素来识别它:
filter <- sapply(code, function(x)as.character(x[[1]])=="<-")
# >filter
# [1] TRUE FALSE
现在我们只能评估作业:
eval(code[filter], envir=globalenv())
然后您可以调用test.mul
功能。您可以使用这些语句来取代source
来电。
这可以推广到其他过滤器。例如,如果要评估除最后一个之外的所有语句,您可以使用它:
eval(code[-length(code)], envir=globalenv())