
Compare Files with odiff (for testthat and shinytest2 Snapshots)
Source:R/snapshot.R
compare_file_odiff.RdA function factory that returns a comparison function suitable for the
compare argument of testthat::expect_snapshot_file() and of
shinytest2::AppDriver$expect_screenshot(). The returned function takes
the paths of the old (snapshot) and new image files and returns TRUE if
odiff considers them a match. When they do not match, it writes a diff
image highlighting the changed pixels and reports where it is.
expect_snapshot_image() uses it internally; use it directly when you
write image files yourself or take screenshots with shinytest2.
Usage
compare_file_odiff(
threshold = 0.1,
antialiasing = FALSE,
ignore_regions = NULL,
fail_on_layout = TRUE,
...,
preset = NULL,
diff_dir = getOption("odiffr.snapshot_diff_dir")
)Arguments
- threshold
Numeric; colour difference threshold between 0.0 and 1.0. Default is 0.1 (or the value from
preset).- antialiasing
Logical; if
TRUE, ignore antialiased pixels. Default isFALSE(or the value frompreset).- ignore_regions
List of regions to ignore during comparison. Use
ignore_region()to create regions, or pass a data.frame with columnsx1,y1,x2,y2.- fail_on_layout
Logical; if
TRUE(the default), images with different dimensions do not match.- ...
Additional arguments passed to
odiff_run().- preset
Optional name of a comparison preset, see
odiff_preset():"strict","default","screenshot"or"cross_platform". The preset suppliesthresholdandantialiasing; values given explicitly for those arguments take precedence.NULL(the default) uses the argument defaults.- diff_dir
Directory for diff images of failed comparisons.
NULL(the default, unless theodiffr.snapshot_diff_diroption is set) chooses a directory automatically, see "Diff images".FALSEdisables diff images. The directory is resolved each time the comparison runs.
Value
A function with arguments old and new (file paths) that
returns a single TRUE or FALSE. If odiff cannot compare the files
(reason == "error"), the function gives a warning with odiff's error
message and returns FALSE.
Diff images
testthat removes unrecognised files from tests/testthat/_snaps/, so diff
images are written elsewhere. With diff_dir = NULL the directory is,
in order of preference:
the
odiffr.diff_diroption (shared withexpect_images_match());tests/testthat/_odiffr/when running tests (or when called from a package root that has atests/testthatdirectory);a directory in
tempdir()otherwise.
Setting options(odiffr.save_diff = FALSE) disables automatic diff images
(an explicit diff_dir still wins).
Inside that directory, the layout below _snaps/ is mirrored and the file
is named after the snapshot: the diff for
_snaps/<variant>/<test-file>/<name>.png is
<diff_dir>/<variant>/<test-file>/<name>_diff.png. Re-running a failing
test overwrites the diff; a passing comparison removes a stale one. Add
tests/testthat/_odiffr/ to .gitignore and .Rbuildignore.
When a comparison fails, a message (not a warning, so it does not add a
warning to the test results) such as
odiff: 1.26% pixels differ (126 px) in 'plot.png'; diff image: <path>
is shown.
See also
expect_snapshot_image(), odiff_preset(),
snapshot_report() for reviewing failed snapshots on CI.
Examples
if (FALSE) { # \dontrun{
test_that("exported chart is stable", {
path <- tempfile(fileext = ".png")
save_my_chart(path)
testthat::expect_snapshot_file(
path,
name = "chart.png",
compare = compare_file_odiff(threshold = 0.2, antialiasing = TRUE)
)
})
# shinytest2: tolerate anti-aliasing noise in browser screenshots
test_that("app looks right", {
app <- shinytest2::AppDriver$new()
app$expect_screenshot(compare = compare_file_odiff(preset = "screenshot"))
})
} # }