我希望测试一个函数是否会生成多个警告(4个或更多),而警告的顺序可能会变化。我的最佳尝试是基于前瞻正则表达式匹配。为了简化,只考虑2个警告,我知道我的正则表达式适用于单个字符串输出,因为以下两个条件都成立:
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
的内部机制会针对每个警告单独测试给定的正则表达式,这就是为什么expect_warning( ... all=TRUE )
参数可能有意义的原因。
不幸的是,我不能使用像"1 | 2"
这样的正则表达式;这种情况只有一个警告时才会成功。
我还想避免多次运行函数并测试每个警告。测试真实函数需要大量的设置和拆卸代码。它与文件系统密切相关,由于我正在测试文件系统警告,所以我无法模拟它。此外,我想在多种情况下测试警告,每种情况都需要不同的设置和拆卸代码,因此这很快使我的测试膨胀。
有没有建议如何简单地一次性测试多个警告?
expect_warning
没有像R中的其他函数一样的perl
参数,但为什么不简单地使用模式1.*\\n.*2
或1(.*\\n)*.*2
*(因为(?s)
、.*
和前瞻是无用的)*? - Casimir et Hippolyteexpect_warning
接受...
,并将参数传递给底层的grepl
调用,因此它 将 使用perl=TRUE
参数。如果没有它,包含 RegExp 的 "lookahead" 是无效的。我需要它,因为顺序是未知的,并且在我的实际应用程序中有超过 2 个。lookaheads 是一种匹配未知顺序的元素的方法。 - Stuart R. Jefferys