如何使用 pytest 断言列表相等

我正在尝试用 < em > pytest 做一些单元测试。

我在考虑做这样的事情:

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

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

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

我认为用 pytest 断言两个不同列表的相等性是不正确的。

如何断言数据框列(一个列表)等于预期的列?

谢谢

114355 次浏览

你可以做一个列表内涵来检查所有值是否相等。如果在列表理解结果上调用 all,如果所有参数都相等,它将返回 True

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


assert len(actual) == len(expected)
assert all([a == b for a, b in zip(actual, expected)])


print(all([a == b for a, b in zip(actual, expected)]))


>>> True

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

Https://docs.python.org/3.5/library/unittest.html#unittest

这个:

注:

您可以简单地使用 assert语句来断言 test 期望。派特的 高级断言自省将 智能地报告断言表达式的中间值 将您从需要学习 < a href = “ http://docs.python.org/library/unittest.html # test-cases”rel = “ norefrer”> JUnit 遗产的许多名称中解放出来 方法 .

还有 这个:

对一些情况进行了特别比较:

  • 比较长字符串: 显示了上下文差异
  • 比较长序列: 第一个失败的索引
  • 比较词汇: 不同的词条

还有 报告示范:

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

看到这个与字面 ==相等的列表断言了吗? pytest 已经为您完成了这项艰巨的工作。

将 numpy 数组转换为 python 列表,您将获得比简单使用 allany更好的响应。这样,如果测试失败,您将看到预期与实际的差异

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

def test_arrays_equal():
a = [1, 2, 3]
b = [1, 2, 4]
assert a == b

或者,您可以将列表解析为 numpy数组并使用函数 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)

这个看似简单的答案有两个答案:
相等条件和断言错误帮助。

相等的条件取决于给定的约束和要求。 断言错误应该指向违反这些条件的情况。

回答以下问题:

  1. 列表的顺序重要吗?

    [1, 2][2, 1]是否相等?

  2. 列表可以有副本吗?

    [1, 2][1, 1, 2]是否相等?

  3. 有不可散列的元素吗?

    有没有可变的类型?

  4. 断言错误是否应该提供信息并有帮助?

不,不,不,不: 对称差之间

def test_nnnn():
expected = [1, 2, 3]
actual = [4, 3, 2, 1]
difference = set(a) ^ set(b)
assert not difference

E assert not {4, 5}

在大型列表上使用这种方法很方便,因为它很快,而且 difference在它们之间只包含 hm 差异,所以 AssertionError将是紧凑的,但是没有信息。

不,不,不,是: 带有自定义消息的集之间的差异

def test_nnny():
expected = [1, 2, 3, 4]
actual = [5, 3, 2, 1]
lacks = set(expected) - set(actual)
extra = set(actual) - set(expected)
message = f"Lacks elements {lacks} " if lacks else ''
message += f"Extra elements {extra}" if extra else ''
assert not message

E AssertionError: assert not 'Lacks elements {4} Extra elements {5}'

不,是,不,是: 检查重复,比集合中的差异

因为 set()删除了重复的内容,所以你应该提前检查它们。 用这个答案:

def test_nyny():
expected = [1, 2, 3, 4]
actual = [1, 2, 3, 3, 5]


seen = set()
duplicates = list()
for x in actual:
if x in seen:
duplicates.append(x)
else:
seen.add(x)


lacks = set(expected) - set(actual)
extra = set(actual) - set(expected)
message = f"Lacks elements {lacks} " if lacks else ''
message += f"Extra elements {extra} " if extra else ''
message += f"Duplicate elements {duplicates}" if duplicates else ''
assert not message

E AssertionError: assert not 'Lacks elements {4} Extra elements {5} Duplicate elements [3]'

是,是,是,否: 比较清单

def test_yyyn():
expected = [1, 2, 3, 3, 3, {'a': 1}]
actual = [3, 3, 2, 1, {'a': 1}]
assert expected == actual

E AssertionError: assert [1, 2, 3, 3, 3, {'a': 1}] == [3, 3, 2, 1, {'a': 1}]

是的,是的,是的,是的: 额外的图书馆

看看 DeepDiff

您也可以使用 https://github.com/AdityaSavara/UnitTesterSG,它可以通过 pip UnitTesterSG 获得