¿Debería realizarme pruebas unitarias para detectar defectos conocidos?

37

Si mi código contiene un defecto conocido que debería corregirse, pero aún no lo es, y no se solucionará en la versión actual, y podría no corregirse en el futuro previsible, en caso de que haya una prueba de unidad fallida para ese error en la suite de prueba? Si agrego la prueba unitaria, fallará (obviamente), y acostumbrarse a tener pruebas fallidas parece una mala idea. Por otro lado, si se trata de un defecto conocido, y hay un caso de falla conocido, parece extraño mantenerlo fuera del conjunto de pruebas, ya que en algún momento debería repararse, y la prueba ya está disponible.

Martijn
fuente
66
No creo que tan mosquito, pregunto específicamente sobre la prueba de unidad
Martijn
3
las pruebas de defectos conocidos se conocen como pruebas de regresión , estas no tienen nada que ver con las pruebas unitarias ... para ser precisos, esto último depende de la opinión del desarrollador; su pregunta tal vez no sea un duplicado, sino una encuesta de opiniones. Es especialmente destacado que la respuesta que aceptó no usa el término "pruebas unitarias" en absoluto, sino que llama razonablemente a estas "pruebas fallidas conocidas" diferentes
mosquito
3
Gracias Michael, que hace ayuda en la forma de marcar este tipo de pruebas en JUnit, pero no realmente en la práctica de la prueba. mosquito, todavía no entiendo cómo ves una prueba de unidad que falla como una prueba de regresión. También recibo una vibra pasiva / agresiva distintivamente hostil a partir de sus comentarios. Si cree que debería hacer preguntas de manera diferente, dígalo, porque no puedo abordar sus inquietudes si las formula así.
Martijn
3
@gnat: honestamente, en mi humilde opinión, no importa si llamamos a las pruebas aquí "unidad" o prueba de "regresión": la pregunta que ha vinculado también tiene un enfoque diferente, y las respuestas allí no se aplican aquí.
Doc Brown

Respuestas:

51

La respuesta es sí, debe escribirlos y ejecutarlos.

Su marco de pruebas necesita una categoría de "pruebas fallidas conocidas" y debe marcar estas pruebas como pertenecientes a esa categoría. Cómo lo hagas depende del marco.

Curiosamente, una prueba de reprobación que de repente pasa puede ser tan interesante como una prueba de aprobación que falla inesperadamente.

david.pfx
fuente
77
Un ejemplo de la característica anterior en el marco de prueba de unidad de
Jace Browning
5

Creo que debería hacerse una prueba unitaria con el comportamiento actual y, en los comentarios, agregar la prueba correcta y el comportamiento correcto. Ejemplo:

@Test
public void test() {
  // this is wrong, it should be fixed some time
  Assert.assertEquals(2, new Calculator().plus(2,2));
  // this is the expected behaviour, replace the above test when the fix is available
  // Assert.assertEquals(4, new Calculator().plus(2, 2));
}

De esta manera, cuando la solución esté disponible, la compilación fallará, notando la prueba fallida. Cuando vea la prueba, sabrá que cambió el comportamiento y la prueba debe actualizarse.

EDITAR: Como dijo el Capitán Man, en proyectos grandes, esto no se solucionará pronto, pero por el bien de la documentación, la respuesta original es mejor que nada.

Una mejor manera de hacerlo es duplicando la prueba actual, haciendo que el clon afirme lo correcto y @Ignorecon un mensaje, por ejemplo

@Test
public void test() {
  Assert.assertEquals(2, new Calculator().plus(2,2));
}

@Ignore("fix me, Calculator is giving the wrong result, see ticket BUG-12345 and delete #test() when fixed")
@Test
public void fixMe() {
  Assert.assertEquals(4, new Calculator().plus(2, 2));
}

Esto viene con la convención en su equipo para reducir el número de @Ignorepruebas d. De la misma manera que lo haría al introducir o cambiar la prueba para reflejar el error, excepto que no falla la compilación si esto es crítico para su equipo, como OP dijo que la corrección del error no se incluirá en la versión actual .

Silviu Burcea
fuente
1
Este es un mal consejo. Nadie intentará arreglarlo. Las personas solo abrirán pruebas unitarias antiguas si hay problemas de compilación o fallas en las pruebas.
Capitán Man
@CaptainMan Estoy de acuerdo, he actualizado mi respuesta para proporcionar una mejor manera de que el equipo de desarrollo sea consciente de un error sin fallar la compilación. Su voto negativo se justificó por la respuesta original que publiqué hace 3 años, creo que la respuesta actual es más apropiada. ¿Lo harías de otra manera?
Silviu Burcea
Esto es casi exactamente lo que hago en las raras ocasiones en que no puedo solucionar el error ahora por alguna razón. Me encantaría saber cómo manejas la situación @CaptainMan
RubberDuck
@RubberDuck No hay realmente ninguna situación ideal aquí (aparte de arreglar el error ahora jaja). Para mí, al menos ver en los resultados de la prueba "10 aprobado, 0 falló, 1 omitido" es al menos una indicación de que algo es sospechoso para las personas que no están familiarizadas con él. Prefiero el @Ignoreenfoque. La razón por la que usar solo un comentario no me parece una buena idea es porque no creo que la gente a menudo abra pruebas unitarias para verificarlas (a menos que estén fallando, o (con suerte) cuando se preguntan por qué se ignora algo )
Capitán Man
@RubberDuck No hay realmente ninguna situación ideal aquí (aparte de arreglar el error ahora jaja). Para mí, al menos ver en los resultados de la prueba "10 aprobados, 0 fallados, 1 omitido" es al menos una indicación de que algo es sospechoso para las personas que no están familiarizadas con él. Prefiero el @Ignoreenfoque. La razón por la que usar solo un comentario no me parece una buena idea es porque no creo que las personas a menudo abran pruebas unitarias para verificarlas (a menos que estén fallando, o (con suerte) cuando se preguntan por qué se está omitiendo algo )
Capitán Man
3

Dependiendo de la herramienta de prueba, puede usar una función omito pend.

Ejemplo en rubí:

gem 'test-unit', '>= 2.1.1'
require 'test/unit'

MYVERSION = '0.9.0' #Version of the class you test 


class Test_omit < Test::Unit::TestCase
  def test_omit
    omit('The following assertion fails - it will be corrected in the next release')
    assert_equal(1,2)
  end

  def test_omit_if
    omit_if(MYVERSION < '1.0.0', "Test skipped for version #{MYVERSION}")
    assert_equal(1,2)
  end

end

El omitcomando omite una prueba, la omit_ifcombina con una prueba; en mi ejemplo, pruebo el número de versión y ejecuto la prueba solo para las versiones donde espero que se resuelva el error.

El resultado de mi ejemplo es:

Loaded suite test
Started
O
===============================================================================
The following assertion fails - it will be corrected in the next release [test_omit(Test_omit)]
test.rb:10:in `test_omit'
===============================================================================
O
===============================================================================
Test skipped for version 0.9.0 [test_omit_if(Test_omit)]
test.rb:15:in `test_omit_if'
===============================================================================


Finished in 0.0 seconds.

2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 2 omissions, 0 notifications
0% passed

Entonces mi respuesta: Sí, implemente la prueba. Pero no confunda un probador con errores, donde sabe que fallará.

Knut
fuente
2

Si el error está fresco en tu mente y tienes tiempo para escribir la prueba de la unidad ahora, entonces lo escribiría ahora y lo marcaría como un error conocido para que no falle la construcción en sí. Su rastreador de errores debe actualizarse para reflejar que hay una prueba unitaria que actualmente está fallando para este error, de modo que la persona asignada para eventualmente solucionarlo no lo escriba de nuevo. Esto supone que el código defectuoso no necesita mucha refactorización y que la API cambia significativamente; si ese es el caso, entonces sería mejor no escribir la prueba unitaria hasta que tenga una mejor idea de cómo se debe escribir la prueba .

kaared
fuente
1

La respuesta es NO IMHO. No debe agregar una prueba unitaria para el error hasta que comience a trabajar en la corrección del error y luego escriba las pruebas que prueben el error y cuando esas pruebas estén fallando de acuerdo con el informe del error ( s) irá y corregirá el código real para que la (s) prueba (s) pasen (s) y el error se resolverá y se cubrirá después de eso.

En mi mundo, tendríamos un caso de prueba manual en el que los QE tienen fallas hasta que se solucione el error. Y nosotros, como desarrolladores, seríamos conscientes de ello a través del TC de falla manual y a través del rastreador de errores.

La razón para no agregar UT fallidos es simple. Los UT son para la retroalimentación directa y la validación de lo que yo como desarrollador estoy trabajando actualmente. Y los UT se usan en el sistema CI para asegurarse de que no haya roto algo involuntariamente en alguna otra área de código para ese módulo. Tener UTs fallando intencionalmente por un error conocido en mi humilde opinión sería contraproducente y simplemente erróneo.

Grenangen
fuente
0

Supongo que la respuesta es realmente, depende. Sé pragmático al respecto. ¿Qué te gana escribirlo ahora? Tal vez es fresco en tu mente?

Al corregir el error, tiene mucho sentido demostrar que existe escribiendo una prueba unitaria que expone el error. Luego corrige el error y la prueba de la unidad debe pasar.

¿Tienes tiempo para escribir la prueba de la unidad que falla en este momento? ¿Hay más funciones urgentes o errores que necesitan ser escritos / corregidos?

Suponiendo que tiene un software de seguimiento de errores competente con el error registrado en él, realmente no hay necesidad de escribir la prueba de la unidad que falla en este momento .

Podría decirse que podría introducir cierta confusión si introduce una prueba de unidad fallida antes de una versión que está ocurriendo sin la corrección de errores.

ozz
fuente
0

Por lo general, me siento incómodo por haber tenido fallas conocidas en los conjuntos de pruebas, porque es demasiado fácil para que la lista crezca con el tiempo, o para que las fallas no relacionadas en las mismas pruebas se descarten como "esperadas". Lo mismo ocurre con las fallas intermitentes: podría haber algo malvado al acecho en el código. Votaría por escribir la prueba para el código tal como está ahora, y como debería ser una vez que se solucione pero de alguna manera se comente o se deshabilite.

Rory Hunter
fuente