如何在独立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)
为什么这样能解决问题?
- ListReporter的优势:它是testthat专门用来收集结构化测试结果的报告器,返回的
results是纯列表格式的数据,完全可以通过callr安全地跨会话序列化传递,不会丢失状态。 - 手动合并结果:主会话中的报告器(比如
SummaryReporter)都支持add_result方法,我们可以遍历子会话返回的结果,逐个添加到原报告器中,这样所有测试(包括子会话内的)都会被统计和展示。
运行效果验证
当你调用summary$end_reporter()时,会看到所有4个测试的失败结果都被合并到同一份报告里,完全符合你在独立会话运行测试并统一汇总结果的需求。
内容的提问来源于stack exchange,提问作者Siete
相关产品推荐
相关产品推荐

