【问题标题】:Is there something in testthat like expect_no_warnings()?测试中是否有类似expect_no_warnings() 的东西?
【发布时间】:2014-03-27 00:47:48
【问题描述】:

我正在为在某些情况下会生成警告的函数编写测试。我想确保在其他条件下它不会产生警告。我看不到用testthat 轻松测试它的明显方法。我想我可以这样做:

my.result <- 25
my.func <- function() my.result
expect_equal(
  withCallingHandlers(
    my.func(), warning=function() stop("A Warning!")
  ), 
  my.result
)

或使用options(warn=2),但我希望会有类似的东西:

expect_no_warnings(my.func())

我是否遗漏了一些明显的东西?

【问题讨论】:

  • 我通过设置options(warning=2)来做到这一点
  • @BenBolker,我对这种方法有两个问题,1.(我建议的另一个替代方法也有问题),testthat 出错时停止执行,而不是继续并报告任何其他失败的测试; 2. 我想不出一个简单的系统机制来撤销它,它可以在test_that 块中保留未处理的错误。通常我会做on.exit(options(warn=old.warn)),但要做到这一点,我必须在test_that 块周围包装一个函数。在最后添加 options(warn=old.warn) 不会出现警告失败,我的选项将被更改。

标签: r testthat


【解决方案1】:

在最新版本的“testthat”(来自0.11.0)中,您可以:

expect_warning(my.func(), regexp = NA)

来自expect_error的文档

regexp:要测试的正则表达式。如果省略,则仅断言代码会产生一些输出、消息、警告或错误。或者,您可以指定 NA 以指示不应有输出、消息、警告或错误。

因此,您可以以同样的方式测试没有消息、错误和输出。

【讨论】:

  • 在 testthat 0.11.0 中,您还可以使用 expect_silent(...),如果您想检查它是否在一个步骤中发出任何输出、消息或警告。
  • @StuartR.Jefferys 如果您想测试所有输出,您是对的。然而,问题在于如何期望没有警告。因此,即使没有发出警告,打印消息的测试也会失败。
  • 绝对。这就是为什么我将它添加为评论并一次性列出它捕获的所有内容。这个问题并没有说应该捕获only警告;)我几乎总是使用expect_silent,因为它通常是真正被测试的并且更具限制性。您的答案是仅测试警告并允许其他所有内容的最佳方法。
  • 我希望验证没有警告,但是我确实得到了输出。即我的被测函数总是会产生一个警告。有时它会产生警告。我想要两个测试用例。一个用于警告,一个用于输出但没有警告。
【解决方案2】:

在最新版本的 testthat 中,您可以简单地执行以下操作:

expect_that(my.func(), not(gives_warning()))

【讨论】:

  • 从 testthat 0.10.0(2015 年 5 月 22 日)开始,expect_that(A, func(B)) 风格的测试已被软性弃用,not() 的文档指出这将在未来的版本中删除。鉴于此,除了设置options(warning=2),还有其他答案吗?
  • 对不起,卡尔,考虑到弃用,将接受的答案更改为 alko's。有关github 的更多详细信息。
【解决方案3】:

更新:现在使用 expect_silent(),因为 expect_that 已被弃用,请参阅该功能的帮助!

更新 2: 正如@eaglefreeman the answer using expect_warning with the param regexp set to NA 所提到的,这是最好的解决方案,因为我的回答会导致测试失败,即使没有发出警告而只是打印了一条消息。这不是 OP 想要的(只是忽略警告)。我不会删除此答案以使其他读者清楚这一区别。

来自帮助的例子:

expect_silent("123")

f <- function() {
  message("Hi!")
  warning("Hey!!")
  print("OY!!!")
}

expect_silent(f())

警告:expect_silent 也期望没有输出,所以语义有点不同!

【讨论】:

  • 谢谢,因为这有点笼统,所以我将当前接受的答案保留为已接受(例如,我可能希望允许标准输出,但不允许警告),但这还是很高兴知道(+1)
  • 对不起,我不得不对此投反对票。在这种情况下,expect_silent 实际上非常具有误导性。
  • @eaglefreeman 你能详细说明一下,并提出一个更好的答案来帮助我们大家改进吗?
  • 我使用了 expect_silent 并且迷失了一些时间来弄清楚它为什么不起作用。我不希望其他人尝试同样的事情 :) 最好的答案是将正则表达式设置为 NA 的 expect_warning。
  • @eaglefreeman 非常感谢您的解释,您是绝对正确的!我更新了我的答案以警告其他读者(而不是删除它)。
【解决方案4】:

您可以检查expect_warning() 是否失败。以下解决了my.func()not() 产生的其他类型的输出被弃用的问题:

expect_failure(expect_warning(my.func()))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-29
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多