With a pointblank agent, we can write a testthat test file and opt to place it in the testthat/tests if it is available in the project path (we can specify an alternate path as well). This works by transforming the validation steps to a series of expect_*() calls inside individual testthat::test_that() statements.

A hard requirement for using write_testthat_file() on an agent is the presence of a read_fn, which is a function that is invoked to obtain the target table. The read_fn statement will be placed at the top of the testthat test file so that the target table is available for each of the testthat::test_that() statements that follow. If an agent does not have a read_fn it can be added via the set_read_fn().

Thresholds will be obtained from those applied for the stop state. This can be set up for a pointblank agent by passing an action_levels object to the actions argument of create_agent() or the same argument of any included validation function. If stop thresholds are not available, then a threshold value of 1 will be used for each generated expect_*() statement in the resulting testthat test file.

There is no requirement that the agent first undergo interrogation with interrogate(). However, it may be useful as a dry run to interactively perform an interrogation on the target data before generating the testthat test file.

  name = NULL,
  path = NULL,
  overwrite = FALSE,
  skips = NULL,
  quiet = FALSE



An agent object of class ptblank_agent.


An optional name for for the testhat test file. This should be a name without extension and without the leading "test-" text. If nothing is supplied, the name will be derived from the tbl_name in the agent. If that's not present, a generic name will be used.


A path can be specified here if there shouldn't be an attempt to place the file in testthat/tests.


Should a testthat file of the same name be overwritten? By default, this is FALSE.


This is an optional vector of test-skipping keywords modeled after the testthat skip_on_*() functions. The following keywords can be used to include skip_on_*() statements: "cran" (testthat::skip_on_cran()), "travis" (testthat::skip_on_travis()), "appveyor" (testthat::skip_on_appveyor()), "ci" (testthat::skip_on_ci()), "covr" (testthat::skip_on_covr()), "bioc" (testthat::skip_on_bioc()). There are keywords for skipping tests on certain operating systems and all of them will insert a specific testthat::skip_on_os() call. These are "windows" (skip_on_os("windows")), "mac" (skip_on_os("mac")), "linux" (skip_on_os("linux")), and "solaris" (skip_on_os("solaris")). These calls will be placed at the top of the generated testthat test file.


Should the function not inform when the file is written? By default this is FALSE.


Invisibly returns TRUE if the testthat file has been written.


Tests for inactive validation steps will be skipped with a clear message indicating that the reason for skipping was due to the test not being active. Any inactive validation steps can be forced into an active state by using the activate_steps() on an agent (the opposite is possible with the deactivate_steps() function).

The testthat package comes with a series of skip_on_*() functions which conveniently cause the test file to be skipped entirely if certain conditions are met. We can quickly set any number of these at the top of the testthat test file by supplying keywords as a vector to the skips option of write_testthat_file(). For instance, setting skips = c("cran", "windows) will add the testthat skip_on_cran() and skip_on_os("windows") statements, meaning that the generated test file won't run on a CRAN system or if the system OS is Windows.

Here is an example of testthat test file output:


# Generated by pointblank

tbl <- small_table

test_that("column `date_time` exists", {
    columns = vars(date_time),
    threshold = 1

test_that("values in `c` should be <= `5`", {
    columns = vars(c),
    value = 5,
    threshold = 0.25

This was generated by the following set of statements:


agent <- 
    read_fn = ~ small_table,
    actions = action_levels(stop_at = 0.25)
  ) %>%
  col_exists(vars(date_time)) %>%
  col_vals_lte(vars(c), value = 5)
  agent = agent,
  name = "small_table",
  path = "."

Function ID


See also

Other Post-interrogation: all_passed(), get_agent_x_list(), get_data_extracts(), get_sundered_data()


if (interactive()) {

# Creating an `action_levels` object is a
# common workflow step when creating a
# pointblank agent; we designate failure
# thresholds to the `warn`, `stop`, and
# `notify` states using `action_levels()`
al <- 
    warn_at = 0.10,
    stop_at = 0.25,
    notify_at = 0.35

# A pointblank `agent` object is now
# created and the `al` object is provided
# to the agent; the static thresholds
# provided by `al` make reports a bit
# more useful after interrogation
agent <- 
    read_fn = ~ small_table,
    label = "An example.",
    actions = al
  ) %>%
  col_exists(vars(date, date_time)) %>%
    regex = "[0-9]-[a-z]{3}-[0-9]{3}"
  ) %>%
  col_vals_gt(vars(d), value = 100) %>%
  col_vals_lte(vars(c), value = 5) %>%

# This agent and all of the checks can
# be transformed into a testthat file
# with `write_testthat_file()`; the `stop`
# thresholds will be ported over
  agent = agent,
  name = "small_table",
  path = "."

# The above code will generate a file with
# the name `test-small_table.R`; the path
# was specified with `"."` but, by default,
# the function will place the file in the
# `tests/testthat` folder if it's available

# An agent on disk as a YAML file can be
# made into a testthat file; the
# 'agent-small_table.yml' file is
# available in the package through
# `system.file()`
yml_file <- 
    "yaml", "agent-small_table.yml",
    package = "pointblank"

# Writing the testthat file into the
# working directory is much the same
# as before but we're reading the
# agent from disk this time
  agent = yaml_read_agent(yml_file),
  name = "from_agent_yaml",
  path = "."