Question: I am testing functions in a package that I am developing and would like to know if you can suggest some general guidelines for how to do this. The functions include a large range of statistical modeling, transformations, subsetting, and plotting. Is there a 'standard' or some sufficient test?
An Example: the test that prompted me ask this question,
The function dtheta:
dtheta <- function(x) {
## find the quantile of the mean
q.mean <- mean(mean(x) >= x)
## find the quantiles of ucl and lcl (q.mean +/- 0.15)
q.ucl <- q.mean + 0.15
q.lcl <- q.mean - 0.15
qs <- c(q.lcl, q.mean, q.ucl)
## find the lcl, mean, and ucl of the vector
c(quantile(x,qs), var(x), sqrt(var(x))/mean(x))
}
Step 1: make test data:
set.seed(100) # per Dirk's recommendation
test <- rnorm(100000,10,1)
Step 2: compare the expected output from the function with the actual output from the function:
expected <- quantile(test, c(0.35, 0.65, 0.5))
actual <- dtheta(test)[1:3]
signif(expected,2) %in% signif(actual,2)
Step 3: maybe do another test
test2 <- runif(100000, 0, 100)
expected <- c(35, 50, 65)
actual <- dtheta(test2)
expected %in% signif(actual,2)
Step 4: if true, consider function 'functional'
It depends on what exactly you want to test. Next to Dirks recommendations, svUnit
or the RUnit
package VitoshKa mentioned, I'd like to add a few things :
replicate()
is a nice function to use in this context. An example on extended testing of datasets: what would you like to see as output in these cases? Is this the result you'd expect? Not according to the test you did.
> test3 <- rep(12,100000) # data with only 1 value
> expected <- c(12, 12, 12)
> actual <- dtheta(test3)
Error in quantile.default(x, qs) : 'probs' outside [0,1]
> test4 <- rbinom(100000,30,0.5) # large dataset with a limited amount of values
> expected <- quantile(test4,c(0.35, 0.50, 0.65))
> actual <- dtheta(test4)
> expected %in% signif(actual,2)
[1] FALSE TRUE TRUE
> test5 <- runif(100,0,100) # small dataset.
> expected <- c(35, 50, 65)
> actual <- dtheta(test5)
> expected %in% signif(actual,2)
[1] FALSE FALSE FALSE
edit : corrected code so tests are a bit more senseful.
You need to write
tests that show you get the right answer when you input sensible values
tests that show your function fails correctly when you input nonsense.
test for all boundary cases
There is a huge amount of literature on different strategies for testing software; Wikipedia's software testing page is as good a place as any to start.
Looking at your example:
What happens when you input a string/dataframe/list?
What about negative x
or imaginary x
?
How about vector/array x
?
If only positive x
is allowed, then what happens at x = 0
?
Note that subfunctions (that are only called by your functions and never by the user) need less input checking because you have more control over what goes into the function.
Nice question.
Besides generalities such as setting a seed, I would recommend that you look at some of the tests in the R sources. The directory tests/
in the source has a wealth of these; some of the packages in R Base (such as tools) also have subdirectory tests/
.
It's already appeared as a comment, but I'll add it as a bona fidey answer. R does have a few automated testing packages to help with this kind of thing, the main two being Runit and testthat . I've briefly used runit, and recently started using testthat in more depth (I can't really give any good advantages / disadvantages of one over another though !).
Automated testing allows you to setup these test cases, as well as others as suggested above like;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.