You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This vignette shows you how to write your expectations. You can use within your package by putting them in a helper file, or share them with others by exporting them from your package.
19
+
This vignette shows you how to write your own expectations. You can use them within your package by putting them in a helper file, or share them with others by exporting them from your package.
msg <- sprintf("%s has length %i, not length %i.", act$lab, act_n, n)
34
34
return(fail(msg))
35
35
}
36
36
37
-
# 3. Pass when expectations are
37
+
# 3. Pass when expectations are met
38
38
pass(act$val)
39
39
}
40
40
```
41
41
42
-
The first step in any expectation is to use `quasi_label()` to capture a "labelled value", i.e. a list that contains both the value (`$val`) for testing and a label (`$lab`) for messaging. This is a pattern that exists for fairly esoteric reasons; you don't need to understand, just copy and paste it 🙂.
42
+
The first step in any expectation is to use `quasi_label()` to capture a "labelled value", i.e. a list that contains both the value (`$val`) for testing and a label (`$lab`) for messaging. This is a pattern that exists for fairly esoteric reasons; you don't need to understand it, just copy and paste it 🙂.
43
43
44
-
Next you need to check each way that `object` could violate the expectation. In this case, there's only one check, but in the more complicated cases that you'll see later there can be multiple checks. In most cases, it's easier to check for violations one by one, using early returns to `fail()`. This makes it easier to write informative failure messages that state both what the object is and what you expected.
44
+
Next you need to check each way that `object` could violate the expectation. In this case, there's only one check, but in more complicated cases there can be multiple checks. In most cases, it's easier to check for violations one by one, using early returns to `fail()`. This makes it easier to write informative failure messages that state both what the object is and what you expected.
45
45
46
46
Also note that you need to use `return(fail())` here. You won't see the problem when interactively testing your function because when run outside of `test_that()`, `fail()` throws an error, causing the function to terminate early. When running inside of `test_that()`, however, `fail()` does not stop execution because we want to collect all failures in a given test.
47
47
@@ -83,7 +83,7 @@ The following sections show you a few more variations, loosely based on existing
83
83
84
84
### `expect_vector_length()`
85
85
86
-
Lets make `expect_length()` a bit more strict by also checking that the input is a vector. R is a bit weird that it gives a length to pretty much every object, and you can imagine not wanting this code to succeed:
86
+
Let's make `expect_length()` a bit more strict by also checking that the input is a vector. R is a bit weird in that it gives a length to pretty much every object, and you can imagine not wanting this code to succeed:
Or imagine if you're checking to see if an object inherits from an S3 class. In R, there's no direct way to tell if an object is an S3 object: you can confirm that it's an object, then that it's not an S4 object. So you might organise your expectation this way:
123
+
Or imagine if you're checking to see if an object inherits from an S3 class. In R, there's no direct way to tell if an object is an S3 object: you can confirm that it's an object, then that it's not an S4 object. So you might organize your expectation this way:
124
124
125
125
```{r}
126
126
expect_s3_class <- function(object, class) {
@@ -174,7 +174,7 @@ expect_s3_class(x1, 1)
174
174
175
175
## Repeated code
176
176
177
-
As you write more expectations, you might discover repeated code that you want to extract out in to a helper. Unfortunately creating helper functions is not straightforward in testthat because every `fail()` captures the calling environment in order to give maximally useful tracebacks. Because getting this right is not critical (you'll just get a slightly suboptimal traceback in the case of failure), we don't recommend bothering. However, we document it here because it's important to get it right in testthat itself.
177
+
As you write more expectations, you might discover repeated code that you want to extract out into a helper. Unfortunately, creating helper functions is not straightforward in testthat because every `fail()` captures the calling environment in order to give maximally useful tracebacks. Because getting this right is not critical (you'll just get a slightly suboptimal traceback in the case of failure), we don't recommend bothering. However, we document it here because it's important to get it right in testthat itself.
178
178
179
179
The key challenge is that `fail()` captures a `trace_env` which should be the execution environment of the expectation. This usually works, because the default value of `trace_env` is `caller_env()`. But when you introduce a helper, you'll need to explicitly pass it along:
0 commit comments