【发布时间】:2016-06-13 06:13:02
【问题描述】:
我想测试一个函数是否会生成多个警告(4 个或更多),而警告的顺序可能会有所不同。我最好的尝试是基于前瞻正则表达式匹配。简化为只有 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" 这样的正则表达式一起使用;如果只给出一个警告就成功了。
我还想避免多次运行该函数并每次测试不同的警告。测试真正的功能需要大量的设置和拆卸代码。它与文件系统进行大量交互,并且因为它是我正在测试的文件系统警告,所以我不能模拟它。此外,我想在多种情况下测试警告,每种情况都需要不同的设置和拆卸代码,所以这很快就会使我的测试膨胀。
关于如何一次简单地测试多个警告有什么建议吗?
【问题讨论】:
-
看来
expect_warning没有perl参数(与R 中的其他函数一样),但为什么不简单地使用模式1.*\\n.*2或1(.*\\n)*.*2(因为(?s),.*和前瞻都没用)? -
@Casimir et Hippolyte -
expect_warning接受...,并将参数传递给底层的grepl调用,因此它将使用perl= TRUE参数。没有它,包含 RegExp 的“前瞻”是无效的。我需要它,因为顺序未知,并且在我的实际应用程序中有超过 2 个。前瞻是match elements in an unknown order 的一种方式。
标签: regex r unit-testing testthat