通过比较字符串来测试 R 中的警告(最好的主意?) [英] Testing warnings in R by comparing strings (best idea?)

查看:20
本文介绍了通过比较字符串来测试 R 中的警告(最好的主意?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个 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:

  1. 我正在编写的大部分内容都是在 C 端完成的.此外,我在 C 中有一个 if 语句类型宏,它允许编码器以字符串的形式将警告传递给 R.基本前提是 if(statement_true) pass_warning_to_R("Warning string to pass").我想要做的是通过编写一个使用 tryCatch 块的 R 文件来测试是否在我期望/需要这些警告时抛出这些警告.
  2. 到目前为止,我已经写过类似的东西:

  1. 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.
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆