メモ:testthat 2.0.0でtidyevalが使えるようになるらしい

「Quasiquotation support」というのがtestthatの次期リリースのNEWSに書かれていて、なんだこれと思ったのでメモ。

話は飛ぶけど、table driven testというのがある(Goでよく出てくる)。テストケースを並べていって次々にテストするというやつ。

Rでやるとすればたぶんこんな感じでテストケースを並べて、

library(testthat)

# 小文字を大文字にする関数のテストケース
test_cases <- purrr::transpose(
  tibble::tribble(
    ~input, ~expected,
       "a",       "A",
       "b",       "B",
       "c",       "C",
       "d",       "d"   # これはテストケースを間違えている
  )
)

str(test_cases)
#> List of 4
#>  $ :List of 2
#>   ..$ input   : chr "a"
#>   ..$ expected: chr "A"
#>  $ :List of 2
#>   ..$ input   : chr "b"
#>   ..$ expected: chr "B"
#>  $ :List of 2
#>   ..$ input   : chr "c"
#>   ..$ expected: chr "C"
#>  $ :List of 2
#>   ..$ input   : chr "d"
#>   ..$ expected: chr "d"

こんな感じでforループなりpurrr::walk()なりでテストを回すことになる。

for (x in test_cases) {
  expect_equal(toupper(x$input), x$expected)
}

と、上にコメント書いたように4つ目が間違ってるのでエラーになるけど、メッセージがちょっとわかりにくい。x$inputx$expectedに何が入っているかわからない。

#> Error: toupper(x$input) not equal to x$expected.
#> 1/1 mismatches
#> x[1]: "D"
#> y[1]: "d"

これを!!を使ってunquoteしとけば、エラーメッセージが

for (x in test_cases) {
  expect_equal(toupper(!! x$input), !! x$expected)
}
#> Error: toupper("d") not equal to "d".
#> 1/1 mismatches
#> x[1]: "D"
#> y[1]: "d"

となってわかりやすいよね、ということらしい。