通过比较字符串来测试 R 中的警告(最好的主意?) [英] Testing warnings in R by comparing strings (best idea?)
问题描述
我正在处理一个 R 包,我需要一些帮助来编写 R 测试函数,这些函数旨在检查是否在 C 端代码上抛出了正确的警告,然后在 R 端捕获.让我给你一些我正在做的工作的背景:
I'm working on an R package and I need some help writing R test functions that are meant to check whether the correct warning is being thrown on C-side code and then caught on the R side. Let me give you some background on what I'm working on exactly:
- 我正在编写的大部分内容都是在 C 端完成的.此外,我在 C 中有一个 if 语句类型宏,它允许编码器以字符串的形式将警告传递给 R.基本前提是 if(statement_true) pass_warning_to_R("Warning string to pass").我想要做的是通过编写一个使用 tryCatch 块的 R 文件来测试是否在我期望/需要这些警告时抛出这些警告.
到目前为止,我已经写过类似的东西:
- Most of what I'm writing is done on the C side. In addition, I have an if-statement type macro in C that allows the coder to pass a warning to R in the form of a string. The basic premise is that if(statement_true) pass_warning_to_R("Warning string to pass"). What I'd like to do is test whether these warnings are being thrown when I expect/need them to be by writing an R file that uses tryCatch blocks.
So far I've written something similar to this:
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 语句是一样的.这一点,加上这种方法非常草率和不可靠的事实,让我相信有更好的方法.那么,有没有更好的方法来做到这一点?
This is the method I'm using and, so far, I haven't even been able to get the if statement to execute by trying to get toString(war) and "Warning I'm expecting/testing for" to be the same thing. This, in addition with the fact that this method is pretty sloppy and unreliable, leads me to believe that there's a better way. So, is there a better approach to doing this?
推荐答案
通常带有警告,您希望允许评估继续;tryCatch
用于停止评估.因此,改为使用带有处理程序的 withCallingHandlers
来执行您想要的警告,然后调用 'muffleWarning' 重新启动.可以使用 conditionMessage
Usually with warnings you'd like to allow evaluation to continue; tryCatch
is used to stop evaluation. So instead use withCallingHandlers
with a handler for warnings that does what you want, and then invokes the 'muffleWarning' restart. The message of an error / warning can be extracted with 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".
Since you're writing your own package, it makes sense to create warnings that can be identified in a more robust way, e.g., the following returns a condition that can be used in warning
, but that has a class 'bad_input' that can be used in withCallingHandlers
.
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
这篇关于通过比较字符串来测试 R 中的警告(最好的主意?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!