Not minor. I've spent almost an equal amount of time fixing those issues in the past couple of years as I have actually developing code. Containerization freed me from caring about the state of everyone else's laptop, and allowed me to get back to work.
— Dr Mark Greenaway (@certifiedwaif) January 15, 2020
‘I started using automated tests because I discovered I was spending too much time re-fixing bugs that I’d already fixed before.’ - from Testing in R Packages (Wickham 2015)
context("String length")
library(stringr)
test_that("str_length is number of characters", {
  expect_equal(str_length("a"), 1)
  expect_equal(str_length("ab"), 2)
  expect_equal(str_length("abc"), 3)
})
test_that("str_length of factor is length of level", {
  expect_equal(str_length(factor("a")), 1)
  expect_equal(str_length(factor("ab")), 2)
  expect_equal(str_length(factor("abc")), 3)
})
| testing object | description | function | 
|---|---|---|
| expectation | atom of testing | expect_* | 
| test | a collection of expectations | test_that | 
| context | a collection of tests | context | 
# test for fixed positive number log(3)
## [1] 1.098612
# test for random positive number x <- rexp(1) # the exponential distribution only produces positive numbers log(x)
## [1] -2.978422
# test for fixed negative number log(-3)
## Warning in log(-3): NaNs produced
## [1] NaN
# test for random netgative number x <- -rexp(1) # the exponential distribution only produces positive numbers log(x)
## Warning in log(x): NaNs produced
## [1] NaN
# test for ugly string input
log("pig")
## Error in log("pig"): non-numeric argument to mathematical function
# test for random string input
x <- c("cat", "pig", "bird") %>% sample(1)
log(x)
## Error in log(x): non-numeric argument to mathematical function
When developing, we won’t test the good, the bad, and the ugly.
a minimal development test
A neet test checks the function outputs a non-empty thing of expected type.
# make a package in rstudio
usethis::create_package()
# set up testing in rstudio package
usethis::use_testthat()
# create a context file
usethis::use_test()
# add context to first line of context file
context("what these tests test")
quack <-
  function(says_the_duck = "quack!", 
           greeting = "quack! ") {
    paste0(greeting, 
           says_the_duck, 
           " said the duck")
  }
quack()
## [1] "quack! quack! said the duck"
quack("quack, quack!")
## [1] "quack! quack, quack! said the duck"
context("test that the duck quacks")
library(stringr)
expect_neet_quack <-
  function(quack_output) {
    expect_gte(
      str_length(quack_output), 
      1)
    expect_type(quack_output, 
                "character")
  }
test_that("duck quacks", {
  expect_neet_quack(quack())
  expect_neet_quack(
    quack("quack, quack!"))
})context("nas nans infs in confidence scores")
method_nans <- function(method_to_test) {
  cs <-
    expert_judgements_frankenstein %>%
    method_to_test() %>%
    purrr::pluck("cs")
  expect_false(NA %in% cs)
  expect_false(NaN %in% cs)
  expect_false(Inf %in% cs)
  expect_false(-Inf %in% cs)
  expect_false(any(cs < 0))
  expect_false(any(cs > 1))
  expect_false(any(cs == 0))
  expect_false(any(cs == 1))
  expect_is(cs, "numeric")
}
## Set panda = 68 to reproduce this panda.
## Set panda = 58 to reproduce this panda.
Gray, Charles T. 2019. “Code::Proof: Prepare for Most Weather Conditions.” In Statistics and Data Science, edited by Hien Nguyen, 22–41. Communications in Computer and Information Science (Preprint: Https://Arxiv.org/1910.06964.pdf). Singapore: Springer. https://doi.org/10.1007/978-981-15-1960-4_2.
Wickham, H. 2015. R Packages: Organize, Test, Document, and Share Your Code. O’Reilly Media.
Wickham, Hadley. 2011. “Testthat: Get Started with Testing.”
Wickham, Hadley, and Jennifer Bryan. 2019. “Usethis: Automate Package and Project Setup.”