Search code examples
runit-testingautomated-testsdevtoolsr-package

Using testthat with more than one expected outcome


I wish to check an R function that may output one of two acceptable values using the "testthat" package. Here's a simplified example:

Foo <- function () {
  if (uncontrolable_condition) {
    matrix(as.raw(0x0c))
  } else {
    matrix(as.raw(0x03))
  }
}

The best solution I could come up with is

result <- Foo()
expect_true(identical(result, matrix(as.raw(0x0c))) ||
            identical(result, matrix(as.raw(0x03))))

But this loses the functionality of waldo::compare: if I fail the test, I have to manually run waldo::compare(Foo(), matrix(as.raw(0x0c))) to see how the output differs from the expectation.


Solution

  • I think you're going to need a custom expectation. Based on the testthat pkgdown site, it might look something like this:

    expect_options <- function(object, options) {
      
      # 1. Capture object and label
      act <- quasi_label(rlang::enquo(object), arg = "object")
      
      # 2. Call expect()
      compResults <- purrr::map_lgl(options, ~identical(act$val, .x))
      expect(
        any(compResults),
        sprintf(
          "Input (%s) is not one of the accepted options: %s",
                toString(act$val),
                paste(purrr::map_chr(options, toString), collapse = ", ")
        )
      )
      
      # 3. Invisibly return the value
      invisible(act$val)
    
    }
    
    expect_options(result, list(matrix(as.raw(0x0c)), matrix(as.raw(0x03))))