开发R包时devtools::test()测试通过但devtools::check()失败如何解决
问题根源
devtools::test是在你本地项目根目录下运行的,所以不管是匹配项目内的tests/路径还是用here定位根目录都能命中目标文件。但devtools::check的执行逻辑是先把你的包构建为tar.gz安装包,再安装到临时隔离环境中运行测试,此时安装好的包目录里根本不会包含tests/文件夹,所以你之前的路径写法全部失效。
你之前尝试的方案无效的原因
Sys.setenv(R_TESTS="")是用于解决旧版testthat中测试运行时的环境变量冲突问题,和路径找不到的问题无关here::here()依赖项目根目录下的标记文件(如.Rproj、.here)定位路径,devtools::check的临时运行环境中不存在这些标记,自然无法定位到你本地的项目路径
解决方案
两种方案任选一种即可解决问题:
方案1:使用R包标准静态资源存放路径(推荐)
第一步:调整测试数据存放位置
把你/tests/testthat/testdata/下的所有rds文件,移动到包项目根目录的inst/testdata/路径下。如果没有inst文件夹就手动新建一个。
inst目录下的所有内容在包安装的时候会原封不动地复制到安装后的包根目录下,是R包内置静态资源的标准存放位置。
第二步:修改测试代码的路径读取逻辑
把所有路径读取代码统一替换为system.file("testdata/xxx.rds", package = "你的包名"),不需要加tests/testthat前缀,也不要用here::here,示例如下:
test_that("the test_arguments() returns errors as it should", { # 把下面代码里的package替换成你自己的包名即可 x <- readRDS(system.file("testdata", "objectA.rds", package = "package")) y <- readRDS(system.file("testdata", "objectB.rds", package = "package")) z <- readRDS(system.file("testdata", "objectC.rds", package = "package")) expect_error(test_arguments(z, y), "X has to be an object of class SpatialPolygonsDataFrame") expect_error(test_arguments(x, z), "y has to be an object of class RasterLayer") })
方案2:使用testthat内置路径函数(无需移动测试数据)
如果你不想改动现有的测试数据存放位置,可以直接用testthat包自带的testthat::test_path()函数定位文件,这个函数会自动适配devtools::test和devtools::check两种运行场景的路径,不需要指定包名,示例如下:
test_that("the test_arguments() returns errors as it should", { x <- readRDS(testthat::test_path("testdata", "objectA.rds")) y <- readRDS(testthat::test_path("testdata", "objectB.rds")) z <- readRDS(testthat::test_path("testdata", "objectC.rds")) expect_error(test_arguments(z, y), "X has to be an object of class SpatialPolygonsDataFrame") expect_error(test_arguments(x, z), "y has to be an object of class RasterLayer") })
内容的提问来源于stack exchange,提问作者Faustin Gashakamba
相关产品推荐
相关产品推荐

