Search code examples
rr-packagetestthat

Hide {cli} messages in tests with {testthat}


I use {cli} messages in one of my packages. I would like to hide these messages in my tests because they clutter the testthat results. Is there a way to do that?

I've seen that {cli} has a TESTTHAT environment variable but I don't know if it exists for this purpose, and I don't know how to use it. Note that I would prefer a solution that is simple to implement, such as a test global option. I don't want to manually edit all my tests or messages.

Reproducible example:

library(testthat)
library(cli)

test_that("addition works", {
  cli_alert_info("This message should not appear")
  expect_equal(1+1, 2)
})

#> i This message should not appear
#> Test passed 

Edit: I could create a custom test_that() that would wrap suppressMessages() like the following:

my_test_that <- function(desc, code) {
  test_that(desc, {
    suppressMessages({
      code
    })
  })
}

my_test_that("addition works", {
  cli_alert_danger("This message should not appear")
  expect_equal(1+1, 2)
})

#> Test passed 

and then store it in tests/testthat/setup.R. The problem is that if a test fails, it indicates the line in my_test_that() and not the line where the error actually appears (so basically all errors and warnings will refer to the same line):

my_test_that("addition works", {
  cli_alert_danger("This message should not appear")
  expect_equal(1+4, 2)
})

-- Failure (.active-rstudio-document:6:5): addition works ----------------------
1 + 4 (`actual`) not equal to 2 (`expected`).

Here, the error refers to the line with suppressMessages(). This makes it much harder to find the source of the problem.


Solution

  • One solution was given in this Github issue. Using withr::with_options() or withr::local_options() with option cli.default_handler = function(...) { } seems to work.

    library(testthat)
    library(cli)
    
    my_test_that <- function(desc, code) {
      withr::with_options(
        list(
          cli.default_handler = function(...) { },
          usethis.quiet = TRUE
        ),
        test_that(desc, {
          code
        })
      )
    }
    
    my_test_that("addition works", {
      cli_alert_danger("This message should not appear")
      expect_equal(1+2, 2)
    })
    
    -- Failure (.active-rstudio-document:15:3): addition works ---------------------
    1 + 2 not equal to 2.
    1/1 mismatches
    [1] 3 - 2 == 1
    

    Note that this will remove all cli messages so it is not possible to use expect_message() in my_test_that().