трассировка, включающая изменение переменных в тесте

У меня есть две функции, одна из которых вызывает другую полурекурсивным образом в зависимости от аргументов.

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() или ctrl-shift-t в rstudio, который тестируется в специальных средах, я получить count_env not found. Я понимаю, что все это взаимодействие между средами trace и testthat, но я не могу его расшифровать.

Я также пытался сделать объект count_env неэкспортируемым объектом самого пакета, но это тоже не сработало.

В этом репозитории есть минимальный пакет с этими двумя функциями и каталог testthattests, с которым можно поиграться.

Любая помощь в том, куда идти отсюда, была бы отличной.


person rmflight    schedule 10.12.2015    source источник
comment
Этот вопрос по сути является дубликатом stackoverflow.com/questions/21687514/r -количество вызовов функций   -  person Steph Locke    schedule 10.12.2015
comment
Кроме того, первый пример в предоставленной вами ссылке, похоже, работает   -  person romants    schedule 10.12.2015
comment
@RomanTsegelskyi правда? вызовом devtools::test() на пакете или Ctrl-shift-t в rstudio? потому что это всегда не для меня   -  person rmflight    schedule 10.12.2015
comment
нет, просто запустив код. Я думаю, вы должны добавить, что тест должен вызываться с помощью devtools::test()   -  person romants    schedule 10.12.2015


Ответы (1)


Оказывается, нужно использовать локальные переменные и функцию local, определенную в вызове 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 за указание на пример использования анонимной функции и за первоначальный запрос на включение.

person rmflight    schedule 10.12.2015