Para dar un ejemplo ligeramente artificial, digamos que quiero probar que una función devuelve dos números y que el primero es más pequeño que el segundo:
def test_length():
result = my_function()
assert len(result) == 2
def test_order()
a, b = my_function()
assert a < b
Aquí, si test_length
falla, test_order
también fallará. ¿Es una buena práctica escribir test_length
u omitirlo?
EDITAR: tenga en cuenta que en esta situación, ambas pruebas son en su mayoría independientes entre sí, cada una se puede ejecutar de forma aislada, o se pueden ejecutar en orden inverso, esto no importa. Entonces ninguna de estas preguntas anteriores
- ¿Cómo debo probar la funcionalidad de una función que usa otras funciones en ella?
- ¿Necesito una prueba unitaria si ya tengo una prueba de integración?
- ¿Cómo estructurar pruebas donde una prueba es la configuración de otra prueba?
- Cómo gestionar la dependencia exitosa entre pruebas unitarias
es un duplicado del anterior.
unit-testing
Mihai
fuente
fuente
A
llamaB
y devuelve el mismo resultado, debería probar ambasA
yB
". Esto es más sobre las pruebas que se superponen en lugar de las funciones bajo prueba. (Aunque es confuso ya que actualmente están nombrados).lambda: type('', (), {'__len__': lambda self: 2})()
pasará la primera, pero no la segunda.Respuestas:
Puede haber valor, pero esto es un poco oloroso. O tus pruebas no están bien aisladas (ya que
test_order
realmente prueban dos cosas) o estás siendo demasiado dogmático en tus pruebas (haciendo que dos pruebas prueben lo mismo lógico).En el ejemplo, fusionaría las dos pruebas juntas. Sí, significa que tienes múltiples afirmaciones. Demasiado. Todavía estás probando una sola cosa: el resultado de la función. A veces en el mundo real eso significa hacer dos controles.
fuente
my_function
no devuelva exactamente dos valores, sin ninguna afirmación, porque la asignación dará como resultado una excepción. Por lo tanto, en realidad no hay necesidad de usar múltiples afirmaciones y dos comprobaciones para probar lo mismo.Sus pruebas deben ser explícitas. No se infiere completamente que si text_length falla test_order falla.
No estoy seguro de cómo va en Python lo que has publicado, pero si
len(result)
es 3, el primero fallará pero el segundo puede pasar (y si no es en Python, seguro que en idiomas como JavaScript).Como dijiste, quieres probar que la función devuelve dos números y que están en orden. Dos pruebas lo es.
fuente
It's not completely inferred that if text_length fails test_order fails
- En Python, es decir, te dará una excepción.test_length
implica el fracaso detest_order
. El hecho de que un par similar de pruebas escritas en Javascript no se comportara de la misma manera que estas dos pruebas de Python es irrelevante.El único valor de
test_length
aquí es que, si todo pasa, su sola presencia indica que se ha probado la "longitud".Por lo tanto, es realmente innecesario tener ambas pruebas. Mantenga solo
test_order
pero considere renombrarlotest_length_and_order
.Por cierto, encuentro el uso de nombres que comienzan con
test
un poco torpe. Soy un gran defensor de los nombres de las pruebas que realmente describen la condición que estás afirmando.fuente
test
verruga es significativa para el marco de prueba de Python. Lo que, por supuesto, no necesita cambiar si eres fanático de él, pero cambia el peso de la discusión necesaria para evitar que alguien lo use ;-)test_that_
, me gusta,test_that_return_values_are_in_order
etc. Tal vez una versión futura del marco de prueba evitará de alguna manera este requisito.Dejaría estas pruebas separadas si así es como han evolucionado para ser. Sí
test_order
es probable que falle siempre que lotest_length
haga, pero definitivamente sabes por qué.También estoy de acuerdo en que si
test_order
apareció primero y encontró una falla comprobable, es posible que el resultado no fueran dos valores, agregando esa verificación comoassert
y cambiando el nombre de la prueba para quetest_length_and_order
tenga sentido.Si tuviera que verificar también que los tipos de valores devueltos eran enteros, lo incluiría en esta prueba de resultados "general".
Pero tenga en cuenta que ahora tiene una batería de pruebas para el resultado de
my_function()
. Si hay múltiples contextos (o, más probablemente, múltiples parámetros) para probar esto, ahora puede ser una subrutina para probar todos los resultadosmy_function()
.Sin embargo, cuando escribo pruebas unitarias, normalmente pruebo el borde y los casos incorrectos por separado de una buena entrada y una salida normal (en parte porque la mayoría de mis pruebas "unitarias" son a menudo pruebas de mini integración), y a menudo con múltiples afirmaciones, que solo están rotas en pruebas separadas si fallan en formas en las que encuentro que quiero más información sin depurar.
Así que probablemente comenzar con sus pruebas por separado y ampliar
test_length
atest_length_and_types
y dejartest_order
aparte, suponiendo que este último se ve que es "proceso normal".fuente