Use the ut_cmp_error
function. For example, here is a function that will throw an error for a bad argument:
add_four <- function(x) {
if( ! is.numeric(x) ) stop("x must be numeric")
return( x+4 )
}
We can test the argument check like this:
ok(ut_cmp_error(add_four("a"), "must be numeric"), "add_four() argument not numeric throws error")
## ok - add_four() argument not numeric throws error
Use ut_cmp_equal(...)
or ut_cmp_identical(...)
as replacements for all.equal(...)
and identical(...)
respectively:
a <- c(1,2,3)
b <- 1:3
ok(ut_cmp_equal(a,b), "a and b are equal")
## ok - a and b are equal
ut_cmp_identical
will make sure your objects are identical, and is more useful when comparing e.g. a list of strings which should be exactly the same.
ut_cmp_equal
will test for ‘near equality’, and is more useful when comparing numeric values which may be slightly different due to floating-point accuracy.
Either way, if your test fails you will get verbose output showing you how they differ, and if you have git installed the output will be coloured. For example:
> ok(ut_cmp_equal(c(1,2,3,4,5), c(1,8,8,4,5))) not ok - ut_cmp_equal(c(1, 2, 3, 4, 5), c(1, 8, 8, 4, 5)) # Test returned non-TRUE value: # Mean relative difference: 2.2 # --- c(1, 2, 3, 4, 5) # +++ c(1, 8, 8, 4, 5) # [1] 1 [-2 3-]{+8 8+} 4 5
When dealing with many unit tests in one file it can be useful to group related unit tests.
The ok_group()
function is used like this:
ok_group("Test addition", {
ok(1 + 1 == 2, "Can add 1")
ok(1 + 3 == 4, "Can add 3")
})
## # Test addition
## ok - Can add 1
## ok - Can add 3
ok_group("Test subtraction", {
ok(1 - 1 == 0, "Can subtract 1")
ok(1 - 3 == -2, "Can subtract 3")
})
## # Test subtraction
## ok - Can subtract 1
## ok - Can subtract 3
No. Sit down and have a cup of tea. Hopefully the feeling will go away.
Add the following line to the package DESCRIPTION
file.
Suggests: unittest
Create a directory called tests
in your package source, alongside your R
directory.
Place your tests in a file with the extension .R
and add the following lines to the top of the file (replacing mypackage
with the name of your package).
library(mypackage)
library(unittest, quietly = TRUE)
That’s it; R CMD check
will run the tests and fail if any of the tests fail.
Any .R
file in the tests
directory will be run by R CMD check
.
When you use the unittest
package the package ‘knows’ that it is being run by CMD check
and at the end of the tests it produces a summary of the results. The package will also throw an error if any tests fail; throwing an error will in turn cause CMD check
to report the error and fail the check
.
Here is a very simple example:
Assuming your package contains (and exports
) the function biggest()
biggest <- function(x,y) {max(c(x,y))}
then the tests/my_tests_for_biggest.R
file could contain something like
library(mypackage)
library(unittest, quietly = TRUE)
ok(biggest(3,4) == 4, "two numbers")
ok(biggest(c(5,3),c(3,4)) == 5, "two vectors")
If you have some unit tests which require access to un-exported functions, or un-exported S3 methods, you can use local
.
local({
ok(internal_function() == 3)
ok(another_internal_function() == 4)
ok(final_internal_function() == 5)
}, asNamespace('mypackage'))