跳过CRAN测试,但在本地运行

时间:2016-03-22 22:16:23

标签: r package cran

如果软件包由CRAN测试,有一种简单的方法可以跳过包中某些测试的执行吗?背景是,我喜欢进行大量的测试,总而言之,它们非常耗时(对CRAN不好)。

我知道有testthat::skip_on_cran()但我不想使用包testthat来避免另一个依赖。我正在寻找一种模仿testthat::skip_on_cran的方式。

理想情况下,我希望在目录pkg/tests中有一个调用测试文件(testfiles)的测试文件,并且如果我们处于不正常情况下会让人感到不安:

if (!on_cran) {
 ## these tests are run only locally/when not on CRAN
 # run test 1 (e.g. source a file with a test)
 # run test 2
}
# run test 3 - always

2 个答案:

答案 0 :(得分:14)

是的!您可以通过编程方式自动处理此问题。让我详细介绍一下我设置的两种方式:

隐含地通过版本号:这是Rcpp现在许多年采用的方法,它完全是通用的,不依赖于任何其他包< / em>的。我们的测试从tests/中的文件开始,然后移交给RUnit,但最后一部分是实现细节。

在主文件tests/doRUnit.R中,我们这样做:

## force tests to be executed if in dev release which we define as
## having a sub-release, eg 0.9.15.5 is one whereas 0.9.16 is not
if (length(strsplit(packageDescription("Rcpp")$Version, "\\.")[[1]]) > 3) { 
    Sys.setenv("RunAllRcppTests"="yes")
}

本质上,我们测试版本是否为a.b.c.d形式 - 如果是这样的结论是它是开发版本。这意味着&#34;运行所有测试&#34;。 a.b.c形式的发布版本将转到CRAN,而不会运行这些测试,因为它们会超出其时间限制。

在每个actual unit test files中,我们可以决定是否要尊重变量并在设置时跳过测试,或者仍然执行:

.runThisTest <- Sys.getenv("RunAllRcppTests") == "yes"

if (.runThisTest) {

   ## code here that contains the tests

}

此机制是全自动的,不依赖于用户。 (在实际的软件包版本中,还有另一个if ()测试包含在那里,它允许我们禁止测试,但这是我们在这里不需要的细节。)

我仍然喜欢这种方法。

明确地通过资源文件我们中的一些人工作的另一个包(最近很多)需要一个特定的后端可用。因此,在Rblpapi包中,我们测试了一个文件的存在,我的共同作者和我各自都在$HOME目录下面,以便设置凭据和连接细节。如果文件丢失,例如在Travis CI或CRAN或其他用户上,将跳过测试。

我们选择将资源文件用作R文件;它sources it if found and thereby sets values for options()。这样我们就可以直接控制是否启动测试。

## We need to source an extra parameter file to support a Bloomberg connection
## For live sessions, we use ~/.Rprofile but that file is not read by R CMD check
## The file basically just calls options() and sets options as needed for blpHost,
## blpPort, blpAutoConnect (to ensure blpConnect() is called on package load) and,
## as tested for below, blpUnitTests.
connectionParameterFile <- "~/.R/rblpapiOptions.R"
if (file.exists(connectionParameterFile)) source(connectionParameterFile)

## if an option is set, we run tests. otherwise we don't.
## recall that we DO need a working Bloomberg connection...
if (getOption("blpUnitTests", FALSE)) {

    ## ... more stuff here which sets things up

}

与第一个用例类似,我们现在可以设置更多变量,这些变量稍后会被测试。

明确地通过Travis CI 我们在rfoaas中使用的另一个选项是在Travis CI file中设置管理此变量的环境变量:

env:
  global:
    - RunFOAASTests=yes

tests script then picks up

## Use the Travis / GitHub integrations as we set this
## environment variable to "yes" in .travis.yml
##
## Set this variable manually if you want to run the tests
##
if (Sys.getenv("RunFOAASTests=yes") == "yes") runTests <- TRUE

在这种情况下,我还根据我的用户ID设置切换,因为我几乎是该项目的唯一贡献者:

## Also run the tests when building on Dirk's box, even whem
## the environment variable is not set
if (isTRUE(unname(Sys.info()["user"])=="edd")) runTests <- TRUE

明确地通过另一个变量您当然也可以依赖于您在所有包中使用的另一个变量。我发现这是个坏主意。如果你在shell中设置它,可以使用包A并将其设置为禁止测试但是然后切换到包B ---您可能会忘记取消设置变量然后无法测试。我最喜欢这种方法,不要使用它。

答案 1 :(得分:2)

使用环境变量like testthat does

skip_on_cran <- function() {
  if (identical(Sys.getenv("NOT_CRAN"), "true")) {
    return(invisible(TRUE))
  }

  skip("On CRAN")
}