pytest:断言几乎相等

时间:2011-12-19 10:41:55

标签: python unit-testing pytest

如何使用py.test进行浮动的assert almost equal而不诉诸:

assert x - 0.00001 <= y <= x + 0.00001

更具体地说,了解一个简洁的解决方案以快速比较浮动对,而无需解压缩它们将是有用的:

assert (1.32, 2.4) == i_return_tuple_of_two_floats()

7 个答案:

答案 0 :(得分:161)

我注意到这个问题专门询问了py.test。 py.test 3.0包含一个approx()函数(嗯,真正的类),它对此非常有用。

import pytest

assert 2.2 == pytest.approx(2.3)
# fails, default is ± 2.3e-06
assert 2.2 == pytest.approx(2.3, 0.1)
# passes

# also works the other way, in case you were worried:
assert pytest.approx(2.3, 0.1) == 2.2
# passes

文档在这里:https://docs.pytest.org/en/latest/reference.html#pytest-approx

答案 1 :(得分:38)

您必须为您指定“几乎”的内容:

assert abs(x-y) < 0.0001

应用于元组(或任何序列):

def almost_equal(x,y,threshold=0.0001):
  return abs(x-y) < threshold

assert all(map(almost_equal, zip((1.32, 2.4), i_return_tuple_of_two_floats())

答案 2 :(得分:29)

如果您有权访问NumPy,它具有很好的浮点比较功能,已经与numpy.testing进行成对比较。

然后你可以做类似的事情:

numpy.testing.assert_allclose(i_return_tuple_of_two_floats(), (1.32, 2.4))

答案 3 :(得分:11)

这样的东西
assert round(x-y, 5) == 0

这就是unittest所做的事情

第二部分

assert all(round(x-y, 5) == 0 for x,y in zip((1.32, 2.4), i_return_tuple_of_two_floats()))

可能更好地将其包装在函数中

def tuples_of_floats_are_almost_equal(X, Y):
    return all(round(x-y, 5) == 0 for x,y in zip(X, Y))

assert tuples_of_floats_are_almost_equal((1.32, 2.4), i_return_tuple_of_two_floats())

答案 4 :(得分:8)

这些答案已存在很长时间了,但我认为最简单也是最易读的方法是使用unittest many nice assertions而不将其用于测试结构。

获取断言,忽略unittest.TestCase

的其余部分

(基于this answer

import unittest

assertions = unittest.TestCase('__init__')

做一些断言

x = 0.00000001
assertions.assertAlmostEqual(x, 0)  # pass
assertions.assertEqual(x, 0)  # fail
# AssertionError: 1e-08 != 0

实施原始问题'自动拆包测试

只需使用*即可解压返回值,而无需引入新名称。

i_return_tuple_of_two_floats = lambda: (1.32, 2.4)
assertions.assertAlmostEqual(*i_return_tuple_of_two_floats())  # fail
# AssertionError: 1.32 != 2.4 within 7 places

答案 5 :(得分:2)

我使用nose.tools。它与py.test runner运行良好,并有其他同样有用的断言 - assert_dict_equal(),assert_list_equal()等。

from nose.tools import assert_almost_equals
assert_almost_equals(x, y, places=7) #default is 7 

答案 6 :(得分:2)

如果您希望某些东西不仅适用于浮点数,还可以使用小数,例如可以使用python的math.isclose

    # - rel_tol=0.01` is 1% difference tolerance.
    assert math.isclose(actual_value, expected_value, rel_tol=0.01)

文档-https://docs.python.org/3/library/math.html#math.isclose