I am using testthat
to write tests for my R package. One of my tests makes use of jitter
. I want to make sure the test is reproducible.
Do I put set.seed(1014)
library(testthat)
in ./tests/testthat.R
; orcontext("Test
) in ./tests/testthat/test-function.R
; ortest_that("Example works"){jitter(1)}))
in ./tests/testthat/test-function.R
?And why?
If you only declare set.seed()
once, then you always need to run the tests that use randomness in the same order in order to get the same results. However, it's probably not a good idea for unit test to only work when run in a certain order. You should set the seed as close to the time that you need to verify a random value is returned.
Here's a function that can set the seed for just a code block
with_seed <- function(seed, code) {
code <- substitute(code)
orig.seed <- .Random.seed
on.exit(.Random.seed <<- orig.seed)
set.seed(seed)
eval.parent(code)
}
You can run it like
with_seed(5, rnorm(5))
or
with_seed(5, {
a <- rnorm(5)
b <- runif(5)
a + b
})
But you will still get random numbers for the original seed outside the block.
If you would prefer to pull such a function from an existing package, the withr::set_seed appears to do the same thing.