ivanbtrujillo / ivanbtrujillo.com

Blog using Next
https://ivanbtrujillo.now.sh
0 stars 0 forks source link

Testear y refactorizar. El camino hacia un buen software. #15

Open ivanbtrujillo opened 4 years ago

ivanbtrujillo commented 4 years ago

date: "2020-06-22" img: "https://res.cloudinary.com/ivanbtrujillo/image/upload/v1592837435/photo-1530447920184-b88c8872_tokjr5.jpg" summary: Cuando decimos refactorizar, ¿realmente estamos refactorizando o simplemente cambiando un código sin mejorarlo? En esta entrada hablaremos de refactorizar y algunos consejos para hacerlo.

En 1999 Martin Flowler decía: Cualquier tont@ puede escribir un código que un ordenador entienda. L@s buen@s programadores escriben codigo que los humanos entienden.

Muchas veces nos encontramos con código imposible de mantener, o el cual no sabemos si cambiándolo modificamos algun comportamiento que no queremos debido a que no está testeado, o incluso somos nosotr@s mism@s l@s que creamos un código para completar una tarea sin importarnos que esté testeado, sea escalable y mantenible ya que nuestra misión es hacer una feature.

Realmente, como desarrolladores debemos ser profesionales. Un código cuando es dificil de testear, tiene todas las papeletas para ser refactorizado y es una señal bastante fiable de lo acoplado que está al resto de la aplicación, pero...¿qué es refactorizar?

La definición de refactorizar es realizar un cambio en la estructura interna de un software para hacerlo mas facil de entender y mas barato de modificar, sin cambiar su comportamiento.

Para cumplir la última premisa, debemos de tener una forma fiable y medible para saber si el comportamiento ha cambiado o no. Esto lo podemos realizar con test: unitarios, de integracion y e2e.

En este punto, sabemos dos cosas:

  1. Que és refactorizar
  2. Para refactorizar, necesitamos probar nuestro código.

Hay un principio boy scout en el desarrollo de software que dice que, cuando te encuentres un codigo, intenta dejarlo mejor que como lo encontraste. Obviamente no podemos pasar el día refactorizando cada fichero que abramos, pero si podemos mejorar los ficheros en los que tenemos que trabajar para implementar una nueva característica o resolver un bug.

Primero hay que aprender a gatear, luego a andar y luego podremos correr

Cuando tenemos que añadir una característica nueva a nuestro código pero no esta estructurado correctamente, primero debemos refactorizarlo para que dicha característica sea facil de implementar y luego debemos añadir la característica. Esto debes hacerlo en procesos separados, es decir, primero refactoriza (commitea) y luego añade la característica (commitea), de esta forma en una revision de código es mucho mas sencillo explicar el motivo del refactoring y explicar la funcionalidad sin mezclar una cosa con la otra.

Tenemos que ser conscientes que no estamos refactorizando cuando cambiamos el código sin tener tests que verifiquen que no ha cambiado su comportamiento. Únicamente estamos cambiando código, pero no refactorizando.

El mejor consejo que te puedo dar cuando tienes un codigo muy grande y acoplado, es empezar a separar poco a poco. Igual que cuando un policía forense se encuentra una escena del crimen, debemos de empezar a buscar pruebas que nos digan que ocurre y nos permitan poco a poco entender lo que ocurre. Una vez tenemos una prueba ("este trozo de codigo hace X") podemos sacarlo a una funcion independiente y testearlo.

Usa funciones puras

Un buen consejo aqui es hacer funciones puras, es decir, dado el mismo input, devuelvan siempre el mismo output. De esta forma, podemos testearla facilmente y ya habremos dado un pequeño paso en nuestro refactor. Recuerda: la mutabilidad es el demonio 🤣

Un buen nombre

Otro buen consejo es dar un buen nombre a nuestras funciones y variables. X, Y, Z, aux ...no son un buen nombre. El código debe de contar que hace sin entrar a ver su implementación.

Lo cierto es que es bastante habitual hablar de todo esto pero en la práctica nadie, o muy poca gente lo hace. Es normal y entendible, muchas veces no disponemos de todo el tiempo del mundo para hacer un codigo perfecto. En este caso, te puedo dar tres consejos:

  1. Aprende TDD. Si para crear tu código haces tu test primero, automáticamente tendrás tu codigo testeado y a su vez documentado. Al principio el desarrollo será lento, pero poco a poco irás cogiendo velocidad hasta que empiezes a entregar un código de alta calidad testeado. Tus clientes o tu empresa verá que el codigo de pepito tiene muy pocos bugs o en el caso de tenerlos, es facil detectar dónde y arreglarlo al tener una buena covertura de test.

  2. En lo que aprendes TDD, puedes crear tu test despues de hacer una feature. Lo mejor es que sigas los principios DRY (Don't repeat yourself) and KISS (Keep it stupid simple). De esta forma aunque no puedas testearlo todo (por ejemplo, no tienes tiempo para aprender como testear un custom hook en React), la mayoria de funciones y utilidades podrás testearlas.

  3. Si no sabes como testear, en lo que aprendes como testear, añade comentarios a tus funciones que detallen como deben de funcionar y un TODO para reemplazar ese comentario por un test o una serie de tests que comprueben (y a su vez documenten) su comportamiento.

Referencias y documentación

Como punto final a esta entrada de blog, te dejo por aqui referencias a libros que te serán de utilidad:

- Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin) - Refactoring: Improving the Design of Existing Code (Martin Fowler)

Por último, si eres desarrollador frontend y te gusta React, este libro es muy bueno para empezar con TDD:

- React Test Driven Development (Daniel Irvine)

¿Tienes libros, articulos o referencias que quieras recomendar? ¡Deja un comentario!