CircleCIは、テスト結果をJUnitかCucumberの形式で渡すとサマリをいい感じに表示してくれます。
なんだRとは縁のない話か、と思ってたら、testthat 2.0.0で、
New
JunitReporter
generates reports in JUnit compatible format. (https://github.com/r-lib/testthat/blob/cb5db4aed48c0e155ac9e9fe2709f61ee23c2c50/NEWS.md#reporters)
とのことなのでやってみました。
試しに作ってみたレポジトリはこれです:
※現時点(testthat 2.0.0未リリース)でこれを試すには、DESCRIPTION
にRemotes: r-lib/testthat
を指定してください。
Reporterの指定
testthatは、Reporterを指定することでテスト結果の出力を変えることができます。Reporterの種類は以下に記載があります。
どこに指定すればいいかというと、ドキュメントがうまく見つけられなかったのであってるか自信がないんですが、test_check()
のreporter
引数みたいです。(set_reporter()
でもいけそうだけどよくわかりませんでした...)
JunitReporter
はR6クラスなので、new()
で生成したインスタンスを渡します。new()
に指定するのはfile
という引数で、デフォルトだとstdout()
になっています。スーパークラスのReporter
の定義はこう:
initialize = function(file = getOption("testthat.output_file", stdout())) { self$out <- file if (is.character(self$out) && file.exists(self$out)) { # If writing to a file, overwrite it if it exists file.remove(self$out) } }
(https://github.com/r-lib/testthat/blob/cb5db4aed48c0e155ac9e9fe2709f61ee23c2c50/R/reporter.R#L24)
これに、拡張子が.xml
の適当なファイル名を指定します。
test_check("testthatJunitRporterTest", reporter = JunitReporter$new(file = "junit_result.xml"))
CircleCIの設定ファイル
JunitReporter
によって吐き出されるファイルの場所にもよりますが、上の設定であればtests
ディレクトリにjunit_result.xml
ができるので、store_test_results
にはを指定します。
- store_test_results: path: /tmp/Rcheck/tests/ when: always
全部書くとこんな感じです。(他の部分の説明はRのテストにCircleCIを使う - Technically, technophobic.に書いたのでそっちを見てください)
defaults: &steps steps: - checkout ## setup ------------------------------- - run: name: Set environmental variables command: | Rscript --vanilla \ -e 'dsc <- read.dcf("DESCRIPTION")' \ -e 'cat(sprintf("export PKG_TARBALL=%s_%s.tar.gz\n", dsc[,"Package"], dsc[,"Version"]))' \ -e 'cat(sprintf("export RCHECK_DIR=%s.Rcheck\n", dsc[,"Package"]))' \ >> ${BASH_ENV} ## install dependencies ------------------ - run: name: Install devtools and dependencies command: | Rscript \ -e 'if (!requireNamespace("devtools", quietly = TRUE)) install.packages("devtools")' \ -e 'devtools::install_deps(dependencies = TRUE)' ## build and test ----------------- - run: name: Build package command: R CMD build . - run: name: Check package command: R CMD check "${PKG_TARBALL}" --as-cran --no-manual - run: name: Check failures command: | Rscript -e "message(devtools::check_failures(path = '${RCHECK_DIR}'))" # warnings are errors # - run: if grep -q -R "WARNING" "${RCHECK_DIR}/00check.log"; then exit 1; fi ## store artifacts ----------------- - run: command: mv ${RCHECK_DIR} /tmp/Rcheck when: always - store_test_results: path: /tmp/Rcheck/tests/ when: always - store_artifacts: path: /tmp/Rcheck when: always version: 2 jobs: "r-release": docker: - image: rocker/tidyverse:latest <<: *steps "r-devel": docker: - image: rocker/tidyverse:devel <<: *steps workflows: version: 2 build_and_test: jobs: - "r-release" - "r-devel"
結果
こうなりました。わかりやすくていいですね。
(https://circleci.com/gh/yutannihilation/testthatJunitRporterTest/25)