2013-05-21 9 views
5

Sto scrivendo un test case per una funzione R che verifica se un errore viene lanciato e rilevato correttamente in un determinato punto della funzione e sto avendo alcuni problemi nel portare il test a continuare quando viene generato un errore durante l'esecuzione inCallingHandlers (...). Sto usando questo approccio:Come continuare la funzione quando viene generato un errore con CallingHandlers in R

counter <- 0 
withCallingHandlers({ 
testingFunction(df0, df1) 
testingFunction(df2, df3) 
testingFunction(df4, df5) 

}, warning=function(war){ 
    print(paste(war$message)) 
}, error=function(err){ 
    print(paste(err$message)) 
    if(err$message == paste("The function should throw this error message", 
           "at the right time.")){ 
     counter <<- counter + 1 
    } 

}) 

stopifnot(counter == 2) 

Il problema che sto funzionando in è che lo script sta uscendo dopo il primo errore è (con successo) catturati e io non sono sicuro di come gestire l'errore in modo che dopo viene catturato, con CallingHandlers continua semplicemente nella parte successiva della sua esecuzione. Capisco che abbia qualcosa a che fare con un oggetto di riavvio, ma non sono sicuro di come usarli correttamente. Qualcuno sa come posso manipolare il codice di cui sopra in modo che l'esecuzione di withCallingHandlers (...) continui anche quando viene rilevato un errore?

risposta

4

Si può solo avvolgere ogni chiamata a testingFunction con una chiamata a tryCatch:.

counter <- 0 
testForExpectedError <- function(expr) { 
    tryCatch(expr, error=function(err) { 
     print(paste(err$message)) 
     if(err$message == paste("The function should throw this error message", 
           "at the right time.")){ 
      counter <<- counter + 1 
     } 
    }) 
} 

testForExpectedError(testingFunction(df0, df1)) 
testForExpectedError(testingFunction(df2, df3)) 
testForExpectedError(testingFunction(df4, df5)) 

stopifnot(counter == 2) 
+0

Impressionante, grazie mille. – Decave

6

Per una funzione di test

fun1 = function() stop("something specific went wrong") 

l'idioma

obs = tryCatch(fun1(), error=conditionMessage) 
exp = "something specific went wrong" 
stopifnot(identical(exp, obs)) 

è forse un più ordinato versione di Ryan, e come lui evita il caso sfortunato in cui c'è un errore ma per la ragione sbagliata. Lo stesso paradigma lavora per avvertenze

fun2 = function(x) as.integer(x) 
obs = tryCatch(fun2(c("1", "two")), warning=conditionMessage) 
stopifnot(identical("NAs introduced by coercion", obs)) 

e per verificare per la valutazione 'pulito'

obs = tryCatch(fun2(c("1", "2")), warning=conditionMessage, 
      error=conditionMessage) 
stopifnot(identical(1:2, obs)) 

Questo è ok, purché Sys.getlocale() è "C" o un'altra codifica che non cambia la traduzione della messaggi di condizione.

Problemi correlati