RUnit を使う
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
[[UnitTest]] // [[RUnit(R ユニットテストフレームワーク)パ...
----
UnitTest は関数をテストするコードを記述することで,関数の...
[[RUnit:http://cran.md.tsukuba.ac.jp/src/contrib/Descript...
RUnit の使い方を簡単にまとめてみます.
* 仕様を決める
これから定義する関数の満たすべき仕様を考えます.
和を求める mysum() を作成することにします.実際には sum()...
mysum() がクリアするべきテストのひとつとして,
mysum(1:10) == 55
がすぐに思い浮かびます.
* テスト
ワーキングディレクトリに tests.R ファイルを作成します.
** その 1
tests.R に test.mysum() を記述.慣習として,test.テストす...
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
そして,おもむろに runTestFile() します.
> runTestFile("tests.R")
Error in data.class(target) : couldn't find function "m...
Timing stopped at: 0 0 0 0 0
Number of test functions: 1
Number of errors: 1
Number of failures: 0
テストは失敗します.まだ mysum() を定義していませんので当...
** その 2
mysum() を定義します.
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
mysum <- function(x) {
}
再びテストを実行します.
> runTestFile("tests.R")
Error in checkEqualsNumeric(mysum(1:10), 55) :
Mean relative difference: 10
Timing stopped at: 0 0 0 0 0
Number of test functions: 1
Number of errors: 0
Number of failures: 1
今回も失敗しますが,エラーメッセージは異なります.これは ...
といっても,この場合 mysum() がなにもしていない(ので,返...
** その 3
mysum() のバグを潰す.具体的には sum() の値を返すことにし...
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
mysum <- function(x) {
sum(x
}
そしてテスト.
> runTestFile("tests.R")
Error in parse(file, n, text, prompt) : syntax error on...
Number of test functions: 1
Number of errors: 1
Number of failures: 0
あれ? エラーになってしまいました.
Number of erros: には関数にエラーがあるということを示して...
** その 4
で,今回はそもそもスクリプトが間違っている(sum() の括弧...
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
mysum <- function(x) {
sum(x)
}
そしてテストする.
> runTestFile("tests.R")
Number of test functions: 1
Number of errors: 0
Number of failures: 0
やたっ♪ 成功しました.
*コメント
-すみません.理解不足なコメントかもしれませんが,R に用意...
- 新しく書いた関数が,正しい処理をしているかどうかは,答...
正解と関数が出す答えをどうやって比較するかですが,たと...
計算に複数の条件によって答えが違うような場合には,あら...
答えが複数(たとえば相関係数行列や因子分析の結果のよう...
OS のセキュリティホールが後になっていろいろ発見されるの...
プログラムをちゃんと設計してから書き始めるとか,細かい...
-当該の関数を書く以前にその関数をテストするための関数を用...
-恐れ入りますが,2 つめのコメントの主旨はなんでしょうか....
-RUnit の効用は限られているのではないかと言うことでは?
-どのような効用が,どのように限られているのでしょうか. -...
-UnitTest のフレームワークが,すでに議論された時代遅れの...
-あるいは R においては,それほど有効性はないだろうという...
-複雑な解を返す関数のチェックをするためには大変な思いをし...
-その場合,複数個のテストを行なえばよいのではないでしょう...
-件のコメントにも書いてありますが,あるデータセットを因子...
-複数の返値があるから大変である,ということでしょうか? -...
-以下のようにすればよいということでしょうね。
test.my.oneway.ANOVA <- function()
{
# equal=TRUE のときのチェック
result <- my.oneway.ANOVA(c(8, 11, 22, 6),
c(135.83, 160.49, 178.35, 188.06),
c(19.59, 12.28, 15.01, 9.81)^2)
checkEqualsNumeric(c(13669.396, 3, 4556.4655,
20.82824, 1.737484e-8, 9406.843...
218.7638, 99999, 99999, 23076.2...
501.6574, 99999, 99999), as.num...
tolerance=0.000001)
# equal=FALSE のときのチェック
result <- my.oneway.ANOVA(c(8, 11, 22, 6),
c(135.83, 160.49, 178.35, 188.06),
c(19.59, 12.28, 15.01, 9.81)^2,
equal=FALSE)
checkEqualsNumeric(c(result$F, result$df1, result$df2, ...
c(17.56461,3,16.50403,2.191921e-05),
tolerance=0.000001)
}
my.oneway.ANOVA <- function(n, m, u, equal=T)
{
# stopifnot(length(n) == length(m), length(m) == leng...
n > 1, u > 0, floor(n) == n)
ng <- length(n)
if (equal) { # 分散が等しいと仮定する場合
nc <- sum(n)
sw <- sum(u*(n-1))
sb <- sum(n*(m-sum(n*m)/nc)^2)
ss <- c(sb, sw, sb+sw)
df <- c(ng-1, nc-ng, nc-1)
ms <- ss/df
f <- p <- rep(99999, 3)
f[1] <- ms[1]/ms[2]
p[1] <- pf(f[1], df[1], df[2], lower = F)
anova.table <- cbind(ss, df, ms, f, p)
colnames(anova.table) <- c("SS", "d.f.", "MS", "...
rownames(anova.table) <- c("between class", "wit...
anova.table
}
else { # 分散が等しいと仮定しない場合
w <- n/u
m0 <- sum(w*m)/(sum.w <- sum(w))
temp <- sum((1-w/sum.w)^2/(n-1))/(ng^2-1)
f <- sum(w*(m-m0)^2)/((ng-1)*(1+2*(ng-2)*temp))
p <- pf(f, ng-1, 1/(3*temp), lower=F)
list(F=f, df1=ng-1, df2=1/(3*temp), P=p)
}
}
まだテストしなくてはならない項目があるが,一応。 -- &new...
-これ以降 oneway.ANOVA() の中身を最適化などの理由で変更し...
-テストデータと,そのときの結果を記録したファイルを残して...
-> テストデータと,そのときの結果を記録したファイルを残し...
それをフレームワークにしたものが UnitTest です -- &new{2...
-相当複雑な出力を持つ実用的な関数について,実現してみてく...
-ついでに。グラフィック出力が結果である関数については無力...
-実用的な関数の内部で用いる純粋な計算を行うような関数の T...
-グラフィック出力の場合,プロットの基となるデータの整合性...
#comment
終了行:
[[UnitTest]] // [[RUnit(R ユニットテストフレームワーク)パ...
----
UnitTest は関数をテストするコードを記述することで,関数の...
[[RUnit:http://cran.md.tsukuba.ac.jp/src/contrib/Descript...
RUnit の使い方を簡単にまとめてみます.
* 仕様を決める
これから定義する関数の満たすべき仕様を考えます.
和を求める mysum() を作成することにします.実際には sum()...
mysum() がクリアするべきテストのひとつとして,
mysum(1:10) == 55
がすぐに思い浮かびます.
* テスト
ワーキングディレクトリに tests.R ファイルを作成します.
** その 1
tests.R に test.mysum() を記述.慣習として,test.テストす...
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
そして,おもむろに runTestFile() します.
> runTestFile("tests.R")
Error in data.class(target) : couldn't find function "m...
Timing stopped at: 0 0 0 0 0
Number of test functions: 1
Number of errors: 1
Number of failures: 0
テストは失敗します.まだ mysum() を定義していませんので当...
** その 2
mysum() を定義します.
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
mysum <- function(x) {
}
再びテストを実行します.
> runTestFile("tests.R")
Error in checkEqualsNumeric(mysum(1:10), 55) :
Mean relative difference: 10
Timing stopped at: 0 0 0 0 0
Number of test functions: 1
Number of errors: 0
Number of failures: 1
今回も失敗しますが,エラーメッセージは異なります.これは ...
といっても,この場合 mysum() がなにもしていない(ので,返...
** その 3
mysum() のバグを潰す.具体的には sum() の値を返すことにし...
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
mysum <- function(x) {
sum(x
}
そしてテスト.
> runTestFile("tests.R")
Error in parse(file, n, text, prompt) : syntax error on...
Number of test functions: 1
Number of errors: 1
Number of failures: 0
あれ? エラーになってしまいました.
Number of erros: には関数にエラーがあるということを示して...
** その 4
で,今回はそもそもスクリプトが間違っている(sum() の括弧...
### tests.R
test.mysum <- function() {
checkEqualsNumeric(mysum(1:10), 55)
}
mysum <- function(x) {
sum(x)
}
そしてテストする.
> runTestFile("tests.R")
Number of test functions: 1
Number of errors: 0
Number of failures: 0
やたっ♪ 成功しました.
*コメント
-すみません.理解不足なコメントかもしれませんが,R に用意...
- 新しく書いた関数が,正しい処理をしているかどうかは,答...
正解と関数が出す答えをどうやって比較するかですが,たと...
計算に複数の条件によって答えが違うような場合には,あら...
答えが複数(たとえば相関係数行列や因子分析の結果のよう...
OS のセキュリティホールが後になっていろいろ発見されるの...
プログラムをちゃんと設計してから書き始めるとか,細かい...
-当該の関数を書く以前にその関数をテストするための関数を用...
-恐れ入りますが,2 つめのコメントの主旨はなんでしょうか....
-RUnit の効用は限られているのではないかと言うことでは?
-どのような効用が,どのように限られているのでしょうか. -...
-UnitTest のフレームワークが,すでに議論された時代遅れの...
-あるいは R においては,それほど有効性はないだろうという...
-複雑な解を返す関数のチェックをするためには大変な思いをし...
-その場合,複数個のテストを行なえばよいのではないでしょう...
-件のコメントにも書いてありますが,あるデータセットを因子...
-複数の返値があるから大変である,ということでしょうか? -...
-以下のようにすればよいということでしょうね。
test.my.oneway.ANOVA <- function()
{
# equal=TRUE のときのチェック
result <- my.oneway.ANOVA(c(8, 11, 22, 6),
c(135.83, 160.49, 178.35, 188.06),
c(19.59, 12.28, 15.01, 9.81)^2)
checkEqualsNumeric(c(13669.396, 3, 4556.4655,
20.82824, 1.737484e-8, 9406.843...
218.7638, 99999, 99999, 23076.2...
501.6574, 99999, 99999), as.num...
tolerance=0.000001)
# equal=FALSE のときのチェック
result <- my.oneway.ANOVA(c(8, 11, 22, 6),
c(135.83, 160.49, 178.35, 188.06),
c(19.59, 12.28, 15.01, 9.81)^2,
equal=FALSE)
checkEqualsNumeric(c(result$F, result$df1, result$df2, ...
c(17.56461,3,16.50403,2.191921e-05),
tolerance=0.000001)
}
my.oneway.ANOVA <- function(n, m, u, equal=T)
{
# stopifnot(length(n) == length(m), length(m) == leng...
n > 1, u > 0, floor(n) == n)
ng <- length(n)
if (equal) { # 分散が等しいと仮定する場合
nc <- sum(n)
sw <- sum(u*(n-1))
sb <- sum(n*(m-sum(n*m)/nc)^2)
ss <- c(sb, sw, sb+sw)
df <- c(ng-1, nc-ng, nc-1)
ms <- ss/df
f <- p <- rep(99999, 3)
f[1] <- ms[1]/ms[2]
p[1] <- pf(f[1], df[1], df[2], lower = F)
anova.table <- cbind(ss, df, ms, f, p)
colnames(anova.table) <- c("SS", "d.f.", "MS", "...
rownames(anova.table) <- c("between class", "wit...
anova.table
}
else { # 分散が等しいと仮定しない場合
w <- n/u
m0 <- sum(w*m)/(sum.w <- sum(w))
temp <- sum((1-w/sum.w)^2/(n-1))/(ng^2-1)
f <- sum(w*(m-m0)^2)/((ng-1)*(1+2*(ng-2)*temp))
p <- pf(f, ng-1, 1/(3*temp), lower=F)
list(F=f, df1=ng-1, df2=1/(3*temp), P=p)
}
}
まだテストしなくてはならない項目があるが,一応。 -- &new...
-これ以降 oneway.ANOVA() の中身を最適化などの理由で変更し...
-テストデータと,そのときの結果を記録したファイルを残して...
-> テストデータと,そのときの結果を記録したファイルを残し...
それをフレームワークにしたものが UnitTest です -- &new{2...
-相当複雑な出力を持つ実用的な関数について,実現してみてく...
-ついでに。グラフィック出力が結果である関数については無力...
-実用的な関数の内部で用いる純粋な計算を行うような関数の T...
-グラフィック出力の場合,プロットの基となるデータの整合性...
#comment
ページ名: