6

私は R パッケージに取り組んでおり、C 側のコードで正しい警告がスローされ、R 側でキャッチされるかどうかを確認するための R テスト関数を作成するのに助けが必要です。私が正確に取り組んでいることの背景を説明しましょう。

  1. 私が書いていることのほとんどは、C 側で行われています。さらに、コーダーが警告を文字列の形式で R に渡すことができるようにする C の if ステートメント タイプのマクロがあります。基本的な前提は、if(statement_true) pass_warning_to_R("渡す警告文字列") です。私がやりたいのは、tryCatch ブロックを使用する R ファイルを作成することによって、これらの警告がスローされると予想される/必要なときにスローされるかどうかをテストすることです。
  2. これまでのところ、私はこれに似たものを書いています:

    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ステートメントを実行することさえできませんでしたもの。これは、この方法がかなりずさんで信頼できないという事実に加えて、より良い方法があると私に信じさせます. それで、これを行うためのより良いアプローチはありますか?

4

3 に答える 3

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 <- 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
于 2013-04-19T21:33:55.040 に答える