【问题标题】:r - data.table and testthat packager - data.table 和 testthat 包
【发布时间】:2016-08-01 12:41:46
【问题描述】:

我正在构建一个与 data.table 一起使用的包,并且应该使用包 testthat 对其进行测试。 虽然从命令行调用时代码工作正常,但从测试用例调用时遇到问题。运行测试时似乎使用了基本包中的 [] 函数,即 data.frames 的函数。

我创建了一个最小示例,可以在这里找到:https://github.com/utalo/test_datatable_testthat

该包包含一个函数:

test <- function() {
   dt <- data.table(MESSAGE="Test 1234567890",TYPE="ERROR")
   dt[,.(MESSAGE=strwrap(MESSAGE,width = 10)),by=.(TYPE)]
}

当从命令行调用test.datatable.testthat:::test() 时,我得到了预期的结果:

    TYPE    MESSAGE
 1: ERROR       Test
 2: ERROR 1234567890

但是,在执行以下单元测试时:

test_that("Test package",{
  dt <- test()

  expected_res <- structure(list(TYPE = c("ERROR", "ERROR"),
                             MESSAGE = c("Test","1234567890")),
                        row.names = c(NA, -2L), class = c("data.table","data.frame"),
                        .Names = c("TYPE", "MESSAGE"))

  expect_equal(dt,expected_res)
})

我收到一个错误:

1
1. Error: Test package -------------------------------------------------------------------------------------------------------
could not find function "."
1: withCallingHandlers(eval(code, new_test_environment), error = capture_calls, message = function(c) invokeRestart("muffleMessage"))
2: eval(code, new_test_environment)
3: eval(expr, envir, enclos)
4: test() at test.R:4
5: dt[, .(MESSAGE = strwrap(MESSAGE, width = 10)), by = .(TYPE)] at test.datatable.testthat/R/hello.R:5
6: `[.data.table`(dt, , .(MESSAGE = strwrap(MESSAGE, width = 10)), by = .(TYPE)) at C:\Users\D057806\Documents\R\test.datatable.testthat/R/hello.R:5
7: `[.data.frame`(x, i, j)

如您所见,在测试中调用了 data.frame 的 []。 我的第一个猜测是对 data.table 包的依赖没有正确声明。这是我的说明文件:

Package: test.datatable.testthat
Type: Package
Title: What the Package Does (Title Case)
Version: 0.1
Date: 2016-04-07
Authors@R: person("First", "Last", email = "first.last@example.com", role = c("aut", "cre"))
Description: More about what it does (maybe more than one line)
License: What license is it under?
LazyData: TRUE
Depends:
    data.table
Suggests:
     testthat
RoxygenNote: 5.0.1

根据Using data.table package inside my own package,将 data.table 声明为依赖包就足够了。但是,这里的情况似乎并非如此。

关于为什么我的函数在被直接调用而不是在 testthat 的上下文中可以正常工作的任何线索?

【问题讨论】:

  • 如果您导入 data.table,并将import(data.table) 添加到您的命名空间,问题是否仍然存在?我问是因为我想到了this post.. 我猜这与testthat 是同样的问题。
  • @Arun 感谢您的指点!这似乎是问题的一部分。如果我将依赖语句更改为 import 它在测试示例中有效,但在我的原始代码中无效。我将尝试在示例中重现此行为。
  • 那是新的.. 您是否也将 import(data.table) 添加到您的 NAMESPACE 中?
  • 是的,我做到了。同时我可以解决原始编码中的问题。出于某种原因,我的一个 data.tables 在应用 rbind 之后变成了一个列表,即使在应用 setDT 之后它仍然是一个列表。我必须使用 as.data.table 显式复制并转换为 data.table。我也在尝试在示例中重现这一点。
  • @utal 最近版本的 testthat 和 data.table 对您来说仍然是个问题吗?我的回答适用吗?

标签: r data.table r-package testthat


【解决方案1】:

渴望评论所以发布作为答案。

  1. 不要在包名中使用下划线,这会违反标准。下划线将变为点。

  2. 无法真正告诉您为什么 testthat 无法处理您的测试。您可以尝试导出test 函数。它不会被导出,因此只能明确地与::: 一起使用。也许 testthat 在某种程度上依赖于此,不知道。

  3. 当我将测试移出 testthat 时,测试正在通过。如果您无法解决它,我会在 testthat 问题中寻求支持。

您可以看到我的 pkg 的 fork jangorecki/test_datatable_testthat(网址在几天后将无法使用,因此如果您想稍后访问它们,请获取更改)。
您的测试已移出tests/test.R 中的测试,内容如下。

dt <- test.datatable.testthat:::test()
expected_res <- structure(list(TYPE = c("ERROR", "ERROR"),
                               MESSAGE = c("Test","1234567890")),
                          row.names = c(NA, -2L), class = c("data.table","data.frame"),
                          .Names = c("TYPE", "MESSAGE"))
stopifnot(all.equal(dt,expected_res))

测试通过将其更改为虚拟来抑制测试,类似于TRUE==TRUE。 现在您的测试在测试之外定义,通过 OK。
相关部分来自00check.log

* checking tests ...
  Running ‘test.R’
  Running ‘testthat.R’
 OK
* DONE

【讨论】:

猜你喜欢
  • 2016-05-11
  • 2019-01-22
  • 1970-01-01
  • 2013-05-12
  • 2016-10-18
  • 2012-03-06
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
相关资源
最近更新 更多