You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R包开发:devtools::test()通过但devtools::check()测试失败排查

问题现象

R包开发过程中,交互式执行devtools::test()时57个测试全部通过,但运行devtools::check()时出现1个测试失败,报错输出如下:

-- Failure (test-plot_admissions_discharges_day_of_week.R:53:3): Admission numbers by day of the Week for improvised data --
`result` not equal to `correct_answers`.
Component "Value": Mean absolute difference: 0.7941176

[ FAIL 1 | WARN 4 | SKIP 0 | PASS 56 ]
Error: Test failures
Execution halted
测试逻辑

失败的测试核心逻辑为比对plot_admissions_discharges_day_of_week函数返回的统计结果与预设的正确值,测试代码如下:

test_that("Admission numbers by day of the Week for improvised data", {

  # 预设正确结果
  correct_answers <- tibble::tibble(
    Weekday = as.character(c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")),
    Event = c(
      "Avg_admissions", "Avg_admissions", "Avg_admissions", "Avg_admissions", "Avg_admissions", "Avg_admissions", "Avg_admissions",
      "Avg_discharges", "Avg_discharges", "Avg_discharges", "Avg_discharges", "Avg_discharges", "Avg_discharges", "Avg_discharges",
      "Non_emergency_admissions", "Non_emergency_admissions", "Non_emergency_admissions", "Non_emergency_admissions", "Non_emergency_admissions",
      "Non_emergency_admissions", "Non_emergency_admissions"
    ),
    Value = c(0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 2.0, 0.0, 1.5, 1.0, 1.0, 1.0, 1.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, 0.5)
  )

  correct_answers <- correct_answers %>%
    dplyr::arrange(Weekday, Event)

  # 构造测试输入数据
  adm <- c("2018-12-09 09:30:00", "2018-12-09 09:30:00", "2018-12-09 09:30:00", "2018-12-11 09:30:00", "2018-12-09 09:30:00", "2018-12-12 09:30:00", "2018-12-09 09:30:00", "2018-12-13 08:00:00", "2018-12-09 09:30:00", "2018-12-14 08:00:00", "2018-12-09 09:30:00", "2018-12-09 09:30:00", "2018-12-15 08:00:00", "2018-12-16 08:00:00", "2018-12-16 08:00:00")
  disch <- c("2018-12-12 09:30:00", "2018-12-10 09:30:00", "2018-12-12 09:30:00", "2018-12-12 09:30:00", "2018-12-13 09:30:00", "2018-12-13 09:30:00", "2018-12-14 08:00:00", "2018-12-14 08:00:00", "2018-12-15 08:00:00", "2018-12-15 08:00:00", "2018-12-16 09:30:00", "2018-12-16 09:30:00", "2018-12-17 08:00:00", "2018-12-17 08:00:00", "2018-12-17 09:00:00")
  spell_class_col <- c(
    "ed_admission", "direct_admission", "ed_admission", "direct_admission", "ed_admission",
    "direct_comp_admission", "ed_admission", "direct_admission", "ed_admission", "direct_admission",
    "ed_admission", "direct_comp_admission", "ed_admission", "ed_admission", "direct_admission"
  )
  spell_start <- as.POSIXct(adm, tz = "Europe/London")
  spell_end <- as.POSIXct(disch, tz = "Europe/London")

  test_avg_adm_disch <- tibble::tibble(
    spell_number = 101:115,
    spell_start,
    spell_end, spell_class_col
  )

  # 调用目标函数
  result <- plot_admissions_discharges_day_of_week(
    data = test_avg_adm_disch,
    startDate = as.Date("2018-12-10", tz = "Europe/London"),
    endDate = as.Date("2018-12-23", tz = "Europe/London"),
    returnPlot = FALSE,
    hospitalName = "{hospital_name}"
  )

  result$Weekday <- as.character(result$Weekday)

  result <- result %>%
    dplyr::arrange(Weekday, Event)

  # 校验结果
  expect_equal(tibble::as_tibble(result), tibble::as_tibble(correct_answers), tolerance = 0.01)
})

手动逐行执行测试代码时,identical()校验返回两个数据框完全一致,差异仅存在于Value列,手动运行结果对比如下:
手动执行结果对比截图

已排查方向
  • 测试文件资源拷贝不全问题
  • RStudio交互会话与R CMD check环境的区域设置差异
  • 上述方向均未定位到问题根因
  • 当前运行环境为R 4.1.0、Windows操作系统,包依赖配置如下:
Depends: 
    R (>= 2.10)
Imports: 
    DescTools (>= 0.99.40),
    dplyr (>= 1.0.4),
    forcats (>= 0.5.1),
    ggplot2 (>= 3.3.3),
    ggpubr (>= 0.4.0),
    gtools (>= 3.9.2),
    lazyeval (>= 0.2.2),
    lubridate (>= 1.7.9.2),
    magrittr (>= 2.0.1),
    naniar (>= 0.6.0),
    padr (>= 0.6.0),
    purrr (>= 0.3.4),
    qicharts2 (>= 0.7.1),
    readr (>= 1.4.0),
    reshape2 (>= 1.4.4),
    rlang (>= 0.4.10),
    scales (>= 1.1.1),
    stringr (>= 1.4.0),
    tibble (>= 3.0.6),
    tidyr (>= 1.1.2)
Suggests: 
    knitr (>= 1.31),
    rmarkdown (>= 2.12),
    testthat (>= 3.0.2),
    vdiffr (>= 0.3.3)
VignetteBuilder: 
    knitr
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.1
根因分析

问题核心是星期计算规则的环境依赖:
R CMD check运行时默认使用C本地化环境,周首日设置为周日,而本地交互式会话通常使用系统区域设置,周首日为周一。测试用例中2018-12-09为周日,若代码中提取星期、按周分组时未显式指定周首日规则,check环境下会将部分日期归到错误的星期分组,最终统计的日均入院/出院数值出现固定偏差,与报错中0.794的平均绝对差值完全吻合。
此外若使用基础函数weekdays()提取星期名称,C环境下返回的英文缩写和本地环境返回值可能存在格式差异,也会导致分组统计错误。

修复方案
  1. 函数逻辑层消除环境依赖
    所有涉及星期计算的代码,全部显式指定规则,禁止依赖系统默认设置:
    • 替换基础函数weekdays()为lubridate::wday(),调用时固定参数week_start = 1(指定周一为周首日),若需要返回星期缩写,增加参数label = TRUE, abbr = TRUE
    • 涉及按星期排序的逻辑,显式指定星期因子水平顺序为c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"),避免按字符排序或默认因子顺序导致的错位
  2. 测试层固定环境配置
    在测试代码开头、或测试用例内显式设置时间区域配置,执行完成后恢复原有配置,避免环境差异影响:
    # 测试开头保存原有配置,设置为统一的C环境
    old_locale <- Sys.getlocale("LC_TIME")
    Sys.setlocale("LC_TIME", "C")
    # 测试结束后恢复原有配置
    on.exit(Sys.setlocale("LC_TIME", old_locale), add = TRUE)
    
  3. 验证修复:重新执行devtools::check(),确认测试全部通过。

内容的提问来源于stack exchange,提问作者Martynas Venckus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 03:39:43