使用data.table和testthat

时间:2016-02-02 11:38:43

标签: r data.table r-package testthat

我目前正在为我的软件包构建一系列测试,并希望构建以下测试以确保函数在data.table中有效。测试如下:

# Load libraries
library(data.table)
library(testthat)

# Creating a test case
test.case <- data.table(V1 = c(1,2,3,NaN,5,Inf,7,8,9,-Inf),
                        V2 = 1:10,
                        V3 = c(NA,2:4,NaN,6:9,Inf))

# Source of the error
test.case <- test.case[,lapply(.SD,findHorrificValues)]

# Creating a comparison
comparison <- data.table(V1 = c(F,F,F,T,F,T,F,F,F,T),
                         V2 = rep(F,10),
                         V3 = rep(c(F,F,F,F,T),2))


value <- identical(test.case,comparison)

# Perform test
test_that("Compare two data.table objects",{expect_true(value)})

请注意,函数findHorrificValues()定义为:

findHorrificValues <- function(data) {
    is.nan(data) | is.infinite(data)
}

当作为脚本执行时,代码没有问题,但是当作为测试执行脚本时,我收到以下错误:

> devtools::test(fresh = T)
Loading packageName
Testing packageName
.
Error in .subset(x, j) : invalid subscript type 'list'
> traceback()
12: `[.data.frame`(x, i, j)
11: `[.data.table`(test.case, , lapply(.SD, findHorrificValues)) at test_fail.R#14
10: test.case[, lapply(.SD, findHorrificValues)] at test_fail.R#14
9: eval(expr, envir, enclos)
8: eval(exprs, envir)
7: sys.source2(fname, new.env(parent = env))
6: FUN(X[[i]], ...)
5: lapply(paths, test_file, env = env, reporter = current_reporter, 
       start_end_reporter = FALSE)
4: testthat::test_dir(test_path, filter = filter, env = env, ...)
3: force(code)
2: with_envvar(r_env_vars(), testthat::test_dir(test_path, filter = filter, 
       env = env, ...))
1: devtools::test(fresh = T)

我确保data.table在我的包描述中既是导入又是依赖。由于正在调用data.table函数,因此它似乎不是问题的根源。知道造成错误的原因是什么吗?这可能是testthat和data.table的组合问题(两个包中的函数都出现在堆栈跟踪中)?

1 个答案:

答案 0 :(得分:1)

我已将您的代码放入一个只有一个函数findHorrificValues的包中 glen包导入data.table 下面提供的包的内容,因为链接的回购可能很快就会被删除(如果您不想将其保留在您的回购中,您可以将其分叉并更新此处的链接)。

tests/tests.R

library(data.table)
library(glen)

# Creating a test case
test.case <- data.table(V1 = c(1,2,3,NaN,5,Inf,7,8,9,-Inf),
                        V2 = 1:10,
                        V3 = c(NA,2:4,NaN,6:9,Inf))

# Source of the error
test.case <- test.case[,lapply(.SD,findHorrificValues)]

# Creating a comparison
comparison <- data.table(V1 = c(F,F,F,T,F,T,F,F,F,T),
                         V2 = rep(F,10),
                         V3 = rep(c(F,F,F,F,T),2))

value <- identical(test.case,comparison)

stopifnot(value)

print(value)

glen.Rcheck/00check.log

* using log directory ‘/home/jan/Projects/glen.Rcheck’
* using R version 3.2.3 (2015-12-10)
* using platform: x86_64-pc-linux-gnu (64-bit)
* using session charset: UTF-8
* using options ‘--no-manual --no-build-vignettes --as-cran’
* checking for file ‘glen/DESCRIPTION’ ... OK
* checking extension type ... Package
* this is package ‘glen’ version ‘0.1.0’
* checking package namespace information ... OK
* checking package dependencies ... OK
* checking if this is a source package ... OK
* checking if there is a namespace ... OK
* checking for executable files ... OK
* checking for hidden files and directories ... OK
* checking for portable file names ... OK
* checking for sufficient/correct file permissions ... OK
* checking whether package ‘glen’ can be installed ... OK
* checking installed package size ... OK
* checking package directory ... OK
* checking DESCRIPTION meta-information ... NOTE
Malformed Description field: should contain one or more complete sentences.
Non-standard license specification:
  What license is it under?
Standardizable: FALSE
* checking top-level files ... OK
* checking for left-over files ... OK
* checking index information ... OK
* checking package subdirectories ... OK
* checking R files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking whether the package can be loaded ... OK
* checking whether the package can be loaded with stated dependencies ... OK
* checking whether the package can be unloaded cleanly ... OK
* checking whether the namespace can be loaded with stated dependencies ... OK
* checking whether the namespace can be unloaded cleanly ... OK
* checking loading without being on the library search path ... OK
* checking dependencies in R code ... OK
* checking S3 generic/method consistency ... OK
* checking replacement functions ... OK
* checking foreign function calls ... OK
* checking R code for possible problems ... OK
* checking Rd files ... OK
* checking Rd metadata ... OK
* checking Rd line widths ... OK
* checking Rd cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... OK
* checking Rd \usage sections ... OK
* checking Rd contents ... OK
* checking for unstated dependencies in examples ... OK
* checking examples ... NONE
* checking for unstated dependencies in ‘tests’ ... OK
* checking tests ... OK
  Running ‘tests.R’
* DONE
Status: 1 NOTE

glen.Rcheck/tests/tests.Rout

R version 3.2.3 (2015-12-10) -- "Wooden Christmas-Tree"
Copyright (C) 2015 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> library(data.table)
> library(glen)
> 
> # Creating a test case
> test.case <- data.table(V1 = c(1,2,3,NaN,5,Inf,7,8,9,-Inf),
+                         V2 = 1:10,
+                         V3 = c(NA,2:4,NaN,6:9,Inf))
> 
> # Source of the error
> test.case <- test.case[,lapply(.SD,findHorrificValues)]
> 
> # Creating a comparison
> comparison <- data.table(V1 = c(F,F,F,T,F,T,F,F,F,T),
+                          V2 = rep(F,10),
+                          V3 = rep(c(F,F,F,F,T),2))
> 
> value <- identical(test.case,comparison)
> 
> stopifnot(value)
> 
> print(value)
[1] TRUE
> 
> proc.time()
   user  system elapsed 
  0.212   0.004   0.212