Skip to content

Commit e040b3c

Browse files
committed
Preserve snapshots for tests that were not run
Fixes #2066
1 parent c45ce93 commit e040b3c

File tree

5 files changed

+82
-9
lines changed

5 files changed

+82
-9
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# testthat (development version)
22

3+
* `test_file(desc = ...)` no longer loses snapshot results (#2066).
34
* In `R CMD check`, snapshots now only advise on how to resolve failures once (#2207).
45
* `snapshot_review()` includes a reject button and only displays the file navigation and the skip button if there are multiple files to review (#2025).
56
* New `snapshot_download_gh()` makes it easy to get snapshots off GitHub and into your local package (#1779).

R/snapshot-reporter.R

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@ SnapshotReporter <- R6::R6Class(
1010
snap_file_saved = character(),
1111
variants_changed = FALSE,
1212
fail_on_new = NULL,
13+
desc = NULL,
1314

1415
old_snaps = NULL,
1516
cur_snaps = NULL,
1617
new_snaps = NULL,
1718

18-
initialize = function(snap_dir = "_snaps", fail_on_new = NULL) {
19+
initialize = function(
20+
snap_dir = "_snaps",
21+
fail_on_new = NULL,
22+
desc = NULL
23+
) {
1924
self$snap_dir <- normalizePath(snap_dir, mustWork = FALSE)
2025
self$fail_on_new <- fail_on_new
26+
self$desc <- desc
2127
},
2228

2329
start_file = function(path, test = NULL) {
@@ -31,6 +37,22 @@ SnapshotReporter <- R6::R6Class(
3137
self$cur_snaps <- FileSnaps$new(self$snap_dir, self$file, type = "cur")
3238
self$new_snaps <- FileSnaps$new(self$snap_dir, self$file, type = "new")
3339

40+
if (!is.null(self$desc)) {
41+
# When filtering tests, we need to copy over all of the old snapshots,
42+
# apart from the one that matches the test
43+
snaps <- self$old_snaps$snaps
44+
test_name <- test_description(self$desc)
45+
for (variant in names(snaps)) {
46+
# In the case of subtests, snaps are named a / b / c1, a / b / c2 etc.
47+
# So if we run a / b, we want to remove a / b, a / b / c, a / b / c2
48+
# Subtests that use / in their names are not currently supported.
49+
matches <- startsWith(names(snaps[[variant]]), test_name)
50+
# Can't just remove because we want to preserve order
51+
snaps[[variant]][matches] <- rep(list(NULL), sum(matches))
52+
}
53+
self$cur_snaps$snaps <- snaps
54+
}
55+
3456
if (!is.null(test)) {
3557
self$start_test(NULL, test)
3658
}
@@ -207,16 +229,30 @@ local_snapshotter <- function(
207229
reporter = SnapshotReporter,
208230
snap_dir = "_snaps",
209231
cleanup = FALSE,
232+
desc = NULL,
210233
fail_on_new = NULL,
211234
frame = caller_env()
212235
) {
213-
reporter <- reporter$new(snap_dir = snap_dir, fail_on_new = fail_on_new)
236+
reporter <- reporter$new(
237+
snap_dir = snap_dir,
238+
fail_on_new = fail_on_new,
239+
desc = desc
240+
)
214241
withr::local_options("testthat.snapshotter" = reporter, .local_envir = frame)
215242

216243
reporter
217244
}
218245

219-
local_test_snapshotter <- function(snap_dir = NULL, frame = caller_env()) {
246+
local_test_snapshotter <- function(
247+
snap_dir = NULL,
248+
desc = NULL,
249+
frame = caller_env()
250+
) {
220251
snap_dir <- snap_dir %||% withr::local_tempdir(.local_envir = frame)
221-
local_snapshotter(snap_dir = snap_dir, fail_on_new = FALSE, frame = frame)
252+
local_snapshotter(
253+
snap_dir = snap_dir,
254+
desc = desc,
255+
fail_on_new = FALSE,
256+
frame = frame
257+
)
222258
}

R/test-files.R

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ test_files_serial <- function(
221221
local_testing_env(env)
222222

223223
test_files_setup_state(test_dir, test_package, load_helpers, env)
224-
reporters <- test_files_reporter(reporter, "serial")
224+
reporters <- test_files_reporter(reporter, "serial", desc = desc)
225225

226226
with_reporter(
227227
reporters$multi,
@@ -318,6 +318,7 @@ test_files_setup_state <- function(
318318
test_files_reporter <- function(
319319
reporter,
320320
mode = c("serial", "parallel"),
321+
desc = NULL,
321322
frame = caller_env()
322323
) {
323324
mode <- arg_match(mode)
@@ -334,7 +335,12 @@ test_files_reporter <- function(
334335
} else {
335336
snap_base <- SnapshotReporter
336337
}
337-
snap <- local_snapshotter(snap_base, fail_on_new = on_ci(), frame = frame)
338+
snap <- local_snapshotter(
339+
snap_base,
340+
fail_on_new = on_ci(),
341+
desc = desc,
342+
frame = frame
343+
)
338344

339345
reporters <- compact(list(user, lister, snap))
340346
list(

R/test-that.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,10 @@ local_description_set <- function(
216216
invisible(old)
217217
}
218218

219-
test_description <- function() {
220-
if (length(the$description) == 0) {
219+
test_description <- function(desc = the$description) {
220+
if (length(desc) == 0) {
221221
NULL
222222
} else {
223-
paste(the$description, collapse = " / ")
223+
paste(desc, collapse = " / ")
224224
}
225225
}

tests/testthat/test-snapshot-reporter.R

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,33 @@ test_that("`expect_error()` can fail inside `expect_snapshot()`", {
176176
err <- out[[1]]$results[[1]]
177177
expect_match(err$message, "did not throw the expected error")
178178
})
179+
180+
181+
test_that("can filter with desc", {
182+
path <- withr::local_tempdir()
183+
184+
# First record some results
185+
suppressWarnings({
186+
snapper <- local_test_snapshotter(snap_dir = path)
187+
snapper$start_file("snapshot")
188+
snapper$start_test(test = "x")
189+
expect_snapshot_output(cat("x"))
190+
snapper$end_test()
191+
snapper$start_test(test = "y")
192+
expect_snapshot_output(cat("y"))
193+
snapper$end_test()
194+
snapper$end_file()
195+
})
196+
snaps_all <- readLines(file.path(path, "snapshot.md"))
197+
198+
# Now pretend we just ran one
199+
snapper <- local_test_snapshotter(snap_dir = path, desc = "x")
200+
snapper$start_file("snapshot")
201+
snapper$start_test(test = "x")
202+
expect_snapshot_output(cat("x"))
203+
snapper$end_test()
204+
snapper$end_file()
205+
snaps_filtered <- readLines(file.path(path, "snapshot.md"))
206+
207+
expect_equal(snaps_all, snaps_filtered)
208+
})

0 commit comments

Comments
 (0)