pytest: утверждают почти равные

Как сделать assert almost equal с py.test для поплавков, не прибегая к чему-то вроде:

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

UPD.

Более конкретно, будет полезно знать аккуратное решение для быстрого сравнения пар float, не распаковывая их:

 assert (1.32, 2.4) == i_return_tuple_of_two_floats() 

6 Solutions collect form web for “pytest: утверждают почти равные”

Вам нужно будет указать, что для вас «почти»:

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

Я заметил, что этот вопрос специально задал вопрос о 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

Если у вас есть доступ к NumPy, у него есть отличные функции для сравнения с плавающей запятой, которые уже делают парное сравнение: 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 

Это то, что делает unittest

Для второй части

 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 для многих приятных утверждений, не используя его для структуры тестирования.

Получить утверждения, игнорировать остальные 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 

Внедрить исходные вопросы по автоматической распаковке

Просто используйте * для распаковки возвращаемого значения без необходимости вводить новые имена.

 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 

Я бы использовал носовые инструменты. Он хорошо работает с run.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 
Python - лучший язык программирования в мире.