Since callr::r
and callr::r_bg
launch a background process in a clean environment, they do not fit neatly into unit test paradigms. An R unit test, run via testthat, loads the current development version of the package, but any background process launched by the unit test -- a plumber API, for example, which one might want to test -- will use the system package instead. Here is some slightly obfuscated output to show what I mean:
> system.file("plumber", "api", "entrypoint.R", package = "DemoPackage")
[1] "/path/to/dev/directory/for/DemoPackage/inst/plumber/api/entrypoint.R"
> callr::r(function() {system.file("plumber", "api", "entrypoint.R", package = "DemoPackage")})
[1] "/home/user_directory/R/x86_64-redhat-linux-gnu-library/3.6/DemoPackage/plumber/api/entrypoint.R"
Variations of the above (passing the system.file output to plumber::plumb
, using plumber::plumb_api
directory, etc.) all work out about the same, meaning that attempts to make a unit test that tests the development version of the API fail.
My current workaround has been to run devtools::load_all()
from within the function run by callr::r_bg
, and also pass in the system.file(...)
path to the function, so that the background process loads the dev version of the package and find the dev version of the plumber script. This has mixed success -- it works as intended when running the unit tests, except when they are run by devtools::check()
in which case there is an error (because the working directory differs and devtools::load_all()
breaks).
What's the best way of getting this test setup to work? I imagine the solution would be involve getting directory or package path and passing it to callr, or passing an environment, but I'm not sure which direction to go in.
Update
Running into this issue again, I found my own question while searching. A new wrinkle is that I am working on measuring unit test coverage via the covr
package, which works by modifying objects in the environment to track usage and so doesn't track usage within the background sessions. I'm not sure whether proper coverage tracking would come for free by starting a background session inheriting the current environment (for one, the coverage statistics from that session may not be communicated to the working session's statistics) but it would at least be one step closer.