【问题标题】:Debugging 'testthat' tests in RStudio在 RStudio 中调试“testthat”测试
【发布时间】:2015-10-11 11:34:27
【问题描述】:

在运行testthat 测试时是否可以在 RStudio 中调用调试器?我还没有找到允许这个的设置(设置中“使用devtools包功能,如果可用”的各种组合,点击“构建->更多”菜单中的“测试包”选项,运行@ 987654324@ 在控制台中,进行browser() 调用等),但还没有找到方法。

我还发现自己在测试时迷失了很多,不确定正在运行的代码是否已安装在系统库中(通过“构建和重新加载”),或者正在运行原位从本地 R 目录,或者什么 - 有时 RStudio 抱怨无法设置断点,直到重建包(所以我怀疑前者)或没有(所以我怀疑后者)。不确定这个问题是否与我的主要问题密切相关。

在没有找到进入调试器的方法的情况下,我最终将测试代码粘贴到控制台中,并以一种非常临时的方式工作,基本上是在打击我的 TDD 习惯。因此,任何建议都将不胜感激 - 如果无法调用调试器,有什么建议的解决方法吗?

我在 OS X 上以本地模式运行 RStudio 版本 0.99.447,使用 R 3.2.1。

编辑 - 我也很想了解有关选项的更多背景信息,例如“选项 X 永远不会支持调试,因为它在分叉进程中运行,请尝试使用其他选项 Y。”

更新 - 在这里没有回复,我也在https://support.rstudio.com/hc/communities/public/questions/204779797-Debugging-testthat-tests-in-RStudio 询问(我也没有任何回复)。

【问题讨论】:

    标签: r debugging testing rstudio testthat


    【解决方案1】:

    以下对我有用:

    1. 在单元测试的测试中的某处插入对browser() 的调用。
    2. 从 RStudio 控制台运行 devtools::test()(而不是使用 UI 中的“测试包”菜单项)

    然后,当测试运行程序点击browser() 调用时,您应该能够使用environment browser 并单步执行代码。

    我还没有找到让 testthat 在断点处停止的方法,但是插入 browser() 调用是一个非常接近的替代方法。

    为了确保您在加载包时从一致的状态开始,您可以关闭 RStudio,重新打开它,运行“清理并重建”,然后devtools::test()

    最后,如果您正在使用 RStudio 包,您可能需要查看来自 RStudio support 的以下建议:

    为了在您的包中进行有效调试,您还需要确保使用 --with-keep.source 选项编译您的包。此选项是 RStudio 中新包的默认选项;如需手动设置,可在工具 -> 项目选项 -> 构建工具中找到。

    【讨论】:

    • “清理和重建”是指“构建和重新加载”吗?我真正讨厌的是,我经常不小心在机器上全局安装我的开发版本。 dev_mode 是一种解决方案,但有时我也忘记打开它,因为它是手动过程...
    • 我也很犹豫是否要使用browser() 方法——最近我团队中的某个人(不是我,谢天谢地!)在他们的代码中留下了一堆browser() 语句,这些语句已经投入生产,这很糟糕。仅仅为了仔细检查就不得不修改代码是一件很糟糕的事情。虽然在这种情况下在测试文件中执行它并没有那么糟糕 - 由于某种原因,使用devtools::test() 断点在测试文件中不起作用,但它们在R/ 目录下的代码文件中起作用。
    • 不,有一个单独的“清理和重建”命令,据我所知,它与“构建和重新加载”相同,但会执行一些初始清理以进入更可预测的状态。
    • 另外,根据以下讨论,似乎缺乏对 test 中断点的支持是一个已知问题,但在撰写本文时尚未修复:discussion 1discussion 2跨度>
    • 酷,感谢您的指点。我在github.com/hadley/testthat/pull/117 上添加了一个“戳”。
    【解决方案2】:

    如果您想使用 RStudio 中的编辑器断点来调试单元测试,您可以通过解决 testthat 来实现。正如 Hadley 在 Github issue 中所说,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("invariant is true", { f(3) == 6 }) 的测试,那么您可以通过运行testf_trace(filename, "is true") 来测试它。

    如果您不确定函数的定义位置以及断点是否有效,您可以通过在控制台输入函数名称来查找。最后一两行将告诉您函数是在哪个环境中定义的,如果它是在 .Global 以外的环境中定义的。

    【讨论】:

    • 这真是太好了,这是我的第一条消息。感谢您抽出宝贵时间。
    猜你喜欢
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 2017-04-16
    • 2016-01-01
    • 2012-09-10
    • 2018-08-08
    相关资源
    最近更新 更多