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.”