对于没有浮点数的字典,我们使用简单的a == bwherea和bare python 字典。这很有效,直到我们最终在其中某处得到a并b包含浮点数。它们是嵌套字典,所以我认为这会带来pytest.approx麻烦。
我们想要的是告诉我们这两个字典相等(或近似相等,但仅在浮点近似时不会失败)的东西:
{"foo": {"bar": 0.30000001}} == {"foo": {"bar": 0.30000002}}
pytest.approx()几乎是我想要的,但它不支持嵌套字典。有什么东西可以做我想做的事吗?
您可以定义自己的近似助手并支持嵌套字典。不幸的是,pytest不支持approx自定义比较器的增强,因此您必须编写自己的函数;但是,它不需要太复杂:
import pytest
from collections.abc import Mapping
from _pytest.python_api import ApproxMapping
def my_approx(expected, rel=None, abs=None, nan_ok=False):
if isinstance(expected, Mapping):
return ApproxNestedMapping(expected, rel, abs, nan_ok)
return pytest.approx(expected, rel, abs, nan_ok)
class ApproxNestedMapping(ApproxMapping):
def _yield_comparisons(self, actual):
for k in self.expected.keys():
if isinstance(actual[k], type(self.expected)):
gen = ApproxNestedMapping(
self.expected[k], rel=self.rel, abs=self.abs, nan_ok=self.nan_ok
)._yield_comparisons(actual[k])
for el in gen:
yield el
else:
yield actual[k], self.expected[k]
def _check_type(self):
for key, value in self.expected.items():
if not isinstance(value, type(self.expected)):
super()._check_type()
Run Code Online (Sandbox Code Playgroud)
现在使用my_approx而不是pytest.approx:
def test_nested():
assert {'foo': {'bar': 0.30000001}} == my_approx({'foo': {'bar': 0.30000002}})
Run Code Online (Sandbox Code Playgroud)