pytest:断言几乎相等

如何执行assert almost equal与py.test相同的浮动,而不诉诸于像这样的东西:

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

更具体地说,知道一个简洁的解决scheme可以快速比较浮点数对,

 assert (1.32, 2.4) == i_return_tuple_of_two_floats() 

我注意到这个问题特别提到了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 

文档位于: http : //doc.pytest.org/en/latest/builtin.html#pytest.approx

你将必须指定什么是“几乎”为你:

 assert abs(xy) < 0.0001 

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

 def almost_equal(x,y,threshold=0.0001): return abs(xy) < threshold assert all(map(almost_equal, zip((1.32, 2.4), i_return_tuple_of_two_floats()) 

如果你有访问NumPy它有很好的浮点比较function,已经做了两两比较: http : //docs.scipy.org/doc/numpy-dev/reference/routines.testing.html 。

然后你可以做一些事情:

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

就像是

 assert round(xy, 5) == 0 

这就是unit testing所做的

对于第二部分

 assert all(round(xy, 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(xy, 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()) 

这些答案已经存在了很长一段时间,但我认为最简单也是最可读的方法是使用unittest,因为它有许多很好的断言,而不用于testing结构。

得到断言,忽略其余的unittest.TestCase

(根据这个答案 )

 import unittest assertions = unittest.TestCase('__init__') 

做出一些断言

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

实施原始问题的自动解包testing

只需使用*解开您的返回值,而无需引入新名称。

 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 

我会用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