繁体   English   中英

如何断言列表与 pytest 相等

[英]How can I assert lists equality with pytest

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

我正在考虑做这样的事情:

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

第一个断言正常,但第二个断言出现值错误。

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

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

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

谢谢

看到这个

笔记:

您可以简单地使用assert语句来断言测试期望。 pytest 的高级断言自省将智能地报告断言表达式的中间值,使您无需学习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 为您完成了艰苦的工作。

你可以做一个列表推导来检查所有值的相等性。 如果你在列表推导结果上调用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

回答这个看似简单的答案有两个关键:
相等条件和断言错误有用性。

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

回答以下问题:

  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

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

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

在 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)

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM