我正在研究R包,我需要一些帮助来编写R测试函数,这些函数用于检查是否在C端代码上抛出正确的警告然后在R端捕获。让我来谈谈我正在做的工作:
到目前为止,我写了类似的东西:
counter <- 0
tryCatch({
function_im_testing()
}, warning = function(war) {
# Check if warning is as expected and if so increment counter
if(toString(war)=="The warning I'm expecting/testing for"){
print(toString(war))
counter <- counter + 1
}
}, error = function(err) {
print(toString(err))
}, finally = {
print("Leaving tryCatch")
})
# Stop if the 3 warnings we expected aren't present
stopifnot(counter == 3)
这是我正在使用的方法,到目前为止,我甚至无法通过尝试获取toString(war)和“警告我期待/测试”来获取if语句。是一回事。除此之外,这种方法非常草率和不可靠,这使我相信有更好的方法。那么,有没有更好的方法来做到这一点?
答案 0 :(得分:4)
通常会有警告,您希望继续进行评估; tryCatch
用于停止评估。因此,请将withCallingHandlers
与处理程序一起使用,以执行您想要的警告,然后调用'muffleWarning'重启。可以使用conditionMessage
counter <- 0L
withCallingHandlers({
function_im_testing()
}, warning = function(w) {
if (conditionMessage(w) == "The warning I'm expecting/testing for")
counter <<- counter + 1L
invokeRestart("muffleWarning")
})
由于您正在编写自己的包,因此创建可以以更健壮的方式识别的警告是有意义的,例如,以下内容返回可在warning
中使用的条件,但具有可以在withCallingHandlers
中使用的类'bad_input'。
bad_input <- function(...) {
w <- simpleWarning(...)
class(w) <- c("bad_input", class(w))
w
}
像warning(bad_input("your input is bad"))
一样使用并使用
fun <- function() {
warning("oops")
warning(bad_input("your input is bad"))
"DONE"
}
像
> fun()
[1] "DONE"
Warning messages:
1: In fun() : oops
2: your input is bad
> counter <- 0L
> withCallingHandlers(fun(), bad_input = function(w) {
+ counter <<- counter + 1L
+ invokeRestart("muffleWarning")
+ })
[1] "DONE"
Warning message:
In fun() : oops
> counter
[1] 1
答案 1 :(得分:4)
除了实际捕获警告之外,您还需要知道警告消息已被翻译:
library(devtools)
with_envvar(c(LANG = "en"), log(-1))
# In log(-1) : NaNs produced
with_envvar(c(LANG = "de"), log(-1))
# In log(-1) : NaNs wurden erzeugt
with_envvar(c(LANG = "fr"), log(-1))
# In log(-1) : production de NaN
with_envvar(c(LANG = "ko"), log(-1))
# In log(-1) : NaN이 생성되었습니다
因此,如果您在测试中执行此操作,请确保设置LANG
环境变量以确保消息不会根据其运行的计算机而有所不同