在RStudio中调试'testthat'测试

25
在运行testthat测试时,是否可以在RStudio中调用调试器?我尝试了各种设置(例如在设置中使用“如果可用,则使用devtools包函数”,在“Build -> More”菜单中选择“Test Package”选项,通过在控制台中运行test(),添加browser()调用等),但都无法找到允许此操作的设置。
当进行测试时,我也经常迷失方向,不确定正在运行的代码是否已安装在系统库中(通过执行“Build&Reload”),还是从本地R目录中直接运行。有时RStudio会抱怨无法设置断点,直到重建包(因此我认为前者),有时则不会(因此我认为后者)。不确定这个问题是否与我的主要问题密切相关。
没有找到进入调试器的方法,最终只能将测试代码粘贴到控制台中,并以非常临时的方式工作,基本上打乱了我的TDD习惯。因此,如果无法调用调试器,则需要任何建议的解决方法。
我正在OS X上以本地模式运行RStudio版本0.99.447,使用R 3.2.1。
编辑 - 我也想了解更多关于选项的背景信息,例如:“选项X永远不支持调试,因为它正在运行forked进程,请尝试使用另一个选项Y。”
更新 - 在这里没有得到任何回复之后,我还在https://support.rstudio.com/hc/communities/public/questions/204779797-Debugging-testthat-tests-in-RStudio 上提出了同样的问题(那里也没有得到任何回复)。
2个回答

34
以下方法适用于我:
  1. 在testthat单元测试中的某处插入browser()调用。
  2. 从RStudio控制台运行devtools::test()(而不是使用UI中的“Test Package”菜单项)。
然后,当测试运行器遇到browser()调用时,您应该能够使用环境浏览器并逐步执行代码。
我还没有找到一种方法来在断点处停止testthat,但插入browser()调用是一个很好的替代方法。
为了确保在加载包方面始终处于一致的状态,您可以关闭RStudio,重新打开它,运行“清理并重建”,然后运行devtools::test() 最后,如果您正在RStudio包内工作,您可能想查看RStudio support提供的以下建议:
为了有效地进行包的调试,您还需要确保使用 --with-keep.source 选项编译您的包。在 RStudio 中,这是新包的默认选项;如果需要手动设置,可以在“工具”->“项目选项”->“构建工具”中找到。

通过“清理和重建”,你是指“构建和重新加载”吗?我真正讨厌的是,我经常会意外地在机器上全局安装我的开发版本。dev_mode是一个解决方案,但有时我也会忘记启用它,因为这是一个手动过程... - Ken Williams
4
我也不太敢使用browser()方法——最近我的团队中有人(幸好不是我!)在代码中留下了一堆browser()语句,结果这些语句被推到生产环境,造成了很糟糕的影响。现在我必须修改代码才能对其进行审查,这真是令人沮丧。不过,在测试文件中这样做并不像在代码文件中那么糟糕——由于某种原因,在使用devtools::test()时,断点无法在测试文件中起作用,但在R/目录下的代码文件中可以。 - Ken Williams
不,有一个单独的“清理和重建”命令,据我所知,它与“构建和重新加载”相同,但执行一些初始清理以进入更可预测的状态。 - alev
3
根据以下讨论,目前来看,在testthat中不支持断点是一个已知的问题,但在撰写本文时尚未修复: discussion 1, discussion 2 - alev
1
太酷了,谢谢你的指针。我在https://github.com/hadley/testthat/pull/117上添加了一个“poke”。 - Ken Williams
显示剩余3条评论

4
如果您希望在RStudio中使用编辑器断点来调试单元测试,则可以通过绕过testthat来实现。正如Hadley在Github问题中所说,testthat通常在与RStudio分开的会话中运行,因此它永远无法使用编辑器断点。但是,测试本身是具有两个参数(描述和代码)的函数调用。您可以使用一些代码来读取并运行这些测试。
testf_trace <- function(filename, match) {
  env <- new.env()

  test_that <- function(desc, code) {
    if (length(grep(match, desc)) > 0) {
      eval(substitute(code), env)
    }
  }
  env$test_that <- test_that
  source(filename, env)
}

如果你有一个测试案例是这么写的,test_that("不变量成立",{f(3) == 6}),那么你可以运行 testf_trace(filename, "is true") 来进行测试。
如果你不确定一个函数定义在哪里,也就无法确认断点是否起作用,你可以在控制台输入这个函数的名称来查找。最后一行或两行将告诉你函数定义在哪个环境中,如果它是在除了.Global之外的其他环境中定义的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接