【问题标题】:Skip tests on CRAN, but run locally跳过 CRAN 上的测试,但在本地运行
【发布时间】:2016-03-22 22:16:22
【问题描述】:

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

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

理想情况下,我希望在目录pkg/tests 中有一个测试文件,它会调用测试(测试文件)并区分我们是否在 cran 上:

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

【问题讨论】:

  • 使用本地定义的 env var,或将测试拆分为多个文件并有条件地以q(save = "no") 退出每个文件。

标签: r package cran


【解决方案1】:

是的!您可以以编程方式自动处理此问题。让我详细说明我设置的两种方式:

隐含地通过版本号:这是 Rcpp 多年来采用的方法许多,它是完全通用的,不依赖于任何其他包。我们的测试从 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 形式——如果是,则断定它是开发版本。这意味着“运行所有测试”。而 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——你可能会忘记取消设置变量,然后测试失败。我最不喜欢这种方法,不使用它。

【讨论】:

  • 谢谢!这个很全面!在所指出的方法中,到目前为止,我最喜欢“隐式通过版本号”。仅仅是因为它不需要包开发人员之间的一些“共享文件/环境变量”。不幸的是,我们还没有定义一个合适的版本控制方案……我想知道是否有一种直接的方法来查询一个定义良好的 CRAN 机器的环境变量——或者 CRAN 维护者是否愿意考虑这样的事情。
  • 过去他们总是说不,例如邮件列表中的一些人(想到一个特定的 R Core 成员,其首字母缩写为 not BDR)强烈反对。所以我怀疑它会发生,这就是为什么我在几年前切换到隐式方案,它可以正常工作,这毕竟是我们想要的。
  • 对于那些对使用版本号的方法感兴趣的人的提示:numeric_version(packageDescription("pkg_name")$Version) 如果想要测试特定版本号,例如numeric_version(packageDescription("pkg_name")$Version)[[1,2]] 将次要版本作为整数提供,似乎比自己拆分字符串更容易(并自动处理“.”和“-”作为分隔符)。
【解决方案2】:

使用环境变量like testthat does:

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

  skip("On CRAN")
}

【讨论】:

  • 谢谢。你能多评论一点吗?所以 CRAN 机器有一个环境变量 NOT_CRAN 设置为“真”以外的东西?还是应该在本地机器上将自己的环境变量 NOT_CRAN 设置为“true”?我需要不同的人在不同的机器上使用它,所以如果需要后者,则需要一些 R 代码来检查机器......你知道有这个自建检查的包(在 CRAN 上)吗?跨度>
  • @Helix123 NOT_CRAN 环境变量将在 CRAN 上不存在。如果你让你的测试以此为条件,它们将不会运行。您还可以指定一些其他随机环境变量名称; NOT_CRAN 只是 testthat 和 devtools 使用的变量。您需要在希望运行测试的每台机器上进行设置。
  • 我认为这是一种有点“间接”的方法。如果该软件包有多个贡献者,它会变得不方便,因为每个人都需要为他的本地机器进行适当的设置......难道没有其他方法吗?不要让 CRAN 机器以某种方式识别自己,例如通过我们可以使用的环境变量? CRAN 政策中没有任何文档,但有“长时间运行的测试和小插曲代码可以作为可选的检查...”
  • 不。 devtools 设置 NOT_CRAN 环境。如果您不想要devtools/testthat,您可以分发带有test 目标的Makefile,该目标设置相关的环境变量...
猜你喜欢
  • 2015-02-17
  • 2016-11-29
  • 2015-03-26
  • 1970-01-01
  • 2017-12-18
  • 2015-07-19
  • 2019-04-07
  • 1970-01-01
  • 2019-01-14
相关资源
最近更新 更多