使用testthat的expect_snapshot_file测试ggplot2绘图函数遇文件找不到错误
解决testthat中expect_snapshot_file测试ggplot绘图时临时文件找不到的问题
我尝试用testthat包的expect_snapshot_file函数测试基于ggplot2的绘图函数plot_losses,完全照搬快照文档的示例,但测试时出现临时图像文件无法找到的错误。
测试文件代码:
save_png <- function(code, width = 400, height = 400) { path <- tempfile(fileext = ".png") png(path, width = width, height = height) on.exit(dev.off()) code path } expect_snapshot_plot <- function(name, code) { name <- paste0(name, ".png") announce_snapshot_file(name = name) path <- save_png(code) expect_snapshot_file(path, name) } test_that("end to end", { # OMITTED: code to generate the output `out` name = "losses_plot" expect_snapshot_plot(name, plot_losses(out)) })
plot_losses函数代码:
plot_losses <- function(out) { out %>% ggplot() + geom_point(aes(x, y, color = k)) }
问题原因
ggplot采用延迟渲染机制:仅创建ggplot对象不会触发实际绘图操作,必须显式输出(如调用print())才能将图形渲染到PNG设备中。原save_png函数里只执行了code(即创建ggplot对象),没有触发渲染,导致生成的PNG文件无效或未正确写入,最终expect_snapshot_file找不到有效文件。
修复方案
修改save_png函数,在执行code后显式调用print()触发绘图:
save_png <- function(code, width = 400, height = 400) { path <- tempfile(fileext = ".png") png(path, width = width, height = height) on.exit(dev.off()) # 显式print ggplot对象,触发渲染到PNG设备 print(code) path }
额外注意事项
- 确保生成
out的代码能输出包含x、y、k列的有效数据框,避免因数据缺失导致绘图失败。 - 首次运行测试时,需执行
testthat::snapshot_accept()或在测试界面中接受快照,生成基准PNG文件供后续测试比对。
内容的提问来源于stack exchange,提问作者theKoozie
相关产品推荐
相关产品推荐

