Unit Testing {gtsummary} Tables
A couple of guidelines while writing unit tests for gtsummary functions.
Create a test chunk for each argument. If you are testing the interaction of two arguments, make a chunk for that, e.g.
test_that("tbl_regression(conf.level, conf.int)")
.test_that("tbl_regression(conf.level)", { expect_silent( <- lm(age ~ trt + marker, trial) |> tbl tbl_regression(conf.level = 0.80) ) expect_equal( $table_styling$header |> tbl::filter(column %in% "conf.low") |> dplyr::pull(label), dplyr"**80% CI**" ) })
For chunks that return messaging or error messaging, create a separate test chunk. Capture error messaging with snapshot tests, so we can assess whether the error’s header appropriately lists the calling function.
test_that("tbl_uvregression(method.args) messaging", { # error with an incorrect argument passed expect_snapshot( error = TRUE, tbl_uvregression( trial,y = response, method = glm, method.args = list(not_an_arg = FALSE), include = trt ) ) })
Generally,
expect_equal()
is preferred over snapshot testing. But snapshots are great for error messaging checks.When using snapshot tests, include one, or perhaps two, tests per test chunk.
expect_silent()
is a useful tool when creating an object to perform further testing on. Use it when you expect no notes or warnings.Our goal is that no matter what a user passes in the arguments (or combination of arguments), they receive a coherent and helpful error message. Keep this in mind while writing unit tests. If inputs result in poor messaging, rather than testing the poor messaging, we should update the function.
For arguments that accept functions, check the tidyverse shortcut notation works as well as typical functions, e.g.
pvalue_fun = ~style_pvalue(.x)
(gtsummary only)