How to write a test for a ggplot plot

十年热恋 提交于 2019-11-30 04:15:56
Forrest R. Stevens

This seems to be what you're aiming at, though specific requirements for plotting parameters and contents will vary of course. But for the example you nicely crafted above these tests should all pass:

##  Load the proto library for accessing sub-components of the ggplot2
##    plot objects:
library(proto)

test_that("Plot layers match expectations",{
  p <- plot_fun(df)
  expect_is(p$layers[[1]], "proto")
  expect_identical(p$layers[[1]]$geom$objname, "bar")
  expect_identical(p$layers[[1]]$stat$objname, "identity")
})

test_that("Scale is labelled 'Proportion'",{
  p <- plot_fun(df)
  expect_identical(p$labels$y, "Proportion")
})

test_that("Scale range is NULL",{
  p <- plot_fun(df)
  expect_null(p$scales$scales[[1]]$range$range)
})

This question and its answers offer a good starting point on other ways to characterize ggplot objects in case you have other things you'd like to test.

It's worth noting that the vdiffr package is designed for comparing plots. A nice feature is that it integrates with the testthat package -- it's actually used for testing in ggplot2 -- and it has an add-in for RStudio to help manage your testsuite.

What I also find useful in addition to the existing answers, is to test if a plot can actually be printed.

library(ggplot2)
library(scales) # for percent()
library(testthat)

# First, 'correct' data frame
df <- data.frame(
    Response   = LETTERS[1:5],
    Proportion = c(0.1,0.2,0.1,0.2,0.4)
)

# Second data frame where column has 'wrong' name that does not match aes()
df2 <- data.frame(
    x          = LETTERS[1:5],
    Proportion = c(0.1,0.2,0.1,0.2,0.4)
)

plot_fun <- function(df) {
    p1 <- ggplot(df, aes(Response, Proportion)) +
        geom_bar(stat='identity') + 
        scale_y_continuous(labels = percent)
    return(p1)
}

# All tests succeed
test_that("Scale is labelled 'Proportion'",{
    p <- plot_fun(df)
    expect_true(is.ggplot(p))
    expect_identical(p$labels$y, "Proportion")

    p <- plot_fun(df2)
    expect_true(is.ggplot(p))
    expect_identical(p$labels$y, "Proportion")
})

# Second test with data frame df2 fails
test_that("Printing ggplot object actually works",{
    p <- plot_fun(df)
    expect_error(print(p), NA)

    p <- plot_fun(df2)
    expect_error(print(p), NA)
})
#> Error: Test failed: 'Printing ggplot object actually works'
#> * `print(p)` threw an error.
#> Message: object 'Response' not found
#> Class:   simpleError/error/condition
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!