[英]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, 2]
和[2, 1]
是否相等?
[1, 2]
和[1, 1, 2]
是否相等?
有没有可变类型?
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 列表,你会得到比简单地使用all
或any
更好的响应。 这样,如果测试失败,您将看到预期与实际的差异
您也可以使用https://github.com/AdityaSavara/UnitTesterSG可以通过 pip UnitTesterSG 获得
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.