myfunction.R that looks something like this
biggest <- function(x,y) { max(c(x,y)) }
To test this create a file called test_myfunction.R in the same directory cointaining
library(unittest, quietly = TRUE)source('myfunction.R')
ok( biggest(3,4) == 4, "two numbers" )
ok( biggest(c(5,3),c(3,4)) == 5, "two vectors" )
Now in an R session source() the test file
source('test_myfunction.R')
That's it.
Now each time you edit myfunction.R re-sourcing test_myfunction.R
reloads your function and runs your unit tests.
unittest to Suggests: in the package DESCRIPTION file.
Suggests: unittest Then create a directory called tests in your package source, alongside your R directory.
Any .R file in the tests directory will be run by R CMD check. The unittest package
CMD check and so at the end of the tests will produce a
summary and throw an error if any tests fail; throwing an error will in turn cause CMD check to
report the error and fail the check.
Assuming your package contains (and exports) the biggest() function from
tests/test_biggest.R that contains
library(unittest, quietly = TRUE)
ok( biggest(3,4) == 4, "two numbers" )
ok( biggest(c(5,3),c(3,4)) == 5, "two vectors" )
and that's it. R CMD check will run the tests and fail if any of the tests fail.
Note that your test file MUST load unittest, but SHOULD NOT load the package being tested explicitly
(this is done for you by CMD check).
If you want to include tests for un-exported functions you will need to refer to them directly using
::: notation.
For example if biggest() was not exported and my package was called mypackage then my
first test would need to look like this
ok( mypackage:::biggest(3,4) == 4, "two numbers" )
all.equal(...)
a <- c(1,2,3)
b <- 1:3
ok( all.equal(a,b), "a and b are equal" )
} tryCatch. In this example if your function returns a character vector, then
these will be displayed as part of the diagnostics.
test_for_error <- function(code, expected_regexp) {
tryCatch({
code
return("No error returned")
}, error = function(e) {
if(grepl(expected_regexp, e$message)) return(TRUE)
return(c(e$message, "Did not match:-", expected_regexp))
}
)
}
add_four <- function( x ) { if( ! is.numeric(x) ) stop("x must be numeric") return( x+4 ) }
ok( test_for_error(add_four("a"), "must be numeric"), "add_four() argument not numeric correctly throws an error" ) this will result in the output ok - add_four() argument not numeric correctly throws an error }
unittest package provides a single function, ok, that prints ok
when the expression provided evaluates to TRUE and not ok if the expression
evaluates to anything else or results in an error. This is the TAP format
( If you are writing a package unittest is designed to integrate with R CMD check.
See
A test summary is produced at the end of a session when a set of tests are run in non-interactive mode;
for example when the tests are run using Rscript or by R CMD check.
For a list of all documentation use library(help="unittest").