#r #rlang #testthat #quasiquotes
#r #rlang #testthat #квазиквоты
Вопрос:
Я новичок в {testthat} и создаю тесты для функции, которая изменяет строки и, как ожидается, будет выдавать определенный вывод для определенных шаблонов ввода.
В качестве примера (повторите ниже) add_excitement
добавляет восклицательный знак к своей входной строке. При вводе «привет» он должен возвращать «привет!»; при вводе любого другого ввода он не должен возвращать «привет!». Я хотел бы проверить поведение {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
Создано 2021-02-04 пакетом reprex (версия 0.3.0)
Спасибо за вашу помощь!
Ответ №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!"
Создано 2021-02-04 пакетом reprex (версия 0.3.0)
Или для аккуратной версии:
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!"
Создано 2021-02-04 пакетом reprex (версия 0.3.0)
Ответ №2:
Ошибка связана с использованием оператора tidyeval
bang bang !!
.
Это заменяется, и приведенный вами пример работает без :
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
Комментарии:
1. Спасибо. Однако версия без
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!".
2. Спасибо за ваш отзыв и рад, что вы нашли решение!