python - Pytest: afirmar casi igual
unit-testing py.test (6)
Cómo hacer assert almost equal
con py.test para floats sin recurrir a algo como:
assert x - 0.00001 <= y <= x + 0.00001
Más específicamente, será útil conocer una solución clara para comparar rápidamente pares de flotadores, sin desempaquetarlos:
assert (1.32, 2.4) == i_return_tuple_of_two_floats()
Algo como
assert round(x-y, 5) == 0
Eso es lo que hace unittest
Para la segunda parte
assert all(round(x-y, 5) == 0 for x,y in zip((1.32, 2.4), i_return_tuple_of_two_floats()))
Probablemente sea mejor envolver eso en una función
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())
Deberá especificar qué es "casi" para usted:
assert abs(x-y) < 0.0001
para aplicar a tuplas (o cualquier secuencia):
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())
Estas respuestas han existido por mucho tiempo, pero creo que la forma más sencilla y legible es usar unittest para sus muchas buenas afirmaciones sin usarlo para la estructura de prueba.
Obtenga afirmaciones, ignore el resto de unittest.TestCase
(basado en esta respuesta )
import unittest
assertions = unittest.TestCase(''__init__'')
Haz algunas afirmaciones
x = 0.00000001
assertions.assertAlmostEqual(x, 0) # pass
assertions.assertEqual(x, 0) # fail
# AssertionError: 1e-08 != 0
Implementar la prueba de desempaquetado automático de las preguntas originales
Simplemente use * para descomprimir su valor de retorno sin necesidad de introducir nuevos nombres.
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
Me di cuenta de que esta pregunta específicamente sobre py.test. py.test 3.0 incluye una función approx()
(bueno, realmente clase) que es muy útil para este propósito.
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
La documentación está aquí: https://docs.pytest.org/en/latest/reference.html#pytest-approx
Si tiene acceso a NumPy, tiene grandes funciones para la comparación de punto flotante que ya hacen comparación por pares: http://docs.scipy.org/doc/numpy-dev/reference/routines.testing.html .
Entonces puedes hacer algo como:
numpy.testing.assert_allclose(i_return_tuple_of_two_floats(), (1.32, 2.4))
Yo usaría nose.tools. Funciona bien con py.test runner y tiene otras afirmaciones igualmente útiles: assert_dict_equal (), assert_list_equal (), etc.
from nose.tools import assert_almost_equals
assert_almost_equals(x, y, places=7) #default is 7