我想测试我的一个函数是否给出了特定的消息(或警告或错误)。
good <- function() message("Hello")
bad <- function() message("Hello!!!!!")
我希望第一个期望成功,第二个期望失败。
library(testthat)
expect_message(good(), "Hello", fixed=TRUE)
expect_message(bad(), "Hello", fixed=TRUE)
不幸的是,他们两个现在都过去了。
澄清:这是一个最小的例子,而不是我测试的确切消息。如果可能的话,我希望避免为我的测试脚本添加复杂性(可能还有错误),因为需要为我要测试的每个新消息提供一个合适的正则表达式。
答案 0 :(得分:7)
您可以使用^
和$
锚来指示字符串必须以您的模式开头和结尾。
expect_message(good(), "^Hello\\n$")
expect_message(bad(), "^Hello\\n$")
#Error: bad() does not match '^Hello\n$'. Actual value: "Hello!!!!!\n"
需要\\n
来匹配message
添加的新行。
对于警告,它有点简单,因为没有新行:
expect_warning(warning("Hello"), "^Hello$")
对于错误,这有点困难:
good_stop <- function() stop("Hello")
expect_error(good_stop(), "^Error in good_stop\\(\\) : Hello\n$")
请注意,任何正则表达式元字符,即. \ | ( ) [ { ^ $ * + ?
,都需要进行转义。
或者,借用Flick先生的回答here,您可以将消息转换为字符串,然后使用expect_true
,expect_identical
等。
messageToText <- function(expr) {
con <- textConnection("messages", "w")
sink(con, type="message")
eval(expr)
sink(NULL, type="message")
close(con)
messages
}
expect_identical(messageToText(good()), "Hello")
expect_identical(messageToText(bad()), "Hello")
#Error: messageToText(bad()) is not identical to "Hello". Differences: 1 string mismatch
答案 1 :(得分:1)
在两种情况下,您的rexeg都匹配"Hello"
,因此它不会返回错误。您需要从两侧设置单词边界\\b
。如果你不在这里使用标点/空格就足够了。为了放弃它们,您还需要添加[^\\s ^\\w]
library(testthat)
expect_message(good(), "\\b^Hello[^\\s ^\\w]\\b")
expect_message(bad(), "\\b^Hello[^\\s ^\\w]\\b")
## Error: bad() does not match '\b^Hello[^\s ^\w]\b'. Actual value: "Hello!!!!!\n"