1

我有两个函数,其中一个函数根据参数以半递归方式调用另一个函数。

f1 <- function(use_f2 = FALSE){
  if (use_f2) {
    f2()
  }
}

f2 <- function(){
  f1(use_f2 = FALSE)
}

我想根据参数跟踪每个函数被调用的次数,然后将其作为单元测试的一部分使用testthat.

我可以跟踪使用自定义环境进行了多少次调用,并且trace(请参阅此处了解我之前所做的),如上一个SO 问题所示

function_counts <- new.env()
function_counts$f1 <- function_counts$f2 <- 0

trace(f1, tracer = quote(function_counts$f1 <- function_counts$f1 + 1), print = FALSE)
trace(f2, tracer = quote(function_counts$f2 <- function_counts$f2 + 1), print = FALSE)

f1()
function_counts$f1
function_counts$f2

这很好用,直到我添加testthat环境的复杂性。

如果我把

count_env <- new.env()

count_env$f1 <- 0

trace(f1, tracer = quote(count_env$f1 <<- count_env$f1 + 1), print = FALSE)

无论是在块外还是在test_that块内,然后devtools::test()rstudio中运行或ctrl-shift-t,在特殊环境下测试,我会得到. 我意识到这都是and环境之间的相互作用,但我无法破译它。count_env not foundtracetestthat

我也尝试过使该count_env对象成为包本身的未导出对象,但这似乎也不起作用。

这个repo 有一个包含这两个函数的最小包和一个testthat测试目录来使用它。

任何关于从这里去哪里的帮助都会很棒。

4

1 回答 1

0

事实证明,答案是使用局部变量,以及在调用中定义的局部trace函数。

.f1 <- .f2 <- 0

trace(f1, tracer = function() {.f1 <<- .f1 + 1}, print = FALSE)
trace(f2, tracer = function() {.f2 <<- .f2 + 1}, print = FALSE)

test_that("f1 FALSE", {
  f1()
  expect_equal(1, .f1)
  expect_equal(0, .f2)
})

感谢 Steph Locke 指出使用匿名函数的示例,以及最初的拉取请求。

于 2015-12-10T18:42:23.110 回答