# pytest: assert almost equal

## Question:

How to do `assert almost equal` with `pytest` for floats without resorting to something like:

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

More specifically it will be useful to know a neat solution for quickly comparing pairs of float, without unpacking them:

``````assert (1.32, 2.4) == i_return_tuple_of_two_floats()
``````

You will have to specify what is "almost" for you:

``````assert abs(x-y) < 0.0001
``````

to apply to tuples (or any sequence):

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

Update:
`pytest.approx` was released as part of `pytest v3.0.0` in 2016.
This answer predates it, use this if:

• you don’t have a recent version of `pytest` AND
• you understand floating point precision and it’s impact to your use case.

for practically all common scenarios, use
`pytest.approx` as suggested in this answer.

Something like

``````assert round(x-y, 5) == 0
``````

That is what unittest does

For the second part

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

Probably better to wrap that in a function

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

If you have access to NumPy it has great functions for floating point comparison that already do pairwise comparison with `numpy.testing`.

Then you can do something like:

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

These answers have been around for a long time, but I think the easiest and also most readable way is to use unittest for it’s many nice assertions without using it for the testing structure.

# Get assertions, ignore rest of unittest.TestCase

``````import unittest

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

# Make some assertions

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

# Implement original questions’ auto-unpacking test

Just use * to unpack your return value without needing to introduce new names.

``````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
``````

I’d use nose.tools. It plays well with py.test runner and have other equally useful asserts – assert_dict_equal(), assert_list_equal(), etc.

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

I noticed that this question specifically asked about pytest. pytest 3.0 includes an `approx()` function (well, really class) that is very useful for this purpose.

``````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
``````

If you want something that works not only with floats but for example Decimals you can use python’s math.isclose():

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

Could just use round()

``````a, b = i_return_tuple_of_two_floats()
assert (1.32, 2.4) == round(a,2), round(b,1)
``````
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.