我希望运行所有测试,并获得测试结果并生成警告,以便以编程方式创建一个标记报告,显示测试结果和测试代码中发生的潜在警告。
但是,在测试运行期间,似乎无法获取或捕获警告!我知道测试是在一个封闭的环境中执行的,但是是否真的没有办法让测试提供抛出的警告呢?
在下面的设置中,warn_list变量始终为空。
最小示例的三个文件:
./tests/testthat.R
library(testthat)
warn_list <- list()
outcome <- withCallingHandlers(
testthat::test_dir(testthat::test_path()),
warning = function(w) {
warn_list <<- c(warn_list, list(msg = w$message))
}
)
rmarkdown::render(input = './tests/create_test_report.Rmd')注意,Rmd文件中使用了outcome (和warn_list)变量。
./tests/testthat/test_thrown_warn.R
test_that("Throws Warning", {
testthat::expect_equal(
{
warning('Example warning fired inside test!') # WHERE WARN IS THROWN
5
}, 5)
})./tests/create_test_report.Rmd
---
title: "test_results_overview"
output: md_document
---
## Produced warnings during the tests:
```{r warnings_during_testing, echo=FALSE}针织品::kable(Warn_list)#,我试着展示它
发布于 2021-11-29 15:17:49
SummaryReporter记者对象似乎记录了警告。正如您在评论中提到的,这些都是非常少的文档,但这似乎做到了:
library(testthat)
summary <- SummaryReporter$new()
test_file("somewarnings.R", reporter = summary)
summary$warnings$as_list()每个警告都会在最后一个语句的列表中生成一个条目。它们作为条件对象存储,因此您可以执行以下操作
awarning <- summary$warnings$as_list()[[1]]
getSrcFilename(awarning$srcref)发布于 2021-11-29 16:40:37
在testthat_results对象中实际上可以使用另一种解决方案。它确实包括特定的测试用例响应,如警告、跳过的测试或崩溃测试的错误,但内容的结构并不好。
例如,在示例中显示的测试用例中,它将显示三个结果字段,而只有两个‘expect_.’语句。中间一个是c('expectation_warning', 'expectation', 'condition')类,包含警告对象。
另一种解决方案是从以下结果中获得这些警告(以及可选的错误和跳转作为奖励):
outcome <- testthat::test_dir(testthat::test_path(), stop_on_failure = FALSE)
create_warn_df <- function(res) {
data.frame(test = res$test, warning_msg = res$message)
}
warn_df <- data.frame()
for (i_test in seq_along(outcome)) {
tst <- outcome[[i_test]]
for (i_res in seq_along(tst$results)) {
res <- tst$results[[i_res]]
if (is(res, "expectation_warning")) {
warn_df <- rbind(warn_df, create_warn_df(res))
}
}
}
knitr::kable(warn_df)注意:“create_warning_str”将格式化表,并可以从警告对象获得更多信息,如堆栈等。
测试结果位于outcome[[X]]$results[[Y]]中,其中X是正在处理的文件,Y是测试用例(或前面描述的警告)。Y元素的数量不等于测试用例的数量。
一个更高级的例子:
这个包括它发生的地方的行号,另外还包括错误和跳过。它还显示了“file”而不是“test”(name)。
create_warn_df <- function(file, src_ref, warn_msg) {
data.frame('file' = file, 'line' = getSrcLocation(src_ref), 'warning_msg' = warn_msg)
}
warn_df <- data.frame()
for (i_test in seq_along(outcome)) {
tst <- outcome[[i_test]]
for (i_res in seq_along(tst$results)) {
res <- tst$results[[i_res]]
if (is(res, "expectation_warning")) {
warn_df <- rbind(warn_df, create_warn_df(tst$file, res$srcref, res$message))
} else if (is(res, "expectation_error")) {
warn_df <- rbind(warn_df, create_warn_df(tst$file, res$srcref, paste('An error crashed this test:', res$message)))
} else if (is(res, "expectation_skip")) {
warn_df <- rbind(warn_df, create_warn_df(tst$file, res$srcref, paste('A test is skipped,', res$message)))
}
}
}
knitr::kable(warn_df)https://stackoverflow.com/questions/70156281
复制相似问题