regex - 如何使用testthat以未知顺序测试多个警告?

标签 regex r unit-testing testthat

我想测试一个函数在警告的顺序可以变化时会生成多个警告(4个或更多)。我最好的尝试是基于前瞻性RegExp匹配。简化为2条警告,我知道我的RegExp在单个字符串输出上工作,因为以下两个都是正确的:

grepl("(?s)(?=.*2)(?=.*1)", "* warn 1.\n* warn 2.", perl=TRUE)
grepl("(?s)(?=.*2)(?=.*1)", "* warn 2.\n* warn 1.", perl=TRUE)

但是,这在使用testhat::expect_warning测试多个警告时不起作用
# The function generating warnings:
foo <- function() { warning("warn 1."); warning("warn 2.") }
foo()
Warning messages:
1: In foo() : warn 1.
2: In foo() : warn 2.

# Testing it
expect_warning( foo(), "(?s)(?=.*1)(?=.*2)", perl=TRUE)

Error: foo() does not match '(?s)(?=.*1)(?=.*2)'. Actual values:
* warn 1.
* warn 2.

我怀疑这是因为expect_warning的内部功能正在像针对每个警告分别测试给定的RegExp一样-为何expect_warning( ... all=TRUE )参数可能有意义。

不幸的是,我不能与"1 | 2"这样的RegExp一起使用;如果只发出一个警告,则成功。

我也想避免多次运行该函数,并且每次都测试不同的警告。要测试真实功能,需要大量的设置和拆卸代码。它与文件系统有很大的交互作用,并且由于它是我正在测试的文件系统警告,因此我不能对此进行 mock 。此外,我想在多种情况下测试警告,每种情况都需要不同的设置和拆卸代码,因此这会使我的测试迅速膨胀。

关于如何简单且一次地测试多个警告的任何建议?

最佳答案

要捕获警告并“手动”分析警告,您还可以使用testthat::capture_warnings:

# The function generating warnings:
foo <- function() { warning("warn 1."); warning("warn 2.") }

w <- capture_warnings(foo())
expect_match(w, ".*1", all = FALSE)
expect_match(w, ".*2", all = FALSE)
expect_match(w, ".*3", all = FALSE)

(最后一行引发错误。)

关于regex - 如何使用testthat以未知顺序测试多个警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35712544/

相关文章:

python - Python单元测试中多行字符串的比较

regex - Perl 脚本中的 Grep

javascript - 用于 brainfuck 循环的正则表达式

java - 其中 "."在我的字符串中,在 "."之后创建一个新行,并对所有字符串执行相同的操作

php - REGEXP 在 PHP 脚本中未按预期工作

r - 公式的符号导数

r - 在 Shiny 的应用程序上,ggplotly() 渲染的大小是 plot_ly() 的一半。如何解决?

unit-testing - 设置/拆卸会损害测试的可维护性吗?

r - 根据 R 中字符串中的字母分配数值

c# - 从构建输出运行单元测试