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

如何在独立R会话中运行testthat测试并合并测试结果

解决方案:传递测试结果数据而非报告器对象

你遇到的核心问题是报告器这类带有内部状态的对象无法通过callr::r跨会话完整传递——当你把reporter_in传给子会话,再把reporter_out传回来时,它已经是一个序列化后的副本,丢失了和原报告器的状态关联,自然没法合并结果。

正确的思路是:让子会话返回结构化的测试结果数据,而不是报告器本身,然后在主会话中将这些数据手动添加到原报告器中。下面是修改后的完整实现:

第一步:修改测试文件 test-mytest.R

test_that('test 1', { expect_equal(2+2, 5) })

# 子会话中运行测试,返回纯数据格式的结果
test_results <- callr::r(
  function() {
    # 使用ListReporter收集测试结果(它会返回结构化的结果列表)
    reporter <- testthat::ListReporter$new()
    testthat::with_reporter(reporter, {
      testthat::test_that("test inside", {
        testthat::expect_equal('this', 'wont match')
      })
      # 可以在这里添加更多子会话内的测试
      testthat::test_that("another sub test", {
        expect_true(FALSE)
      })
    })
    # 返回收集到的所有测试结果
    reporter$results
  },
  show = TRUE
)

# 将子会话的测试结果添加到当前主报告器中
current_reporter <- testthat::get_reporter()
for (res in test_results) {
  current_reporter$add_result(res)
}

test_that('test 2', { expect_equal(2+2, 8) })

第二步:保持原调用代码不变

summary <- testthat::SummaryReporter$new()
testthat::test_file('./tests/testthat/test-mytest.R', reporter = summary)

为什么这样能解决问题?

  1. ListReporter的优势:它是testthat专门用来收集结构化测试结果的报告器,返回的results是纯列表格式的数据,完全可以通过callr安全地跨会话序列化传递,不会丢失状态。
  2. 手动合并结果:主会话中的报告器(比如SummaryReporter)都支持add_result方法,我们可以遍历子会话返回的结果,逐个添加到原报告器中,这样所有测试(包括子会话内的)都会被统计和展示。

运行效果验证

当你调用summary$end_reporter()时,会看到所有4个测试的失败结果都被合并到同一份报告里,完全符合你在独立会话运行测试并统一汇总结果的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:54:22