Unit tests for deprecated functions in R package cause warnings during check
Asked Answered
K

2

8

I've deprecated several functions in my R package by including a .Deprecated("new_function_name") line at the start of the function. I had full unit test coverage for those deprecated functions. Now those tests produce warnings (because of the deprecation message) and muddy up the results of testthat::test() and devtools::check().

I could just delete the test coverage for deprecated functions, but it seems like as long as users can still call the functions, I should retain test coverage. Is there a way I can keep the tests but avoid the clutter in the result of check()? E.g., tell testthat to count them as passing if the expect_equal() still works, ignoring the deprecation warnings?

Koball answered 22/3, 2017 at 12:49 Comment(0)
V
2

This is an old question, but now the 'lifecycle' package offers a good method. The documentation is clear and concise:

library(testthat)

mytool <- function() {
  deprecate_soft("1.0.0", "mytool()")
  10 * 10
}

# Forcing the verbosity level is useful for unit testing. You can
# force errors to test that the function is indeed deprecated:
test_that("mytool is deprecated", {
  rlang::local_options(lifecycle_verbosity = "error")
  expect_error(mytool(), class = "defunctError")
})

# Or you can enforce silence to safely test that the function
# still works:
test_that("mytool still works", {
  rlang::local_options(lifecycle_verbosity = "quiet")
  expect_equal(mytool(), 100)
})

You can use tests/testthat/setup.R to set the option globally for the tests.

Versatile answered 14/7, 2023 at 4:6 Comment(0)
M
7

.Deprecated produces a warning. So you can always temporarily store the output and wrap that in a call to expect_warning or suppressWarnings if you don't care to test that it gives a warning.

my_dep_fun <- function(x){
   .Deprecated("my_new_fun")
   return(x+1)
}

Using this

> # This is what I expect you're doing right now
> expect_equal(my_dep_fun(3), 4)
Warning message:
'my_dep_fun' is deprecated.
Use 'my_new_fun' instead.
See help("Deprecated") 
> 
> # If we store and use expect_warning we don't get the warning
> expect_warning(tmp <- my_dep_fun(3))
> expect_equal(tmp, 4)
> # Alternatively...
> suppressWarnings(expect_equal(my_dep_fun(3), 4))
> 
Milt answered 22/3, 2017 at 12:57 Comment(1)
This satisfies the primary goals of keeping the tests and yielding a clean sheet on test(). I'd love to put this approach in a function so I could just change my tests from expect_equal to expect_equal_deprecated - would be cleaner to implement vs. updating each test like this. But I tinkered with it and don't see a way, so maybe this is the best that can be done.Koball
V
2

This is an old question, but now the 'lifecycle' package offers a good method. The documentation is clear and concise:

library(testthat)

mytool <- function() {
  deprecate_soft("1.0.0", "mytool()")
  10 * 10
}

# Forcing the verbosity level is useful for unit testing. You can
# force errors to test that the function is indeed deprecated:
test_that("mytool is deprecated", {
  rlang::local_options(lifecycle_verbosity = "error")
  expect_error(mytool(), class = "defunctError")
})

# Or you can enforce silence to safely test that the function
# still works:
test_that("mytool still works", {
  rlang::local_options(lifecycle_verbosity = "quiet")
  expect_equal(mytool(), 100)
})

You can use tests/testthat/setup.R to set the option globally for the tests.

Versatile answered 14/7, 2023 at 4:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.