This vignette shows you how to create custom expectations that work
identically to the built-in expect_ functions. Since these
functions will need to be loaded in order for your tests to work, we
recommend putting them in an appropriately named helper file,
i.e. tests/testthat/helper-expectations.R.
There are three main parts to writing an expectation, as illustrated
by expect_length():
expect_length <- function(object, n) {
# 1. Capture object and label
act <- quasi_label(rlang::enquo(object), arg = "object")
# 2. Call expect()
act$n <- length(act$val)
expect(
act$n == n,
sprintf("%s has length %i, not length %i.", act$lab, act$n, n)
)
# 3. Invisibly return the value
invisible(act$val)
}The first step in any expectation is to capture the actual object, and generate a label for it to use if a failure occur. All testthat expectations support quasiquotation so that you can unquote variables. This makes it easier to generate good labels when the expectation is called from a function or within a for loop.
By convention, the first argument to every expect_
function is called object, and you capture it’s value
(val) and label (lab) with
act <- quasi_label(enquo(object)), where
act is short for actual.
Next, you should verify the expectation. This often involves a little
computation (here just figuring out the length), and you
should typically store the results back into the act
object.
Next you call expect(). This has two arguments:
ok: was the expectation successful? This is usually
easy to write
failure_message: What informative error message
should be reported to the user so that they can diagnose the problem.
This is often hard to write!
For historical reasons, most built-in expectations generate these
with sprintf(), but today I’d recommend using the glue package
succeed() and fail()For expectations with more complex logic governing when success or
failure occurs, you can use succeed() and
fail(). These are simple wrappers around
expect() that allow you to write code that looks like
this: