是否有一个 testthat expect_* 函数用于比较两个对象的行为?
Posted
技术标签:
【中文标题】是否有一个 testthat expect_* 函数用于比较两个对象的行为?【英文标题】:Is there a testthat expect_* function for comparing two objects behavior? 【发布时间】:2021-11-12 01:27:51 【问题描述】:我正在使用testthat
为 R 包编写一些单元测试。我想比较两个对象,其中并非所有细节都需要匹配,但它们必须在一组感兴趣的功能方面保持等效。
举个简单的例子,我想使用类似的东西
library(testthat)
x <- 1:4
y <- matrix(4:1, nrow=2)
test_that("objects behave similarly",
expect_equal_applied(x, y, .fn=list(sum, prod))
## which would be shorthand for:
## expect_equal(sum(x), sum(y))
## expect_equal(prod(x), prod(y))
)
实际上,x
和 y
可能是 S3 对象,而不仅仅是基础数据结构。
显然,这很容易实现,但如果已经存在的话,我更喜欢惯用的东西。那么,问题是,testthat
是否实现了这样的期望函数?
通过 API 搜索,没有什么符合这个描述,但它似乎是一种自然模式。或者,我忽略了这种模式令人反感的原因。
【问题讨论】:
【参考方案1】:查看documentation testthat 目前(第三版)没有像expect_equal_applied
这样的功能。但是,正如你已经提到的,我们可以很容易地构造这样一个函数:
library(testthat)
x <- 1:4
y <- matrix(4:1, nrow=2)
expect_equal_applied <- function(object, expected, fns)
fns <- purrr::map(fns, rlang::as_function)
purrr::map(fns, ~ expect_equal(.x(object), .x(expected)))
test_that("objects behave similarly",
expect_equal_applied(x, y, fns = list(sum, prod))
)
#> Test passed
x <- 1:3
test_that("objects behave similarly",
expect_equal_applied(x, y, fns = list(sum, prod))
)
#> -- Failure (<text>:19:3): objects behave similarly -----------------------------
#> .x(object) not equal to .x(expected).
#> 1/1 mismatches
#> [1] 6 - 10 == -4
#> Backtrace:
#> 1. global::expect_equal_applied(x, y, fns = list(sum, prod))
#> 2. purrr::map(fns, ~expect_equal(.x(object), .x(expected)))
#> 3. .f(.x[[i]], ...)
#> 4. testthat::expect_equal(.x(object), .x(expected))
#>
#> -- Failure (<text>:19:3): objects behave similarly -----------------------------
#> .x(object) not equal to .x(expected).
#> 1/1 mismatches
#> [1] 6 - 24 == -18
#> Backtrace:
#> 1. global::expect_equal_applied(x, y, fns = list(sum, prod))
#> 2. purrr::map(fns, ~expect_equal(.x(object), .x(expected)))
#> 3. .f(.x[[i]], ...)
#> 4. testthat::expect_equal(.x(object), .x(expected))
由reprex package (v2.0.1) 于 2021-09-17 创建
关于为什么 testthat 中似乎缺少这样的函数,我认为实际上没有必要,我们可以使用 lapply
或 map
构造它。
【讨论】:
以上是关于是否有一个 testthat expect_* 函数用于比较两个对象的行为?的主要内容,如果未能解决你的问题,请参考以下文章
如何编写测试用例以使用r中的testthat检查函数是否正常工作?
我们可以使用 testthat 包中的函数来测试向量的元素吗?
如何将 testthat 测试应用于我的包中与特定命名模式匹配的所有函数?
使用 testthat 在单元测试中重用变量。是不是有一种可接受的做法来避免重新创建计算量大的变量