【问题标题】:Test for exact string in testthat在 testthat 中测试确切的字符串
【发布时间】:2014-08-19 22:00:53
【问题描述】:

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

good <- function() message("Hello")
bad <- function() message("Hello!!!!!")

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

library(testthat)
expect_message(good(), "Hello", fixed=TRUE)
expect_message(bad(), "Hello", fixed=TRUE)

不幸的是,他们俩现在都过去了。

为了澄清:这只是一个最小的例子,而不是我正在测试的确切消息。如果可能的话,我希望通过需要为我要测试的每条新消息提供适当的正则表达式来避免给我的测试脚本增加复杂性(并且可能是错误)。

【问题讨论】:

    标签: r testthat


    【解决方案1】:

    您可以使用^$ 锚来指示字符串必须以您的模式开始和结束。

    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$")
    

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


    或者,借用弗里克先生的回答here,您可以将消息转换为字符串,然后使用expect_trueexpect_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
    

    【讨论】:

    • 谢谢。我将添加要求以匹配错误和警告,然后接受。
    • @pete 我没有意识到错误是要求的一部分,但我可能不会按照您在我的答案中编辑的方式进行操作。那这个呢? bad_stop &lt;- function() stop("Hello", call.=FALSE)你想让那个测试失败吗?
    • 我不确定那是否应该失败,我想我更愿意选择?我想我可以使用^Error (|in good_stop\\(\\) ): Hello\n$,但这变得很乱。我最终可能只是为testthat 提出功能请求,因为在这个用例中完全避免使用正则表达式会很好。
    【解决方案2】:

    您的 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"
    

    【讨论】:

    • 谢谢,但不是我需要的。例如:expect_message(message("Hello Dave."), "\\b^Hello\\W\\b")
    • 那是因为您在其中添加了一个空格。需要修改它以逃避空格
    • expect_message(message("Hello%Dave"), "\\b^Hello[^\\s ^\\w]\\b") 我在上面添加了一个说明。我正在尝试测试我是否完全掌握了我指定的消息。因此,虽然我给出的特定反例需要失败,但这还不够:我希望所有不完全符合我指定的内容也失败。
    • 赞成,因为这很有帮助。
    • 也许我遗漏了什么……这能行吗expect_message(bad(), "^Hello\\n$")
    猜你喜欢
    • 2015-10-11
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 2014-09-09
    相关资源
    最近更新 更多