¿Cuáles son las mejores prácticas para nombrar clases de prueba unitarias y métodos de prueba?
Esto se discutió en SO antes, en ¿Cuáles son algunas convenciones de nomenclatura populares para las pruebas unitarias?
No sé si este es un enfoque muy bueno, pero actualmente en mis proyectos de prueba, tengo mapeos uno a uno entre cada clase de producción y una clase de prueba, por ejemplo, Product
y ProductTest
.
En mis clases de prueba, luego tengo métodos con los nombres de los métodos que estoy probando, un guión bajo, y luego la situación y lo que espero que suceda, por ejemplo Save_ShouldThrowExceptionWithNullName()
.
unit-testing
naming-conventions
James Newton-King
fuente
fuente
test<MethodUnderTest>_<state>
por ejemplo,testPop_emptyStack
google-styleguide.googlecode.com/svn/trunk/javaguide.html 5.2.3 Nombres de métodos. En caso de duda, sigue a Google.Respuestas:
Me gusta la estrategia de nombres de Roy Osherove , es la siguiente:
[UnitOfWork_StateUnderTest_ExpectedBehavior]
Tiene toda la información necesaria sobre el nombre del método y de manera estructurada.
La unidad de trabajo puede ser tan pequeña como un solo método, una clase o tan grande como varias clases. Debe representar todas las cosas que se probarán en este caso de prueba y que están bajo control.
Para los ensambles utilizo el
.Tests
final típico , que creo que está bastante extendido y lo mismo para las clases (que termina conTests
):[NameOfTheClassUnderTestTests]
Anteriormente utilicé Fixture como sufijo en lugar de Pruebas, pero creo que este último es más común, luego cambié la estrategia de nomenclatura.
fuente
UpdateManager.Update()
. Teniendo esto en cuenta, tiendo a llamar a mis pruebasWhenUpdating_State_Behaviour
oWhenUpdating_Behaviour_State
. De esta manera, pruebo una acción particular de una clase mientras evito poner un nombre de método en un nombre de prueba. Pero lo más importante es que tengo que tener una idea de qué lógica empresarial está fallando cuando veo el nombre de una prueba que fallaMe gusta seguir el estándar de nomenclatura "Debería" para las pruebas al nombrar el dispositivo de prueba después de la unidad bajo prueba (es decir, la clase).
Para ilustrar (usando C # y NUnit):
¿Por qué "debería" ?
Encuentro que obliga a los escritores de prueba a nombrar la prueba con una oración en la línea de "Debería [estar en algún estado] [después / antes / cuando] [la acción se lleva a cabo]"
Sí, escribir "Debería" en todas partes se vuelve un poco repetitivo, pero como dije obliga a los escritores a pensar de la manera correcta (por lo que puede ser bueno para los principiantes). Además, generalmente da como resultado un nombre de prueba legible en inglés.
Actualización :
Me he dado cuenta de que Jimmy Bogard también es fanático del 'debería' e incluso tiene una biblioteca de pruebas unitarias llamada debería .
Actualización (4 años después ...)
Para aquellos interesados, mi enfoque para nombrar pruebas ha evolucionado a lo largo de los años. Uno de los problemas con el patrón Deber que describo anteriormente es que no es fácil saber de un vistazo qué método se está probando. Para OOP, creo que tiene más sentido comenzar el nombre de la prueba con el método bajo prueba. Para una clase bien diseñada, esto debería dar como resultado nombres de métodos de prueba legibles. Ahora uso un formato similar a
<method>_Should<expected>_When<condition>
. Obviamente, dependiendo del contexto, es posible que desee sustituir los verbos debería / cuándo por algo más apropiado. Ejemplo:Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()
fuente
increasesBalanceWhenDepositIsMade()
.Me gusta este estilo de nombres:
y así. Realmente deja claro a un no evaluador cuál es el problema.
fuente
should
lo preferiríawill
asíOrdersWithNoProductsWillFail()
Will
no es realmente apropiado y al hacerlo, le estás diciendo al lector por error que de ninguna manera la prueba fallará ... si usasWill
para expresar algo en el futuro que podría no suceder, estás usarlo incorrectamente, mientras queShould
es la mejor opción aquí porque indica que desea / desea que suceda algo, pero no sucedió o no pudo, cuando se ejecuta la prueba le dice si falló / tuvo éxito, por lo que no puede implicar que de antemano, esa es la explicación lógica, ¿cuál es la tuya? ¿Por qué lo evitasShould
?Kent Beck sugiere:
Un accesorio de prueba por 'unidad' (clase de su programa). Los accesorios de prueba son clases en sí. El nombre del dispositivo de prueba debe ser:
Los casos de prueba (los métodos de fijación de prueba) tienen nombres como:
Por ejemplo, tener la siguiente clase:
Un accesorio de prueba sería:
fuente
Nombres de clase . Para los nombres de los dispositivos de prueba, encuentro que "Prueba" es bastante común en el lenguaje ubicuo de muchos dominios. Por ejemplo, en un dominio de la ingeniería:
StressTest
y en un dominio de cosméticos:SkinTest
. Lamento no estar de acuerdo con Kent, pero usar "Test" en mis accesorios de prueba (StressTestTest
?) Es confuso."Unidad" también se usa mucho en dominios. Por ej
MeasurementUnit
. ¿Se llama una claseMeasurementUnitTest
una prueba de "Medición" o "Unidad de medida"?Por eso me gusta usar el prefijo "Qa" para todas mis clases de prueba. Por ejemplo
QaSkinTest
yQaMeasurementUnit
. Nunca se confunde con los objetos de dominio, y el uso de un prefijo en lugar de un sufijo significa que todos los accesorios de prueba viven juntos visualmente (útil si tiene falsificaciones u otras clases de apoyo en su proyecto de prueba)Espacios de nombres . Trabajo en C # y mantengo mis clases de prueba en el mismo espacio de nombres que la clase que están probando. Es más conveniente que tener espacios de nombres de prueba separados. Por supuesto, las clases de prueba están en un proyecto diferente.
Nombres de métodos de prueba . Me gusta nombrar mis métodos WhenXXX_ExpectYYY. Aclara la condición previa y ayuda con la documentación automatizada (a la TestDox). Esto es similar al consejo del blog de pruebas de Google, pero con una mayor separación de precondiciones y expectativas. Por ejemplo:
fuente
Yo uso el concepto dado-cuando-entonces . Eche un vistazo a este breve artículo http://cakebaker.42dh.com/2009/05/28/given-when-then/ . El artículo describe este concepto en términos de BDD, pero también puede usarlo en TDD sin ningún cambio.
fuente
Ver: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html
Para los nombres de los métodos de prueba, personalmente considero que usar nombres detallados y auto documentados es muy útil (junto con los comentarios de Javadoc que explican más a fondo lo que está haciendo la prueba).
fuente
Creo que una de las cosas más importantes es ser coherente en su convención de nomenclatura (y estar de acuerdo con otros miembros de su equipo). Muchas veces veo muchas convenciones diferentes utilizadas en el mismo proyecto.
fuente
Recientemente se me ocurrió la siguiente convención para nombrar mis pruebas, sus clases y proyectos que contengan para maximizar sus descriptivos:
Digamos que estoy probando la
Settings
clase en un proyecto en elMyApp.Serialization
espacio de nombres.Primero crearé un proyecto de prueba con el
MyApp.Serialization.Tests
espacio de nombres.Dentro de este proyecto y, por supuesto, el espacio de nombres crearé una clase llamada
IfSettings
(guardada como IfSettings.cs ).Digamos que estoy probando el
SaveStrings()
método. -> Voy a nombrar la pruebaCanSaveStrings()
.Cuando ejecuto esta prueba, mostrará el siguiente encabezado:
MyApp.Serialization.Tests.IfSettings.CanSaveStrings
Creo que esto me dice muy bien lo que está probando.
Por supuesto, es útil que en inglés el sustantivo "Tests" sea el mismo que el verbo "tests".
No hay límite para su creatividad al nombrar las pruebas, de modo que obtengamos títulos completos de las oraciones para ellas.
Por lo general, los nombres de las pruebas tendrán que comenzar con un verbo.
Ejemplos incluyen:
DetectsInvalidUserInput
. Ej. )ThrowsOnNotFound
)WillCloseTheDatabaseAfterTheTransaction
)etc.
Otra opción es usar "eso" en lugar de "si".
Sin embargo, este último me ahorra pulsaciones de teclas y describe más exactamente lo que estoy haciendo, ya que no sé, que el comportamiento probado está presente, pero estoy probando si lo está.
[ Editar ]
Después de usar la convención de nomenclatura anterior durante un poco más de tiempo, descubrí que el prefijo If puede ser confuso cuando se trabaja con interfaces. Sucede que la clase de prueba IfSerializer.cs se parece mucho a la interfaz ISerializer.cs en la "pestaña Abrir archivos". Esto puede ser muy molesto cuando se alterna entre las pruebas, la clase que se está probando y su interfaz. Como resultado, ahora elegiría Eso sobre If como prefijo.
Además, ahora uso, solo para métodos en mis clases de prueba, ya que no se considera la mejor práctica en ningún otro lugar, la "_" para separar palabras en los nombres de mis métodos de prueba como en:
Encuentro que esto es más fácil de leer.
[ Finalizar edición ]
Espero que esto genere algunas ideas más, ya que considero que nombrar las pruebas es de gran importancia, ya que puede ahorrarle mucho tiempo que de lo contrario se habría gastado tratando de comprender lo que están haciendo las pruebas (por ejemplo, después de reanudar un proyecto después de una pausa prolongada) .
fuente
En VS + NUnit, generalmente creo carpetas en mi proyecto para agrupar las pruebas funcionales. Luego creo clases de dispositivos de prueba de unidad y les doy el nombre del tipo de funcionalidad que estoy probando. Los métodos [Test] se nombran a lo largo de las líneas de
Can_add_user_to_domain
:fuente
Debo agregar que mantener sus pruebas en el mismo paquete, pero en un directorio paralelo a la fuente que se está probando, elimina la hinchazón del código una vez que esté listo para implementarlo sin tener que hacer un montón de patrones de exclusión.
Personalmente, me gustan las mejores prácticas descritas en la "Guía de bolsillo JUnit" ... ¡es difícil superar un libro escrito por el coautor de JUnit!
fuente
el nombre del caso de prueba para la clase Foo debe ser FooTestCase o algo similar (FooIntegrationTestCase o FooAcceptanceTestCase), ya que es un caso de prueba. Consulte http://xunitpatterns.com/ para conocer algunas convenciones de nomenclatura estándar como prueba, caso de prueba, dispositivo de prueba, método de prueba, etc.
fuente