启动 R 后台进程/线程/等。使用当前环境进行单元测试

jwi*_*ley 5 unit-testing r testthat covr callr

由于callr::rcallr::r_bg在干净的环境中启动后台进程,因此它们并不完全适合单元测试范例。通过 testthat 运行的 R 单元测试会加载包的当前开发版本,但单元测试启动的任何后台进程(例如,可能想要测试的管道工 API)将使用系统包。这是一些稍微混淆的输出来说明我的意思:

> 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"
Run Code Online (Sandbox Code Playgroud)

上述的变体(将 system.file 输出传递到plumber::plumb、使用plumber::plumb_api目录等)的结果都大致相同,这意味着尝试进行测试 API 开发版本的单元测试会失败。

devtools::load_all()我当前的解决方法是从 run by 的函数内运行callr::r_bg,并传入system.file(...)函数的路径,以便后台进程加载包的开发版本并找到管道工脚本的开发版本。这取得了好坏参半的成功——它在运行单元测试时按预期工作,除非运行单元测试时devtools::check()会出现错误(因为工作目录不同并devtools::load_all()中断)。

让此测试设置发挥作用的最佳方法是什么?我想解决方案将涉及获取目录或包路径并将其传递给调用者,或传递环境,但我不确定该朝哪个方向走。

更新

再次遇到这个问题,我在搜索时发现了自己的问题。一个新的问题是我正在通过covr包来测量单元测试覆盖率,它通过修改环境中的对象来跟踪使用情况来工作,因此不会跟踪后台会话中的使用情况。我不确定通过启动继承当前环境的后台会话是否可以免费实现正确的覆盖率跟踪(例如,该会话的覆盖率统计数据可能不会传达到工作会话的统计数据),但这至少是一个步骤更近了。