diff --git a/R/snapshot-file.R b/R/snapshot-file.R index dea4ce474..af70a4570 100644 --- a/R/snapshot-file.R +++ b/R/snapshot-file.R @@ -41,10 +41,23 @@ #' written to the `_snaps` directory but which no longer have #' corresponding R code to generate them. These dangling files are #' automatically deleted so they don't clutter the snapshot -#' directory. However we want to preserve snapshot files when the R -#' code wasn't executed because of an unexpected error or because of a -#' [skip()]. Let testthat know about these files by calling -#' `announce_snapshot_file()` before `expect_snapshot_file()`. +#' directory. +#' +#' This can cause problems if your test is conditionally executed, either +#' because of an `if` statement or a [skip()]. To avoid files being deleted in +#' this case, you can call `announce_snapshot_file()` before the conditional +#' code. +#' +#' ```R +#' test_that("can save a file", { +#' if (!can_save()) { +#' announce_snapshot_file(name = "data.txt") +#' skip("Can't save file") +#' } +#' path <- withr::local_tempfile() +#' expect_snapshot_file(save_file(path, mydata()), "data.txt") +#' }) +#' ``` #' #' @export #' @examples @@ -67,21 +80,20 @@ #' } #' #' # You'd then also provide a helper that skips tests where you can't -#' # be sure of producing exactly the same output +#' # be sure of producing exactly the same output. #' expect_snapshot_plot <- function(name, code) { +#' # Announce the file before touching skips or running `code`. This way, +#' # if the skips are active, testthat will not auto-delete the corresponding +#' # snapshot file. +#' name <- paste0(name, ".png") +#' announce_snapshot_file(name = name) +#' #' # Other packages might affect results #' skip_if_not_installed("ggplot2", "2.0.0") -#' # Or maybe the output is different on some operation systems +#' # Or maybe the output is different on some operating systems #' skip_on_os("windows") #' # You'll need to carefully think about and experiment with these skips #' -#' name <- paste0(name, ".png") -#' -#' # Announce the file before touching `code`. This way, if `code` -#' # unexpectedly fails or skips, testthat will not auto-delete the -#' # corresponding snapshot file. -#' announce_snapshot_file(name = name) -#' #' path <- save_png(code) #' expect_snapshot_file(path, name) #' } @@ -97,14 +109,15 @@ expect_snapshot_file <- function( check_string(path) check_string(name) check_bool(cran) + check_variant(variant) edition_require(3, "expect_snapshot_file()") + + announce_snapshot_file(name = name) if (!cran && on_cran()) { - skip("On CRAN") + return(invisible()) } - check_variant(variant) - snapshotter <- get_snapshotter() if (is.null(snapshotter)) { snapshot_not_available(path) diff --git a/man/expect_snapshot_file.Rd b/man/expect_snapshot_file.Rd index 473634109..5a2a8cda6 100644 --- a/man/expect_snapshot_file.Rd +++ b/man/expect_snapshot_file.Rd @@ -79,10 +79,22 @@ testthat automatically detects dangling snapshots that have been written to the \verb{_snaps} directory but which no longer have corresponding R code to generate them. These dangling files are automatically deleted so they don't clutter the snapshot -directory. However we want to preserve snapshot files when the R -code wasn't executed because of an unexpected error or because of a -\code{\link[=skip]{skip()}}. Let testthat know about these files by calling -\code{announce_snapshot_file()} before \code{expect_snapshot_file()}. +directory. + +This can cause problems if your test is conditionally executed, either +because of an \code{if} statement or a \code{\link[=skip]{skip()}}. To avoid files being deleted in +this case, you can call \code{announce_snapshot_file()} before the conditional +code. + +\if{html}{\out{
}}\preformatted{test_that("can save a file", \{ + if (!can_save()) \{ + announce_snapshot_file(name = "data.txt") + skip("Can't save file") + \} + path <- withr::local_tempfile() + expect_snapshot_file(save_file(path, mydata()), "data.txt") +\}) +}\if{html}{\out{
}} } \examples{ @@ -105,21 +117,20 @@ expect_snapshot_file(save_png(hist(mtcars$mpg)), "plot.png") } # You'd then also provide a helper that skips tests where you can't -# be sure of producing exactly the same output +# be sure of producing exactly the same output. expect_snapshot_plot <- function(name, code) { + # Announce the file before touching skips or running `code`. This way, + # if the skips are active, testthat will not auto-delete the corresponding + # snapshot file. + name <- paste0(name, ".png") + announce_snapshot_file(name = name) + # Other packages might affect results skip_if_not_installed("ggplot2", "2.0.0") - # Or maybe the output is different on some operation systems + # Or maybe the output is different on some operating systems skip_on_os("windows") # You'll need to carefully think about and experiment with these skips - name <- paste0(name, ".png") - - # Announce the file before touching `code`. This way, if `code` - # unexpectedly fails or skips, testthat will not auto-delete the - # corresponding snapshot file. - announce_snapshot_file(name = name) - path <- save_png(code) expect_snapshot_file(path, name) }