我正在开发一个R应用程序并想出一个解决方法,通过向项目根目录添加一个文件来集成testthat(它通常需要你的项目成为一个包)DESCRIPTION.
我从同事那里获得了这种方法,并设法让它像这样工作.
问题是,当我尝试测试任何东西(甚至是空的测试文件)时,我收到此错误:
Error in x[[method]](...) : attempt to apply non-function
Calls: <Anonymous> ... <Anonymous> -> o_apply -> lapply -> FUN -> <Anonymous>
Execution halted
Run Code Online (Sandbox Code Playgroud)
我知道的是,这似乎只有在MacOS.我的同事仍可在Windows上运行此应用程序而不会出现问题.
这有什么用处?
用于重现此错误的MCVE将是:
创建DESCRIPTION包含内容的最小文件:
Package: testpckg
Run Code Online (Sandbox Code Playgroud)将testthat添加到您的项目中:
usethis::use_testthat()
usethis::use_test("foo")
Run Code Online (Sandbox Code Playgroud)bar.Rtest-foo.R,源栏:source("bar.R")RStudio版本1.1.447,R版本3.4.4,Mac OS X 10_13_4
在运行testthat测试时是否可以在RStudio中调用调试器?我无法找到允许此设置的设置(在设置中使用"使用devtools包功能"的各种组合,点击"Build - > More"菜单中的"Test Package"选项,test()在控制台中运行,投入browser()电话等),但还没有找到一种方法呢.
我还发现自己迷路了很多测试时,不确定是否正在运行已安装在系统库中的代码(做"构建和重新载入"),或正在运行就地从本地R目录,或者是什么-有时RStudio抱怨在重建包之前不能设置断点(所以我怀疑是前者)或者没有(所以我怀疑是后者).不确定这个问题是否与我的主要问题密切相关.
在没有找到进入调试器的方法的情况下,我最终将测试代码粘贴到控制台中并以非常特别的方式工作,并基本上将我的TDD习惯放在脚下.所以任何建议都会受到赞赏 - 如果无法调用调试器,任何建议的解决方法?
我在OS X上以本地模式运行RStudio版本0.99.447,使用R 3.2.1.
编辑 - 我也想知道更多关于选项的背景知识,例如"选项X永远不会支持调试,因为它在分叉的过程中运行,而是尝试使用其他选项Y".
更新 - 此处没有回复,我也在https://support.rstudio.com/hc/communities/public/questions/204779797-Debugging-testthat-tests-in-RStudio(我也没有响应).
我正在编写一个最终返回数据框的脚本.我的问题是,如果有任何关于如何使用单元测试包以确保返回的数据框是正确的良好实践.(我是R程序员的开始,加上单元测试的新概念)
我的脚本实际上如下所示:
# initialize data frame
df.out <- data.frame(...)
# function set
function1 <- function(x) {...}
function2 <- function(x) {...}
# do something to this data frame
df.out$new.column <- function1(df.out)
# do something else
df.out$other.new.column <- function2(df.out)
# etc ....
Run Code Online (Sandbox Code Playgroud)
......最终我得到了一个包含许多新列的数据框.但是,使用单元测试测试生成的数据帧是预期的最佳方法是什么?
到目前为止,我已经创建了单元测试来检查每个函数的结果,但我想确保将所有这些一起运行产生预期的结果.我查看了Hadley Wickham关于测试的页面,但是在返回数据帧时看不出有什么明显的事情要做.
我的想法是:
expect_that或类似检查输出是否等于此数据帧关于在哪里寻找指导的任何想法/指示?到目前为止,我的谷歌已经让我失望了.
我有一堆测试,我不希望它们在CRAN检查或Travis CI构建期间运行.它们要么长时间运行,要么可能导致写入网络数据库的事务/并发冲突.将它们分开的方法(来自R CMD检查测试)最适合测试吗?
我应该将这些测试放在单独的文件夹中吗?我应该标记他们的文件名并使用正则表达式吗?(例如,在test_package中使用filter参数跳过 @Jeroen的测试)
http://cran.r-project.org/web/packages/policies.html:
可以选择长时间运行的测试和插图代码进行检查,但确保剩下的检查确实可以执行包的所有功能.
我testthat用来检查我的包中的代码.我的一些测试用于基本功能,例如构造函数和getter.其他的则是基于基本功能构建的复杂功能.如果基本测试失败,那么预计复杂测试将失败,因此没有进一步的测试点.
是否有可能:
我在我的代码中从base调用一个函数,我想在我的testthat单元测试中模拟这个函数.
我怎样才能做到这一点?
library(testthat)
my.func <- function() {
return(Sys.info()["sysname"]) # e. g. "Linux"
}
my.func()
# sysname
# "Linux"
test_that("base function can be mocked",
with_mock(
Sys.info = function() return(list(sysname = "Clever OS")), # see edit 2 !!!
expect_equal(my.func(), "Clever OS", fixed = TRUE)
)
)
# Error: Test failed: 'base function can be mocked'
# * my.func() not equal to "Clever OS".
Run Code Online (Sandbox Code Playgroud)
?with_mock 说:
无法模拟基础包中的函数,但可以通过定义包装函数轻松解决此问题.
我可以Sys.info()通过我my.func从那时调用的包装器函数来封装基函数调用,但我们假设我不能这样做,因为我正在测试一个我无法更改的包中的函数...
对此有何解决方案?
我在Ubuntu 14.04上使用R3.4.4 64位,testthat为2.0.0.9000.
编辑1:
运用
`base::Sys.info` = function() …Run Code Online (Sandbox Code Playgroud) 对于给定的已安装软件包,如何运行其测试测试?我不是已安装软件包的开发人员,我是用户.我只是想运行它的测试套件来确认它的测试在我的环境中通过.我试过了test_check,test_package但我看到了错误.
更具体地说,我知道它的测试套件失败了,我想在交互式R会话中运行测试,所以我可以调试它.
> require(eplusr) # choice of package unimportant. Any using testthat will do.
Loading required package: eplusr
> require(testthat)
Loading required package: testthat
> test_check("eplusr")
Error in test_files(paths, reporter = reporter, env = env, stop_on_failure = stop_on_failure, :
No matching test file in dir
> test_package("eplusr")
Error: No tests found for eplusr
> sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.1 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so
locale:
[1] …Run Code Online (Sandbox Code Playgroud) tl;dr我想devtools::test()在一个包上运行并让它跳过测试等,就像它在 CRAN 上运行一样,但我不知道如何操作。
据我了解,testthat::skip_on_cran()检查环境变量NOT_CRAN,如果测试未在CRAN 上运行,则应将其设置为“true”值(为了支持这一点,底层测试函数testthat:::on_cran()等于
!identical(Sys.getenv("NOT_CRAN"), "true")
Run Code Online (Sandbox Code Playgroud)
我试图用来skip_on_cran()跳过一些测试。我想确认CRAN 上实际上会跳过这些测试。我有一条线
cat("ON CRAN:", testthat:::on_cran(), "\n")
Run Code Online (Sandbox Code Playgroud)
在我的测试文件中,以便我可以看到 R/testthat认为发生了什么。
如果我使用,环境变量会按照我想要的方式设置(即输出包括ON CRAN: FALSE)/测试被正确跳过)
source([testfile], echo = TRUE)
Run Code Online (Sandbox Code Playgroud)
NOT_CRAN(即,无需预先执行任何特殊操作来设置或取消设置环境变量)或
withr::with_envvar(c(NOT_CRAN = "false"),
devtools::test_active_file("tests/testthat/test-bootMer.R"))
Run Code Online (Sandbox Code Playgroud)
(如果我运行时test_active_file()没有包装它,我会得到ON CRAN: FALSE)。
但是,我没有看到devtools::test()以类似的方式运行所有测试(通过)的方法。换句话说,我不知道如何devtools::test()在“ON CRAN”模式下运行。 test()对此没有明确的参数(它有...“传递给包装函数的附加参数”,但我看不到任何相关的向下挖掘),并且使用withr::with_envvar()似乎没有帮助。devtools::check() 确实有一个明确的env_vars参数,但我希望能够运行测试而无需经历整个包检查过程......
抱歉,这不能完全重现;如果需要,我可以尝试构建一个最小的包来显示行为......
我testthat用来测试包含类似于以下文件树的包:
.
??? data
? ??? testhaplom.out
??? inst
? ??? test
? ??? test1.r
? ??? tmp_S7byVksGRI6Q
? ? ??? testm.desc
? ??? tmp_vBcIkMN1arbn
? ???testm.bin
? ??? testm.desc
??? R
? ??? haplom.r
? ??? winIdx.r
??? tmp_eUG3Qb0PKuiN
??? testhaplom.hap2.desc
Run Code Online (Sandbox Code Playgroud)
在test1.r文件中,我需要使用该data/testhaplom.out文件作为某个函数的输入数据,但如果我这样做test_file(test1.r),它将更改为inst/test目录并且无法查看数据文件,给出以下错误:
...Error in file(file, "rt") : cannot open the connection
In addition: Warning message:
In file(file, "rt") :
cannot open file 'data/testhaplom.out': No such file or directory
Run Code Online (Sandbox Code Playgroud) 我正在使用该testthat库在R项目中进行单元测试.我想测试依赖于数据库查询的代码,但不测试实际的查询本身.换句话说,我想模拟数据库连接和查询(让它们返回预定的数据集或命中测试数据库).
我知道Ruby中有很多宝石,以及其他语言中的其他宝石,它们提供了这种功能.R有什么类似的吗?或者我该如何完成它?
some_file.R:
sqlQuery <- function(some_query) {
chnl <- odbcConnect(get.db.name())
data <- sqlQuery(chnl, query)
}
Run Code Online (Sandbox Code Playgroud)
从测试文件:
test_that("test query", {
dataset <- sqlQuery("SELECT * FROM some_database_table")
#How to make this not actually hit the production database?
expect_equal(nrow(dataset), 2)
} )
Run Code Online (Sandbox Code Playgroud)
如果没有方便的包,testthat::with_mock()我最好的选择?