Testthat code in a function instead of a file?

testthat

#1

Anybody have a good approach for putting testthat tests in a function instead of in a test file?

Why I want to do this:

I am working on a project where I am using many input files, and I would like to test a number of expectations on each input file prior to reading them in. I really like the vocabulary of testthat and the way that you can do a lot of tests and have a report at the end instead of choking on the first error. I know that there are other assertion libraries, and maybe this is more of an assertion thing... but I would love to keep using the expect_* functions I know and love.

My attempt so far:

suppressPackageStartupMessages(library(tidyverse))
suppressPackageStartupMessages(library(testthat))

car_tests <- function(arg) {

  context("in car_tests")
  x <- rlang::enquo(arg)

  test_that(paste0("properties of ", rlang::quo_text(x)), {
    expect_type(!!x, "list")
    expect_length(!!x, 11)
  })

  invisible(arg)
}

test_in_fun <- function(code) {
  lister <- ListReporter$new()

  with_reporter(
    reporter = lister,
    {
      lister$start_file("in script")
      force(code)
      lister$end_context()
    },
    start_end_reporter = FALSE
  )

  res <- lister$get_results()
}

res <- test_in_fun({
  car_tests(mtcars)
  car_tests(mtcars[1:3])
})

res %>% purrr::map("results") %>% flatten() %>% {
  tibble(
    test = map_chr(., "test"),
    message = map_chr(., "message")
  )
}
#> # A tibble: 4 x 2
#>   test                      message                                 
#>   <chr>                     <chr>                                   
#> 1 properties of mtcars      success                                 
#> 2 properties of mtcars      success                                 
#> 3 properties of mtcars[1:3] success                                 
#> 4 properties of mtcars[1:3] mtcars[1:3] has length 3, not length 11.

Created on 2018-06-19 by the reprex package (v0.2.0).

So...

I know I'm not using testthat the way its intended ... but I am pretty happy with what I came up with so far. I am hoping to hear if you all have better approaches.