Day15: Unit tests

Posted by csiu on March 11, 2017 | with: 100daysofcode

Yesterday I presented hmmpickr, an R package to quantitatively help pick the hidden Markov model whose states are the most well-defined. Today we add some unit tests.

Unit testing

Unit testing is a level of software testing where individual units/components of a software are tested. The purpose is to validate that each unit of the software performs as designed. (From Software Testing Fundamentals)

[Unit testing] is a very efficient and easy way to make sure all your functions are working properly and to detect bugs in your code as soon as possible (Thiago G. Martins, 2013)

testthat

I make use of the testthat package to add unit tests to my R package. testthat is a package developed by Hadley Wickham to “make testing as fun as possible”.

Basic architecture

A tests/ directory is created and inside this directory is a test-all.R script which uses testthat::test_check(...) to tell R to run all tests in an installed package. Tests should be placed in tests/testthat/.

|-- DESCRIPTION
|-- NAMESPACE
|-- R/
|-- man/

|-- tests/
|   |-- test-all.R
|   |-- testthat/
|   |   |-- ...

Unit tests can be ran automatically with R CMD check.

Example:

context("Loading")

test_that("load_chromhmm_model creates a list of 3", {
  model_file <-
    system.file("extdata", "model_roadmap15.txt", package="hmmpickr")

  m <- load_chromhmm_model(model_file)

  expect_that(m, is_a("list"))

  expect_length(m, 3)

  expect_equal(names(m), c("num_states", "emissions", "transitions"))

  expect_that(m$num_states, is_a("numeric"))
  expect_that(m$emissions, is_a("data.frame"))
  expect_that(m$transitions, is_a("data.frame"))

  expect_equal(names(m$emissions), c("state", "mark", "markname", "prob"))
  expect_equal(names(m$transitions), c("from", "to", "prob"))
})

A good practice is to first run the unit tests before committing changes to the code.