rstudio / config

config package for R
https://rstudio.github.io/config/
256 stars 27 forks source link

Play nice with testthat #45

Open epruesse opened 1 year ago

epruesse commented 1 year ago

There does not currently seem to be a good way to override config parameters for testing.

Assume you have e.g. a Shiny app which records uploads in a storage folder. In production, this is set to some appropriate location via config::get("storage_path"). During unit testing, this value should point to a temporary folder removed after the end of a test_that call. Creating a temporary config.yml in pkg_root/tests/testthat does not seem to be a good idea for various reasons, including potentially parallel test execution. Changing the CWD is not really supported by test_that, as test_path(x) will return x while executing tests and tests/testthat while not executing tests.

It would be good to have some sort of withr style way to override individual variables for the duration of a test, simply to force output into a temporary directory.

For what it's worth, test_that should IMO run tests in tests/testthat in a temporary directory, but that's a different issue. It would still be good to be able to override config::get values within a scope.

andrie commented 1 year ago

It's not clear what you need here. Advice on how to use testthat? You seem to have a good understanding of that already. A request on modifying config? It's not clear what such a request would be.

andrie commented 1 year ago

Perhaps something like this is getting close to what you have in mind?

with_config <- function(
    config_yml, 
    code, 
    .active_config = c(R_CONFIG_ACTIVE = "default"), 
    .temp_file = "config.yml"
) {
  cat(config_yml, file = file.path(tempdir(), .temp_file))
  withr::with_envvar(
    new = .active_config,
    code = withr::with_tempdir(code = code)
  )
}

yaml <- '
default:
  databases:
    db1: !expr c("abc")
    db2: ~/abc
dev:
  databases:
    db1: /opt/abc
    db2: !expr Sys.getenv("R")
'

with_config(yaml, config::get("databases")) |> str()
#> List of 2
#>  $ db1: chr "abc"
#>  $ db2: chr "~/abc"

Created on 2023-04-11 with reprex v2.0.2