tinytest
tinytest copied to clipboard
Feature suggestion: recursively test directories with `run_test_dir`
There has been a lot of movement to make R code more modular, most recently with the box package, which supports Python-like imports and treats files as encapsulated modules.
This allows for a much cleaner structure than a regular R package does, as now you can have as many nested directories in R/
as you want. A lot of shiny
app frameworks like rhino also move into this direction, and a lot of best-practice talks at conferences recommend related approaches such as modules that promote more encapsulation than R can offer.
The downside is that so far I haven't found a clean approach that would support testing a structure like that, since always regular package structures are expected. I created a hacky solution using tinytest
:
test_dir <- function(directory) {
message('Testing directory ', directory)
test <- tinytest::run_test_dir(directory)
frame <- as.data.frame(test)
frame$path <- paste(directory, frame$file, sep = "/")
frame
}
clean_characters <- \(vec) gsub("\r?\n|\r", "", vec)
dirs <- list.dirs(path = "tests", full.names = TRUE, recursive = TRUE)
tests <- do.call(what = 'rbind', args = lapply(dirs, test_dir))
if (all(tests$result)) {
message('All tests passed')
quit(status = 0)
} else {
failed_tests <- tests[!tests$result,]
for (column in c('call', 'diff')) {
failed_tests[[column]] <- clean_characters(failed_tests[[column]])
}
error_messages <- paste(
failed_tests$path,
paste0('lines: ', failed_tests$first, ':', failed_tests$last),
paste0('call: ', failed_tests$call),
paste0('error: ', failed_tests$diff),
sep = ' | '
)
stop('\n', paste(error_messages, collapse = '\n'))
}
Would it be possible to support something like recurse = TRUE
to run_test_dir
out of the box or are there drawbacks to this? With an approach like this, it's not the test package's duty to somehow find the code that should be tested, each test file imports the code itself.
I feel like this could be done. I have to see how easy it is. Also, as tinytest
can run in parallel (with the file as unit for parallel running) I'd have to see if there are consequences there.
Thanks for considering this, this would be a very helpful feature I think and make testing more accessible to people who do not use R package structures as umbrella for their work.