如何在testthat嵌套for循环中获取完整信息的错误提示?
解决testthat循环测试多数据框时的错误提示问题
针对你用testthat 3.1.4批量测试多个结构相似dataframe列时,错误提示缺少数据框名称和列名的问题,这里提供两种直接有效的解决方式:
核心思路
必须用命名列表存储数据框,这样才能在循环中获取到数据框的名称字符串,进而把它和列名一起嵌入错误提示。
方法一:自定义完全匹配需求的错误消息
直接构造符合你期望格式的错误提示,精准定位问题位置:
library(testthat) # 用命名列表存储需要测试的数据框 dfs <- list( example1 = data.frame(A = 1:3, B = c("x", "y", "z")), example2 = data.frame(A = c("a", "b", "c"), B = 4:6) ) # 定义各列的预期类型 col_expected_types <- list(A = "character", B = "double") test_that("验证所有数据框列类型符合要求", { # 循环遍历数据框名称和对应数据 for (df_name in names(dfs)) { current_df <- dfs[[df_name]] # 循环遍历列名和预期类型 for (col_name in names(col_expected_types)) { expected_type <- col_expected_types[[col_name]] actual_type <- typeof(current_df[[col_name]]) # 直接构造自定义错误消息,不符合预期时抛出 if (actual_type != expected_type) { fail(sprintf("%s[['%s']] has type '%s', not '%s'", df_name, col_name, actual_type, expected_type)) } } } })
运行后错误提示会完全符合你的需求:
✖ example1[['A']] has type 'integer', not 'character'
方法二:嵌套test_that优化测试结构
如果希望测试报告的层级更清晰,可嵌套test_that将每个数据框的测试作为独立单元,同时补充列名上下文:
library(testthat) dfs <- list( example1 = data.frame(A = 1:3, B = c("x", "y", "z")), example2 = data.frame(A = c("a", "b", "c"), B = 4:6) ) col_expected_types <- list(A = "character", B = "double") test_that("批量验证数据框列类型", { for (df_name in names(dfs)) { # 内层test_that以数据框名称作为测试上下文 test_that(sprintf("数据框 %s 的列类型正确", df_name), { current_df <- dfs[[df_name]] for (col_name in names(col_expected_types)) { expect_type( current_df[[col_name]], col_expected_types[[col_name]], # 补充列名信息到错误提示 info = sprintf("目标列: %s", col_name) ) } }) } })
运行后错误提示会包含层级化的上下文:
── 测试失败:数据框 example1 的列类型正确 ─────────────────────────── ℹ 目标列: A ✖ current_df[["A"]] has type 'integer', not 'character'
内容的提问来源于stack exchange,提问作者AaronDD
相关产品推荐
相关产品推荐

