testthatメモ

testthatパッケージを使ったので簡単なメモを残す。
詳しくはこちら参照のこと。
http://adv-r.had.co.nz/Testing.html

考え方

テストの粒度によって、expect、test、contextの3つが考慮されている。
粒度の大きさとしてはcontext>test>expectとなっている。
関数のテストはexpect単位で書いて、それをtestでまとめるというのが基本形。
規模が大きくなるとtestをさらにcontextでまとめる。

テストの書き方

以下のようにして作ったadd関数をテストしたいとする。

add <- function(x,y)x+y

現在の作業ディレクトリ直下にtestsフォルダを作り、そこにテストコードを書いたtest-sample.Rというファイルを用意する。

context("work numeric")
test_that("numeric add", {
  expect_that(add(1,2), equals(3))
  expect_that(add(-1,-1), equals(-2))
})

先ほどの階層構造にそれぞれexpect_that、test_that、contextが対応している。
context、test_thatはテストに失敗した時にどのテストで失敗したのかを
わかりやすくするためのもの、くらいの認識でいいと思う。
書き方としては以下のような感じ。
なおtest_thatの{}の中でのテストの区切りにカンマは不要なので注意。

expect_that(テスト, 正解の条件)
test_that(テストが失敗した時に出すメッセージ,{expect_thatで書かれたテスト})
context(テスト実行時に出すメッセージ)

expect_thatの正解の条件に使える関数は上記equal関数の他にも10種類ある。
以下ページ内の表を参照。
http://adv-r.had.co.nz/Testing.html

テストの実行

ファイルに対してテストを実行する場合はtest_file関数を使う。

library(testthat)
test_file("tests/test-sample.R")

下記のような結果が得られる。

> test_file("tests/test-sample.R")
work numeric : ..

実行結果の内容は以下の通り。

contextで指定したメッセージ: テストの状況(成功していればドット)

もう一つテストを用意してみる(test-sample2.R)。

context("work NA")
test_that("NA add", {
  expect_that(add(NA,2), equals(2))
})

NAの処理なんてしていないのでこのテストは失敗することが期待される。
先ほどのテストと併せて実行する際はフォルダ(ディレクトリ)単位で指定できるtest_dir関数を使う。
すると以下のような結果が得られ、実際2つ目に作ったテストファイルで失敗していることが把握できる。

> test_dir("tests")
work numeric : ..
work NA : 1

1. Failure(@test-sample2.R#3): NA add ---------------
           add(NA, 2) not equal to 2
           'is.NA' value mismatch: 1 in current 0 in target

他にもパッケージまるごとテストするtest_package関数や
自動的にテストするauto_test関数などがあるが使っていないので今回は省略した。
テストの実例はたとえば以下のggplot2のテストなど見たらよいと思う。
https://github.com/hadley/ggplot2/blob/master/inst/tests/test-aes-grouping.r
それでは快適なテストライフを!