testthat `quasi_label` 和 `expect_match` 抛出“错误:参数类型无效”
Posted
技术标签:
【中文标题】testthat `quasi_label` 和 `expect_match` 抛出“错误:参数类型无效”【英文标题】:testthat `quasi_label` with `expect_match` throws "Error: invalid argument type"testthat `quasi_label` 和 `expect_match` 抛出“错误:参数类型无效” 【发布时间】:2021-05-08 17:41:07 【问题描述】:我是 testthat 的新手,我正在为一个修改字符串的函数构建测试,并希望为某些输入模式生成特定的输出。
作为示例(下面的表示形式),add_excitement
在其输入字符串中添加了一个感叹号。当输入“hello”时,它应该返回“hello!”;当给出任何其他输入时,它应该不返回“hello!”。我想testthat一系列模式的行为并返回信息性错误,指定哪个模式导致错误。
根据 testthat 包文档,我相信我应该使用expect_match
。但是,这会引发“无效参数类型”错误,而 expect_identical
有效。我不明白为什么会这样。我的问题是:
expect_identical
而不是expect_match
接受quasi_label
参数?
我是否可以使用 expect_identical
而不是 expect_match
来实现我的目的,或者这会带来其他错误的风险吗?
这是一个代表:
library(testthat)
library(purrr)
patterns = c("hello", "goodbye", "cheers")
add_excitement <- function(pattern) paste0(pattern, "!")
# For a single pattern
show_failure(expect_identical(add_excitement(!!patterns[2]), "hello!"))
#> Failed expectation:
#> add_excitement("goodbye") not identical to "hello!".
#> 1/1 mismatches
#> x[1]: "goodbye!"
#> y[1]: "hello!"
try(
show_failure(expect_match(add_excitement(!!patterns[2]), "hello!", fixed = TRUE,all = TRUE))
)
#> Error in !patterns[2] : invalid argument type
# For multiple patterns
purrr::map(
patterns,
~ show_failure(expect_identical(add_excitement(!!.), "hello!"))
)
#> Failed expectation:
#> add_excitement("goodbye") not identical to "hello!".
#> 1/1 mismatches
#> x[1]: "goodbye!"
#> y[1]: "hello!"
#> Failed expectation:
#> add_excitement("cheers") not identical to "hello!".
#> 1/1 mismatches
#> x[1]: "cheers!"
#> y[1]: "hello!"
#> [[1]]
#> NULL
#>
#> [[2]]
#> NULL
#>
#> [[3]]
#> NULL
try(
purrr::map(
patterns,
~ show_failure(expect_match(add_excitement(!!.), "hello!",
fixed = TRUE, all = TRUE)
)
)
)
#> Error in !. : invalid argument type
由reprex package (v0.3.0) 于 2021-02-04 创建
感谢您的帮助!
【问题讨论】:
【参考方案1】:我能够在 https://r-pkgs.org/tests.html#building-your-own-testing-tools 之后解决这个问题,它使用非标准评估 bquote()
和 eval()
(而不是 quasi_label()
)来产生更多信息错误。
library(testthat)
library(purrr)
patterns = c("hello", "goodbye", "cheers")
add_excitement <- function(pattern) paste0(pattern, "!")
show_failure(eval(bquote(expect_match(add_excitement(.(patterns[2])), "hello!", fixed = TRUE, all = TRUE))))
#> Failed expectation:
#> add_excitement("goodbye") does not match "hello!".
#> Actual value: "goodbye!"
purrr::walk(
patterns,
~ show_failure(eval(bquote(expect_match(add_excitement(.(.)), "hello!", fixed = TRUE, all = TRUE))))
)
#> Failed expectation:
#> add_excitement("goodbye") does not match "hello!".
#> Actual value: "goodbye!"
#> Failed expectation:
#> add_excitement("cheers") does not match "hello!".
#> Actual value: "cheers!"
由reprex package (v0.3.0) 于 2021 年 2 月 4 日创建
或者对于一个整洁的版本:
library(testthat)
library(purrr)
patterns = c("hello", "goodbye", "cheers")
add_excitement <- function(pattern) paste0(pattern, "!")
expect_hello <- function(pattern)
show_failure(eval(bquote(expect_match(add_excitement(.(pattern)), "hello!", fixed = TRUE, all = TRUE))))
expect_hello(patterns[2])
#> Failed expectation:
#> add_excitement("goodbye") does not match "hello!".
#> Actual value: "goodbye!"
walk(patterns, expect_hello)
#> Failed expectation:
#> add_excitement("goodbye") does not match "hello!".
#> Actual value: "goodbye!"
#> Failed expectation:
#> add_excitement("cheers") does not match "hello!".
#> Actual value: "cheers!"
由reprex package (v0.3.0) 于 2021-02-04 创建
【讨论】:
【参考方案2】:该错误与tidyeval
bang bang !!
operator 的使用有关。This is superseded,您提供的示例没有:
show_failure(expect_identical(add_excitement(patterns[2]), "hello!"))
# Failed expectation:
# add_excitement(patterns[2]) not identical to "hello!".
# 1/1 mismatches
# x[1]: "goodbye!"
# y[1]: "hello!"
show_failure(expect_match(add_excitement(patterns[2]), "hello!", fixed = TRUE,all = TRUE))
# Failed expectation:
# add_excitement(patterns[2]) does not match "hello!".
# Actual value: "goodbye!"
purrr::map(
patterns,
~ show_failure(expect_match(add_excitement(.x), "hello!",
fixed = TRUE, all = TRUE)
)
)
Failed expectation:
add_excitement(.x) does not match "hello!".
Actual value: "goodbye!"
Failed expectation:
add_excitement(.x) does not match "hello!".
Actual value: "cheers!"
[[1]]
NULL
[[2]]
NULL
[[3]]
NULL
【讨论】:
谢谢。但是,没有tidyeval
的版本不会在错误中显示pattern
。 show_failure(expect_identical(add_excitement(!!patterns[2]), "hello!"))
提供add_excitement("goodbye") not identical to "hello!".
但show_failure(expect_identical(add_excitement(patterns[2]), "hello!"))
提供的信息较少add_excitement(patterns[2]) not identical to "hello!".
感谢您的反馈,很高兴您找到了解决方案!以上是关于testthat `quasi_label` 和 `expect_match` 抛出“错误:参数类型无效”的主要内容,如果未能解决你的问题,请参考以下文章
我们可以使用 testthat 包中的函数来测试向量的元素吗?
如何编写测试用例以使用r中的testthat检查函数是否正常工作?
使用 testthat 在单元测试中重用变量。是不是有一种可接受的做法来避免重新创建计算量大的变量