在testthat中测试精确的字符串

pet*_*ete 2 r testthat

我想测试我的一个函数给出了一个特定的消息(或警告或错误).

good <- function() message("Hello")
bad <- function() message("Hello!!!!!")
Run Code Online (Sandbox Code Playgroud)

我希望第一个期望成功,第二个期望失败.

library(testthat)
expect_message(good(), "Hello", fixed=TRUE)
expect_message(bad(), "Hello", fixed=TRUE)
Run Code Online (Sandbox Code Playgroud)

不幸的是,他们两个目前都在通过.

为了澄清:这是一个最小的例子,而不是我正在测试的确切消息.如果可能的话,我希望避免为我的测试脚本添加复杂性(可能还有错误),因为需要为我要测试的每个新消息提供一个合适的正则表达式.

GSe*_*See 7

您可以使用^$锚点来指示字符串必须以您的模式开头和结尾.

expect_message(good(), "^Hello\\n$")
expect_message(bad(), "^Hello\\n$")
#Error: bad() does not match '^Hello\n$'. Actual value: "Hello!!!!!\n"
Run Code Online (Sandbox Code Playgroud)

\\n需要以匹配新行message补充道.

对于警告,它有点简单,因为没有新行:

expect_warning(warning("Hello"), "^Hello$")
Run Code Online (Sandbox Code Playgroud)

对于错误,它有点困难:

good_stop <- function() stop("Hello")
expect_error(good_stop(), "^Error in good_stop\\(\\) : Hello\n$")
Run Code Online (Sandbox Code Playgroud)

请注意,任何正则表达式元字符,即. \ | ( ) [ { ^ $ * + ?需要进行转义.


另外,从弗里克先生的回答借用在这里,你可以在消息转换成字符串,然后使用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
Run Code Online (Sandbox Code Playgroud)