当涉及S4代码时,testthat :: auto_test()似乎失败了

时间:2012-10-29 19:08:21

标签: r unit-testing autotest s4 testthat

在过去的几周里,我越来越多地将testthat软件包的单元测试功能集成到我的日常工作中,真的不得不说:这个软件包很棒!

我特别喜欢自动测试功能,它会自动运行您的所有单元测试每次您在代码中的某处进行更改。但是,当您的代码目录包含S4定义(类,泛型方法,自定义方法)时,我认为在使用testthatauto_test()函数时遇到了一个小错误或至少一些不良行为。

问题

使用auto_test()

时,此行为是否显示为错误或我做错了什么?

您将在下面找到需要先创建一些示例文件的插图

预赛

设置工作目录

setwd("testthat_autotest")

确保目录

dir.create("src", showWarnings=FALSE)
dir.create("tests", showWarnings=FALSE)

创建S4参考类定义

在目录classes.R

中创建文件src
def <- c(
    "setRefClass(",
    "   Class=\"MyClass\",",
    "   fields=list(",
    "       name=\"character\"",
    "   ),",
    "   methods=list(",
    "       getName=function(...) {",
    "           getName_ref(.self=.self, ...)",
    "       },",
    "       setName=function(...) {",
    "           setName_ref(.self=.self, ...)",
    "       }",
    "   )",
    ")"
)
write(def, file="src/classes.R")

创建通用方法定义

在目录generics.R

中创建文件src
def <- c(
    "setGeneric(",
    "    name=\"getName_ref\",",
    "    signature=c(\".self\"),",
    "    def=function(",
    "        .self,",
    "        ...",
    "    ) {",
    "standardGeneric(\"getName_ref\")",    
    "   }",
    ")",
    "",
    "setGeneric(",
    "   name=\"setName_ref\",",
    "   signature=c(\".self\"),",
    "   def=function(",
    "       .self,",
    "       value,",
    "       ...",
    "   ) {",
    "   standardGeneric(\"setName_ref\")",    
    "   }",
    ")"
)
write(def, file="src/generics.R")

创建自定义方法定义

在目录methods.R

中创建文件src
def <- c(
    "require(\"compiler\")",
    "",
    "setMethod(",
    "   f=\"getName_ref\",", 
    "   signature=signature(.self=\"MyClass\"),", 
    "   definition=cmpfun(function(",
    "       .self,",
    "       ...",
        ") {",
        "out <- .self$name",
        "return(out)",
        "}, options=list(suppressAll=TRUE))",  
    ")",
    "setMethod(",
    "   f=\"setName_ref\",", 
    "   signature=signature(.self=\"MyClass\"),", 
    "   definition=cmpfun(function(",
    "       .self,",
    "       ...",
    "   ) {",
    "   .self$field(name=\"name\", value=value)",
    "   return(TRUE)",
    "   }, options=list(suppressAll=TRUE))",  
    ")"
)
write(def, file="src/methods.R")

创建单元测试

在目录test_getName_ref.R

中创建文件test_setName_ref.Rtests
test <- c(
    "require(\"testthat\")",
    "",
    "test_that(desc=\"test_getName_ref,.self=MyClass\",",
    "   code={",
    "       x.target <- \"some value\"",
    "       expect_that(",
    "            .self <- new(\"MyClass\", name=x.target),",
    "            is_a(\"MyClass\")",
    "        )",
    "        expect_that(",
    "            x.test <- .self$getName(),",
    "            is_a(\"character\")",
    "        )",
    "        expect_that(",
    "            x.test,",
    "            is_identical_to(x.target)",
    "        )",
    "    }",
    ")"
)
write(test, file="tests/test_getName_ref.R")

test <- c(
    "require(\"testthat\")",
    "",
    "test_that(desc=\"test_setName_ref,.self=MyClass\",",
    "   code={",
    "       x.target <- \"some value\"",
    "       expect_that(",
    "            .self <- new(\"MyClass\"),",
    "            is_a(\"MyClass\")",
    "        )",
    "        expect_that(",
    "            .self$setName(value=x.target),",
    "            is_identical_to(TRUE)",
    "        )",
    "        expect_that(",
    "            .self$getName(),",
    "            is_identical_to(x.target)",
    "        )",
    "    }",
    ")"
)
write(test, file="tests/test_setName_ref.R")

插图

运行auto_test()会导致错误:

require("testthat")

auto_test(
    code_path="src",
    test_path="tests"
)
Loading required package: compiler
.1.2

1. Error: test_getName_ref,.self=MyClass ---------------------------------------
could not find function "getName_ref"
1: expect_that(x.test <- .self$getName(), is_a("character"))
2: condition(object)
3: str_c(class(x), collapse = ", ")
4: Filter(function(x) length(x) > 0, list(...))
5: sapply(x, f)
6: lapply(X = X, FUN = FUN, ...)
7: .self$getName()

2. Error: test_setName_ref,.self=MyClass ---------------------------------------
could not find function "setName_ref"
1: expect_that(.self$setName(value = x.target), is_identical_to(TRUE))
2: condition(object)
3: all.equal(expected, actual)
4: all.equal.default(expected, actual)
5: all.equal.raw(target, current, ...)
6: attr.all.equal(target, current, ...)
7: mode(current)
8: .self$setName(value = x.target)

我的第一个猜测是它可能与testthat::source_dir()处理采购的方式有关,可能是由于参数env

为了继续,我们需要使用CRTL + BREAK关闭自动测试(在Windows上;如果您在其他平台上,请参阅section "Autotest" in this article

现在,当我们首先手动获取代码并运行test_dir()时,一切似乎都运行良好:

require("testthat")

sapply(list.files("src", full.names=TRUE), source)

test_dir("tests")

......
You are a coding rockstar! 
> 

0 个答案:

没有答案