如何使用pytest断言列表相等性

bAN*_*bAN 15 python unit-testing pytest

我正在尝试用pytest进行一些单元测试.

我在考虑这样做:

actual = b_manager.get_b(complete_set)
assert actual is not None
assert actual.columns == ['bl', 'direction', 'day']
Run Code Online (Sandbox Code Playgroud)

ok中的第一个断言但是第二个我有一个值错误.

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Run Code Online (Sandbox Code Playgroud)

我假设这不是用pytest断言两个不同列表相等的正确方法.

如何断言数据帧列(列表)是否等于预期的列?

谢谢

Roc*_*ite 39

看到这个:

注意:

您可以简单地使用该assert语句来断言测试期望.pytest的高级断言内省将智能地报告断言表达式的中间值,使您无需学习JUnit遗留方法的许多名称.

:

对许多案例进行了特殊比较:

  • 比较长字符串:显示上下文差异
  • 比较长序列:首先是失败的指数
  • 比较dicts:不同的条目

报告演示:

failure_demo.py:59: AssertionError
_______ TestSpecialisedExplanations.test_eq_list ________

self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>

    def test_eq_list(self):
>       assert [0, 1, 2] == [0, 1, 3]
E       assert [0, 1, 2] == [0, 1, 3]
E         At index 2 diff: 2 != 3
E         Use -v to get the full diff
Run Code Online (Sandbox Code Playgroud)

==在那里看到列表与文字相等的断言?pytest为你完成了艰苦的工作.

  • @AllenWang,您比较的一个或两个值很可能是numpy数组。似乎在这种情况下,pytest会测试比较产生的numpy数组的真值,这是布尔值的numpy数组,并且numpy会产生以上警告。尝试用`list()`包装这两个值。 (4认同)
  • 出于某种原因,我收到了“ValueError:具有多个元素的数组的真值不明确”的错误消息。即使我使用的是 pytest 4.3.0 版,也要使用 a.any() 或 a.all()` (3认同)
  • 好答案。应该被接受。请把实际的代码示例带到答案中以使其更加清晰。 (2认同)

GGG*_*ser 19

在写断言之前,请回答以下问题:

  1. 顺序重要吗?
  2. 可以有重复吗?
  3. 可以有不可哈希的元素吗?

不,不,不:集合中的对称差异

a = [1, 2, 3]
b = [3, 2, 1]
diff = set(a) ^ set(b)
assert not diff
Run Code Online (Sandbox Code Playgroud)

在大型列表上使用此方法很方便,因为diff将只包含它们之间的差异,因此AssertionError紧凑且可读。

注意set()将删除重复项。最好也检查一下:

assert len(a) == len(set(a))
Run Code Online (Sandbox Code Playgroud)

是的,是的,是的:比较列表

a = [1, 2, 3, {'a': 1}]
b = [1, 2, 3, {'a': 1}]
assert a == b
Run Code Online (Sandbox Code Playgroud)

  • 我已经更新了我的答案。由您决定要比较列表的哪些参数。 (2认同)

rit*_*e46 14

您可以执行列表推导以检查所有值的相等性.如果您调用all列表推导结果,True如果所有参数相等,它将返回.

actual = ['bl', 'direction', 'day']

assert all([a == b for a, b in zip(actual, ['bl', 'direction', 'day'])])

print(all([a == b for a, b in zip(actual, ['bl', 'direction', 'day'])]))

>>> True
Run Code Online (Sandbox Code Playgroud)

  • 您忘记了列表长度检查。zip() 函数按最小大小的列表剪切输出。重写实际并将其设置为 ['bl', 'direction', 'day', 'MYAHAHA'] 甚至 [] 并得到 True :P 我会尝试重写你的示例。 (7认同)

Ada*_*son 13

在 Python 3.9 中,现在应该可以工作:

def test_arrays_equal():
    a = [1, 2, 3]
    b = [1, 2, 4]
    assert a == b
Run Code Online (Sandbox Code Playgroud)

或者,您可以将列表解析为numpy数组并使用 function array_equal

import numpy as np

def test_arrays_equal():
    a = [1, 2, 3]
    b = [1, 2, 4]
    ar = np.array(a)
    br = np.array(b)
    assert np.array_equal(ar, br)
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您使用内置的unittest.TestCase,那么已经有一种方法可以为您做到这一点:unittest.TestCase.assertListEqual如果您关心列表排序,unittest.TestCase.assertCountEqual如果您不关心列表排序。

https://docs.python.org/3.5/library/unittest.html#unittest.TestCase.assertCountEqual

  • 在 pytest 测试用例中调用 `unittest.TestCase().assertCountEqual(first, second)` 工作得很好。如果断言失败,您将收到更糟糕的错误消息(从 assertCountEqual 方法中进行回溯),否则没有问题。 (6认同)
  • 我使用的是 pytest,而不是内置的 unittest 包。这就是为什么我不使用 assertListEqual .. (2认同)