Skip to content

Commit 1c9947d

Browse files
authored
Snapshot documentation improvements (#1682)
Fixes #1548. Fixes #1629. Fixes #1649.
1 parent 0630319 commit 1c9947d

8 files changed

+173
-96
lines changed

R/expect-output.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#' Does code print output to the console?
22
#'
33
#' Test for output produced by `print()` or `cat()`. This is best used for
4-
#' very simple output; for more complex cases use [verify_output()].
4+
#' very simple output; for more complex cases use [expect_snapshot()].
55
#'
66
#' @export
77
#' @family expectations

R/snapshot.R

+35-23
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,9 @@
88
#' (e.g. this is a useful error message). Learn more in
99
#' `vignette("snapshotting")`.
1010
#'
11-
#' * `expect_snapshot()` captures all messages, warnings, errors, and
12-
#' output from code.
13-
#' * `expect_snapshot_output()` captures just output printed to the console.
14-
#' * `expect_snapshot_error()` captures an error message and
15-
#' optionally checks its class.
16-
#' * `expect_snapshot_warning()` captures a warning message and
17-
#' optionally checks its class.
18-
#' * `expect_snapshot_value()` captures the return value.
19-
#'
20-
#' (These functions supersede [verify_output()], [expect_known_output()],
21-
#' [expect_known_value()], and [expect_known_hash()].)
11+
#' `expect_snapshot()` runs code as if you had executed it at the console, and
12+
#' records the results, including output, messages, warnings, and errors.
13+
#' If you just want to compare the result, try [expect_snapshot_value()].
2214
#'
2315
#' @section Workflow:
2416
#' The first time that you run a snapshot expectation it will run `x`,
@@ -50,11 +42,9 @@
5042
#' @param error Do you expect the code to throw an error? The expectation
5143
#' will fail (even on CRAN) if an unexpected error is thrown or the
5244
#' expected error is not thrown.
53-
#' @param variant `r lifecycle::badge("experimental")`
54-
#'
55-
#' If not-`NULL`, results will be saved in `_snaps/{variant}/{test.md}`,
56-
#' so `variant` must be a single string of alphanumeric characters suitable
57-
#' for use as a directory name.
45+
#' @param variant If non-`NULL`, results will be saved in
46+
#' `_snaps/{variant}/{test.md}`, so `variant` must be a single string
47+
#' suitable for use as a directory name.
5848
#'
5949
#' You can use variants to deal with cases where the snapshot output varies
6050
#' and you want to capture and test the variations. Common use cases include
@@ -206,8 +196,24 @@ snap_header <- function(state, header) {
206196
}
207197
}
208198

199+
#' Snapshot helpers
200+
#'
201+
#' @description
202+
#' `r lifecycle::badge("questioning")`
203+
#'
204+
#' These snapshotting functions are questioning because they were developed
205+
#' before [expect_snapshot()] and we're not sure that they still have a
206+
#' role to play.
207+
#'
208+
#' * `expect_snapshot_output()` captures just output printed to the console.
209+
#' * `expect_snapshot_error()` captures an error message and
210+
#' optionally checks its class.
211+
#' * `expect_snapshot_warning()` captures a warning message and
212+
#' optionally checks its class.
213+
#'
214+
#' @inheritParams expect_snapshot
215+
#' @keywords internal
209216
#' @export
210-
#' @rdname expect_snapshot
211217
expect_snapshot_output <- function(x, cran = FALSE, variant = NULL) {
212218
edition_require(3, "expect_snapshot_output()")
213219
variant <- check_variant(variant)
@@ -228,7 +234,7 @@ expect_snapshot_output <- function(x, cran = FALSE, variant = NULL) {
228234
#' always fail (even on CRAN) if an error of this class isn't seen
229235
#' when executing `x`.
230236
#' @export
231-
#' @rdname expect_snapshot
237+
#' @rdname expect_snapshot_output
232238
expect_snapshot_error <- function(x, class = "error", cran = FALSE, variant = NULL) {
233239
edition_require(3, "expect_snapshot_error()")
234240
expect_snapshot_condition(
@@ -240,7 +246,7 @@ expect_snapshot_error <- function(x, class = "error", cran = FALSE, variant = NU
240246
}
241247

242248
#' @export
243-
#' @rdname expect_snapshot
249+
#' @rdname expect_snapshot_output
244250
expect_snapshot_warning <- function(x, class = "warning", cran = FALSE, variant = NULL) {
245251
edition_require(3, "expect_snapshot_warning()")
246252
expect_snapshot_condition(
@@ -273,6 +279,12 @@ expect_snapshot_condition <- function(base_class, x, class, cran = FALSE, varian
273279
)
274280
}
275281

282+
#' Snapshot testing for values
283+
#'
284+
#' Captures the result of function, flexibly serializing it into a text
285+
#' representation that's stored in a snapshot file. See [expect_snapshot()]
286+
#' for more details on snapshot testing.
287+
#'
276288
#' @param style Serialization style to use:
277289
#' * `json` uses [jsonlite::fromJSON()] and [jsonlite::toJSON()]. This
278290
#' produces the simplest output but only works for relatively simple
@@ -284,11 +296,11 @@ expect_snapshot_condition <- function(base_class, x, class, cran = FALSE, varian
284296
#' * `serialize()` produces a binary serialization of the object using
285297
#' [serialize()]. This is all but guaranteed to work for any R object,
286298
#' but produces a completely opaque serialization.
287-
#' @param ... For `expect_snapshot_value()` only, passed on to
288-
#' [waldo::compare()] so you can control the details of the comparison.
289-
#' @export
299+
#' @param ... Passed on to [waldo::compare()] so you can control the details of
300+
#' the comparison.
301+
#' @inheritParams expect_snapshot
290302
#' @inheritParams compare
291-
#' @rdname expect_snapshot
303+
#' @export
292304
expect_snapshot_value <- function(x,
293305
style = c("json", "json2", "deparse", "serialize"),
294306
cran = FALSE,

_pkgdown.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ reference:
4141

4242
- title: Snapshot testing
4343
contents:
44-
- starts_with("expect_snapshot_")
44+
- expect_snapshot
45+
- expect_snapshot_value
46+
- expect_snapshot_file
4547
- starts_with("snapshot_")
4648

4749
- title: Test helpers

man/expect_output.Rd

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/expect_snapshot.Rd

+6-63
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/expect_snapshot_output.Rd

+52
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/expect_snapshot_value.Rd

+62
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vignettes/snapshotting.Rmd

+13-7
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,12 @@ Since they can't automatically find the reference output, they instead just prin
162162
## Other types of output
163163

164164
So far we've focussed on snapshot tests for output printed to the console.
165-
But `expect_snapshot()` also captures messages, errors, and warnings.
165+
But `expect_snapshot()` also captures messages, errors, and warnings[^1].
166166
The following function generates a some output, a message, and a warning:
167167

168+
[^1]: We no longer recommend `expect_snapshot_output()`, `expect_snapshot_warning()`, or `expect_snapshot_error()`.
169+
Just use `expect_snapshot()`.
170+
168171
```{r}
169172
f <- function() {
170173
print("Hello")
@@ -210,15 +213,18 @@ test_that("you can't add weird thngs", {
210213
})
211214
```
212215

213-
## Other types of snapshot
216+
## Snapshotting values
214217

215218
`expect_snapshot()` is the most used snapshot function because it records everything: the code you run, printed output, messages, warnings, and errors.
216-
But sometimes you just want to capture the output or errors in which you might want to use `expect_snapshot_output()` or `expect_snapshot_error()`.
217-
This can happen when the associated code is lengthy or doesn't add much in terms of capturing the test's intent.
218-
`expect_snapshot_error()` predates `expect_snapshot()` and, if history had unfolded differently, `expect_snapshot(error = TRUE, ...)` probably would have made `expect_snapshot_error()` unnecessary.
219+
If you care about the return value rather than any side-effects, you may might to use `expect_snapshot_value()` instead.
220+
It offers a number of serialisation approaches that provide a tradeoff between accuracy and human readability.
219221

220-
Or rather than caring about side-effects, you may want to check that the value of an R object stays the same.
221-
In this case, you can use `expect_snapshot_value()` which offers a number of serialisation approaches that provide a tradeoff between accuracy and human readability.
222+
```{r}
223+
test_that("can snapshot a simple list", {
224+
x <- list(a = list(1, 5, 10), b = list("elephant", "banana"))
225+
expect_snapshot_value(x)
226+
})
227+
```
222228

223229
## Whole file snapshotting
224230

0 commit comments

Comments
 (0)