无论顺序如何,如何测试列表是否相等?

时间:2019-07-09 21:24:25

标签: r unit-testing testing equality testthat

我正在使用 testthat 框架,但是这个问题应该适合更大的背景。基本上,我有一个输出此功能的函数

final List<DocumentSnapshot> userList = snapshot.data.documents;

userList.removeWhere((DocumentSnapshot documentSnapshot) => documentSnapshot['userId'] != id).toList();

但是,我不在乎订单,所以也很好

list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"))

如何测试与list("PL+", c("PW-", "PL+"), "PL+", "PW-", "PW-") 的相等性?我本来考虑在expect_equal之后加上unlist,但这会破坏嵌套结构。

3 个答案:

答案 0 :(得分:1)

您可以使用purrr::map_depth对嵌套列表进行排序,然后使用setdiff检查列表。如果调用setdiff的长度为0,则列表包含相同的元素。棘手的是,setdiff会根据其参数的顺序产生不同的结果,因此您最终会两次调用它,每个方向调用一次。这类似于在testthat::expect_setequal中进行的双重检查。

为简单起见,我将其包装在一个函数中。相反,您可以结合使用all%in%来做同样的事情,但这看起来很紧凑。

a1 <- list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"))
b1 <- list("PL+", c("PW-", "PL+"), "PL+", "PW-", "PW-")

nested_equal <- function(l1, l2) {
  left_diff <- setdiff(
    purrr::map_depth(l1, 1, sort),
    purrr::map_depth(l2, 1, sort)
  )
  right_diff <- setdiff(
    purrr::map_depth(l2, 1, sort),
    purrr::map_depth(l1, 1, sort)
  )
  (length(left_diff) == 0) & (length(right_diff) == 0)
}

nested_equal(a1, b1)
#> [1] TRUE

一些具有不同元素的测试用例:

a2 <- list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"), "A")
b2 <- list("PL+", c("PW-", "PL+"), "PL+", "PW-", "PW-")

nested_equal(a2, b2)
#> [1] FALSE

a3 <- list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"))
b3 <- list("PL+", c("PW-", "PL+", "X"), "PL+", "PW-", "PW-", "B")

nested_equal(a3, b3)
#> [1] FALSE

要适合testthat测试,可以针对nested_equalexpect_equalexpect_trueexpect_false返回的真或假值进行测试。 / p>

答案 1 :(得分:0)

sort()unlist()可能是最好的选择。

identical(sort(unlist(a1)), sort(unlist(b1)))

您对打破嵌套结构表示犹豫,但请注意sort(unlist(...))不是永久性的。您仍然可以毫无问题地访问任何一个列表。

此外,虽然我对testthat包不熟悉,但是expect_equalexpect_identical应该提供相似的结果,尽管如果相等,则该语句将以静默方式执行。

> identical(sort(unlist(a1)), sort(unlist(b1)))
[1] TRUE
> a1
[[1]]
[1] "PL+"

[[2]]
[1] "PW-"

[[3]]
[1] "PL+"

[[4]]
[1] "PW-"

[[5]]
[1] "PL+" "PW-"

数据向@camille发送数据。

a1 <- list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"))
b1 <- list("PL+", c("PW-", "PL+"), "PL+", "PW-", "PW-")

答案 2 :(得分:0)

浏览列表中的元素并相互检查

l1 = list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"))
l2 = list("PL+", c("PW-", "PL+"), "PL+", "PW-", "PW-")
temp = sapply(l1, function(x) sapply(l2, function(y) identical(sort(x), sort(y))))
all(rowSums(temp) > 0) & all(colSums(temp) > 0)
#[1] TRUE