Wie man assert almost equal
mit py.test für Floats macht, ohne auf etwas wie zu greifen:
assert x - 0.00001 <= y <= x + 0.00001
Insbesondere ist es hilfreich, eine ordentliche Lösung für den schnellen Vergleich von Floatpaaren zu kennen, ohne sie auszupacken:
assert (1.32, 2.4) == i_return_Tuple_of_two_floats()
Mir ist aufgefallen, dass diese Frage speziell nach py.test gestellt wurde. py.test 3.0 enthält eine approx()
-Funktion (naja, wirklich Klasse), die für diesen Zweck sehr nützlich ist.
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
Die Dokumentation ist hier: https://docs.pytest.org/de/latest/reference.html#pytest-approx
Sie müssen angeben, was für Sie "fast" ist:
assert abs(x-y) < 0.0001
für Tupel (oder eine beliebige Sequenz) gelten:
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())
Wenn Sie auf NumPy zugreifen können, gibt es großartige Funktionen für den Vergleich von Fließkommazahlen, die bereits einen paarweisen Vergleich mit numpy.testing
durchführen.
Dann kannst du so etwas tun:
numpy.testing.assert_allclose(i_return_Tuple_of_two_floats(), (1.32, 2.4))
So etwas wie
assert round(x-y, 5) == 0
Das ist es, was unittest tut
Für den zweiten Teil
assert all(round(x-y, 5) == 0 for x,y in Zip((1.32, 2.4), i_return_Tuple_of_two_floats()))
Wahrscheinlich besser, das in eine Funktion zu packen
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())
Diese Antworten gibt es schon lange, aber ich denke, der einfachste und auch lesbarste Weg ist, sie nur für viele Nice Assertions zu verwenden, ohne sie für die Teststruktur zu verwenden.
(basierend auf diese Antwort )
import unittest
assertions = unittest.TestCase('__init__')
x = 0.00000001
assertions.assertAlmostEqual(x, 0) # pass
assertions.assertEqual(x, 0) # fail
# AssertionError: 1e-08 != 0
Verwenden Sie einfach *, um Ihren Rückgabewert zu entpacken, ohne neue Namen eingeben zu müssen.
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
Ich würde Nasentools verwenden. Es spielt gut mit py.test runner und hat andere, ebenso nützliche Asserts - assert_dict_equal (), assert_list_equal () usw.
from nose.tools import assert_almost_equals
assert_almost_equals(x, y, places=7) #default is 7
Wenn Sie etwas möchten, das nicht nur mit Floats, sondern beispielsweise mit Decimals funktioniert, können Sie den math.isclose
von python verwenden:
# - rel_tol=0.01` is 1% difference tolerance.
assert math.isclose(actual_value, expected_value, rel_tol=0.01)
Text & Tabellen - https://docs.python.org/3/library/math.html#math.isclose