Download - Tokyor14 - R言語でユニットテスト
R 言語でユニットテスト
@yokkuns: 里 洋平2011.05.28 Tokyo.R#14
AGENDA● 自己紹介● RUnit とは● テストの実行● テストケースをチェックする● まとめ
AGENDA● 自己紹介● RUnit とは● テストの実行● テストケースをチェックする● まとめ
自己紹介● ID: yokkuns
● 名前 : 里 洋平● 職業 : データマイニングエンジニア
自己紹介Tokyo.R の主催をやっています!
AGENDA● 自己紹介● RUnit とは● テストの実行● テストケースをチェックする● まとめ
目的● R のコードの信頼性を高める● バグの出にくいコードを書けるようになる
R の普及● 統計解析やデータマイニングなどの需要● R を使う人が増えてきている
R の普及R 使いの人材募集とか
R の普及R 使いの人材募集とか
R の普及R 使いの人材募集とか
コードの質
良い結果が出ました!
コードの質
良い結果が出ました!
コードの質
良い結果が出ました!
実はバグでした・・・
ってことになると、非常にまずい
ユニットテスト通常の開発では、ユニットテストが行われている
● JUnit● CppUnit● PHPUnit● ...
ユニットテスト通常の開発では、ユニットテストが行われている
● JUnit● CppUnit● PHPUnit● ...
RUnitは、これらの R言語版
AGENDA● 自己紹介● RUnit とは● テストの実行● テストケースをチェックする● まとめ
RUnit を使う準備
install.packages(“RUnit”)
library(RUnit)
ファイルの配置● ここでは、以下のように配置
● R/sample.R● test/runit.sample.R
RUnit のやること● ある命名規則で定義されたテスト関数を実行● テストが成功したか否かを保存● 最後に結果を出力
命名規則テスト関数は、 test.×× という関数名
c2f <- function(c) { return(9/5 * c + 32)}
test.c2f <- function() { checkEquals(c2f(0), 32) checkEquals(c2f(10), 50) checkException(c2f("xx"))}
チェック関数● checkEquals● checkEqualsNumeric● checkTrue● checkException● checkIdentical● ...
意図していない挙動の例
hoge <- function(x) return( ifelse(x>20, "OK", "NG") )
> hoge(100)[1] "OK"
> hoge("100")[1] "NG"
> hoge("xx")[1] "OK"
テストの実行1 ファイルのテストを実行
● absFileName● テスト関数を書いてるファイル
runTestFile(absFileName)
テストの実行1 ファイルのテストを実行
> runTestFile("../test/runit.sample.R")
Executing test function test.c2f ... Error in 9/5 * c : non-numeric argument to binary operator done successfully.
Number of test functions: 1 Number of errors: 0 Number of failures: 0
テストスイート複数のファイルのテストを実行したい場合は
テストスイートを作成する
Testsuite ← defineTestSuite(name, dirs, testFileRegexp, ... )
runTestSuite(testsuite)
printTextProtocol(testData)printHTMLProtocol(testData)
テストスイート
> testsuite.c2f <- defineTestSuite(name = "c2f", dirs = "../test", testFileRegexp = "^runit.+\\.R" )
> testResult <- runTestSuite(testsuite.c2f)
テストスイート> printTextProtocol(testResult)RUNIT TEST PROTOCOL -- Sat May 28 08:45:02 2011 *********************************************** Number of test functions: 1 Number of errors: 0 Number of failures: 0
1 Test Suite : c2f - 1 test function, 0 errors, 0 failures
Details *************************** Test Suite: c2f Test function regexp: ^test.+ Test file regexp: ^runit.+\.R Involved directory: ../test --------------------------- Test file: ../test/runit.sample.R test.c2f: (3 checks) ... OK (0 seconds)
AGENDA● 自己紹介● RUnit とは● テストの実行● テストケースをチェックする● まとめ
テストケースは十分か?
自分で書いたテストケースが
全ての組み合わせに対して網羅しているか?
tracker の初期化コードをトラッキンングするオブジェクトを生成
● ※ 変数名は、 track で無ければならない
track <- tracker()track$init()
コードの追跡コードのどこを通ったかを追跡する
inspect(expr, track = track)resTrack <- track$getTrackInfo()printHTML.trackInfo(object, baseDir = ".")
出力結果● 実行された回数が出力● 1 回も呼ばれてない行は赤色になる
テストに組み込む● テストを呼び出す箇所で、 tracker を初期化● テスト完了後、結果を出力する
track <- tracker()track$init()testsuite.c2f <- defineTestSuite(name = "c2f", dirs = "../test", testFileRegexp = "^runit.+\\.R" )testResult <- runTestSuite(testsuite.c2f)printTextProtocol(testResult)
printHTML.trackInfo(track$getTrackInfo(), "../test")
テストに組み込む● 条件式がある例を作成
bar <- function(x, y = NULL) { if (is.null(y)) { y <- x } if (all(y > 100)) { y <- y - 100 } res <- x^y return(res)}
テストに組み込む● check 関数のタイミングで組み込む
test.bar <- function() { checkTrue(is.numeric(inspect(bar(1:100), track)))}
出力結果漏れてるケースがないかが分かる
AGENDA● 自己紹介● RUnit とは● テストの実行● テストケースをチェックする● まとめ
まとめ● RUnit でコードの信頼性を高めることが出来る● Code Inspector でテストの漏れを発見出来る
AGENDA● 自己紹介● RUnit とは● テストの実行● テストケースをチェックする● まとめ
次回以降の発表者を募集しています!