If you are writing your own package, it might make sense to use the R state system by throwing (and catching) certain types of errors or warnings. So
myFun <- function(x) { if (any(is.na(x))) { w <- simpleWarning("'x' contains NA values") class(w) <- c("HasNA", class(w)) warning(w) } if (any(x < 0)) warning("'x' contains values less than 0") x }
and then in your test, for example, using library(RUnit) , use tryCatch and select only those conditions that interest you when testing, i.e. warnings with HasNA class:
test_myFun_NAwarning <- function() { warnOccurred <- FALSE tryCatch(myFun(1:5), HasNA = function(w) warnOcccurred <<- TRUE) checkTrue(!warnOccurred) tryCatch(myFun(-(1:5)), HasNA = function(w) warnOcccurred <<- TRUE) checkTrue(!warnOccurred) tryCatch(myFun(c(1:5, NA)), HasNA = function(w) warnOccurred <<- TRUE) checkTrue(warnOccurred) }
leading to
> test_myFun_NAwarning() [1] TRUE Warning message: In myFun(-(1:5)) : 'x' contains values less than 0
which shows that tryCatch captures only the specific warning that interests you, and does so in a way that does not rely on line text matching. Perhaps you have a helper function .warn to do all the warnings for your package. See ?withCallingHandlers ; withCallingHandlers and muffleRestart is how you can handle a constant evaluation after a warning occurs, rather than stopping on the tryCatch path.
source share