¿Cuál debería ser mi primer test? ¿y el siguiente? Cada vez que empezamos a escribir test nos vienen a la cabeza cuestiones similares. La decisión a veces es fácil y otras, no tanto. Pero esto no solo cuando escribimos tests, al leer los nombres de los test no se acercan ni de lejos a lo que estamos intentando probar.
Tenemos diferentes puntos de vista a la hora de decidir como empezar a «meterle mano» a los tests. Podemos pararnos a pensar en nombrar muy bien el nombre del test, podemos dejar que flow nos guíe y escribir el nombre del test más tarde. También podemos escribir un comentario con los tests que pensamos escribir al principio de la clase y mantener el comentario actualizado. Y lo más complicado de todo esto es cuando intentamos hacer pairing y encontrar un poco de consenso con el compañero, cada uno tiene su aproximación y es necesario llegar a un acuerdo pronto.
En este post vamos a dialogar sobre como poner nombre a los tests, lo que escribo aquí es solo una aproximación y seguramente entre todos podamos iterar sobre esta solución opinión o encontrar diferentes visiones para que podamos extraer ideas.
Este enfoque nos obliga a pensar en el comportamiento, intentando que los nombres de los tests sean entendibles incluso por alguien de negocio. Una vez que tenemos un buen nombre para el test, crear el assert es bastante sencillo.
Una nota al pie, es que creo que intentar tener las tres partes dentro del test (given, when, then). Sin embargo, en algunas pruebas no son necesarias las 3 partes ya que son lo suficientemente simples (un par de lineas a lo sumo) para que no hagan falta.
Nombres malos
Tener nombres con poca semántica o incluso abreviaturas, creo que rompe un poco el flujo a la hora de leer el test y en algún momento podría llevarnos a tener dudas.
$test = new BankAccount();
$sut = new BankAccount();
$ba = new BankAccount();
Y para los nombres de los tests, pasa algo parecido
test_deposit_works() {…} // what does 'works' mean?
test_deposit_works_correctly() {…} // should it ever work incorrectly?
test_deposit() {…} // what exactly is it testing?
check_balance_after_deposit() {…} // what is it checking?
¿qué quiere decir que el método works? ¿funciona?, lo mismo con works correctly, ¿podría no funcionar? y que estamos testando en
deposit
.
El nombre de un test debería indicar por qué un test debe pasar o no, habría que intentar no tener que mirar el assert para averiguar lo que se está probando. Llegar a esto es muy difícil, pero con un nombre como have_balance_increased_after_a_deposit
si el test falla, seguramente no sea sencillo saber por qué ha fallado.
Comentarios
Generalmente: si necesitamos comentarios, entonces nuestro código no es lo suficientemente expresivo.
En cierto modo es verdad, aunque a veces si puede ser necesario algún comentario.
De hecho cuando estamos refactorizando ver comentarios en un fichero supone un smell. Normalmente siempre escuchamos 1000 razones para evitar poner comentarios en el código. Pero simplemente no podemos puede llegar a un trozo de código y borrar todos los comentarios. Tenemos que absorber la semántica de esos comentarios mediante un buen naming de variables, refactoring o como sea.
// somedev1 - 6/7/02 Fix bug in the login screen
$x += 2 // increment x by 2
$x = $x - ($x * $x - $n) / (2 * $x) // iteration of the Newton-Raphson method for sqrt
Los 2 primeros ejemplo podemos borrarlos, en cambio, el 3º deberíamos refactorizarlo en un función para no perder semántica.
obtain versus get
Cuando tenemos un objeto que tiene una serie de propiedades, normalmente accedemos a ellas a través de métodos get, pero de un tiempo a esta parte estoy planteándome que los métodos get y set están un poco poseídos, ya que indican el acceso a una propiedad. Por ello cuando necesitamos devolver un cálculo creo que es mejor usar obtain
private function obtainScheme($url)
{
$urlParsed = parse_url($url);
return $urlParsed['scheme'];
}
Consideraciones
Estamos en constante aprendizaje, sobre todo a base prueba y error, por lo que a veces no tenemos que seguir estas reglas o las modificamos. Todo depende del problema al que nos enfrentemos y del contexto. Del mismo modo hay proyectos que ya tienen una forma estándar de escribir test y si entro nuevo lo mejor es cumplir dicho estándar. Este estándar nos evitará tener malos entendidos y/o sorpresas.
2 comentarios en “Naming, que difícil es”