Mi experiencia con la formación interna de qualtio

En este artículo presento mi experiencia tras completar la formación interna en mi nueva empresa: qualtio.

Mi nombre es Eduardo Vazquez. Soy QA.
Me incorporé a qualtio con 6 años de experiencia a mis espaldas trabajando principalmente con pruebas funcionales. Desde el primer momento vi que lo que me habían contado en el proceso de selección era cierto: la cultura de la empresa es apostar por la Calidad tanto desde el enfoque funcional como el técnico. Esto es algo que a mi me motiva especialmente para seguir aprendiendo y creciendo.
Cuando un nuevo compañero se incorpora en qualtio siempre se realizan una serie de formaciones iniciales para que todos los miembros se familiaricen o repasen conceptos y herramientas comunes en el ambito del desarrollo software que les pueden ser útiles en su día a día. Estas formaciones las preparan e imparten los miembros mas veteranos de la empresa y te introducen conceptos tales como Agile, Gherkin, Git, Jira, CI/CD, arquitecturas software mas comunes, API testing, E2E testing y análisis de código estático con SonarQube.
Además de estas pequeñas píldoras formativas, los compañeros diseñaron una formación voluntaria extra, mas larga y con un enfoque muy práctico para que otros compañeros como yo pudieramos involucrarnos en todas las fases del desarollo software.

Objetivo de la formación

El objetivo fue realizar un proyecto de software simulando una experiencia real en cliente. Había que pasar por todas las fases: definición, implementación y despliegue, incluyendo el uso de frameworks de tests apropiados y sistema de integración continua. Todo ello bajo un marco Agile (Scrum) con sus dinámicas y con los formadores ejerciendo los roles pertienentes.
Había que pasar por todas las fases: definición, implementación y despliegue, incluyendo el uso de frameworks de tests apropiados y sistema de integración continua.
Como proyecto decidí implementar una sencilla API que simula una calculadora. Para ello también pude escoger la tecnología y lenguaje para llevarlo a cabo con los que me sientera mas cómodo.

Mentor

Como figura de referencia tuve un Mentor. El Mentor era el responsable de mi formación y de mi acompañamiento y cada compañero que realizó esta formación ha tenido uno. El grupo de Mentores diseñaron los requisitos clave que tendría que cumplir cada proyecto y se alinearon para que todos los alumnos pasasemos por los mismos puntos y asi aprender todo lo mismo.
Mi primer Mentor fue Nicolás Cordero, quien se encargó de la definición de las épicas e Historias de Usuario en Jira y de dar el pistoletazo de salida al proyecto. Con el realicé mis primeras sesiones de planificación y refinamientos.
Tras su paternidad cogió las riendas Eladio Mejuto, que heredaría las funciones de negocio/Product Owner y yo recogí las de equipo de desarrollo.
La figura del Mentor, como ya he comentado, se encargaba de velar y gestionar tanto el Backlog como el PO pero también ejercía de apoyo en los momentos en los que tenía problemas sobre todo a nivel técnico.

Comienzo del proyecto

Una vez conformado el Product Backlog, lo primero que hicimos fue definir nuestro Definition of Ready (DOR) y nuestro Definition of Done (DOD) para conocer qué funcionalidades podían entrar al Sprint y qué requisitos debían cumplir para que estas se cerrasen. Tanto el DoR como DoD se fue revisando Sprint a Sprint para ver que se podía añadir o modificar a medida que la funcionalidad iba creciendo:
DOR:
    • Criterios de aceptación completos y escritos en Gherkin.
    • Escenarios de prueba con ejemplos definidos.
    • API definida con Swagger y su correspondiente contrato.
    • HU estimada y priorizada.
DOD:
    • Escenarios probados OK.
    • Quality gates de Sonar activados (80% cobertura de código test unitarios).
    • Build en Jenkins estable.
    • Merge reviews OK.
Decidimos que para estimar las tareas íbamos a utilizar la técnica de Fibonacci, definiendo la tarea más sencilla con 1 punto de historia y la tarea más compleja equivaldría a 8 puntos. Los Sprints tendrán una duración de 2 semanas.
Después, en nuestro tablero de Jira, desglosamos y refinamos las HU y tareas necesarias para la realización de la API. Inluimos tareas no solo asociadas a la funcionalidad y la entrega de valor si no de configuración de herramientas para también profundizar en ellas.
Definimos el comportamiento de la calculadora de la manera mas sencilla posible, como si se trataran de escenarios basados en BDD, usando Gherkin como DSL y pensando en los diferentes escenarios y ejemplos que debía cumplir cada Feature.

Sprint 1

Hicimos nuestra primera planificación, estimamos las HU y definimos que íbamos a meter 8 puntos de historia en este primer Sprint.
Gestionados estos puntos, dimos comienzo al desarrollo y a la preparación de las herramientas necesarias para la construcción, análisis y despliegue del servicio.
En la primera tarea decidí que JavaScript sería el lenguaje de programación más apropiado. A continuación, con ayuda de mi Mentor, decidí que la librería fuese ExpressJS con NodeJS, puesto que era la mejor combinación con el lenguaje de JS.
Después pasé a configurar el repositorio git en Gitlab y en mi repositorio local para tener un sitio donde trabajar e ir subiendo y revisando el código que iba a empezar a generar.
Una vez hecho esto, empezamos con la estructura de la API. Para documentarla elegí Swagger, puesto que no lo conocía en profundidad y quería trabajar con ello. Empecé a documentar la API para después desarrollar un endpoint base.
Una vez hecho esto, empezamos con la estructura de la API. Para documentarla elegí Swagger, puesto que no lo conocía en profundidad y quería trabajar con ello. Empecé a documentar la API para después desarrollar un endpoint base.

Sprint 2

Lo siguiente que hicimos fue planificar el Sprint 2 y lo iniciamos. En este Sprint me enfrenté al reto de configurar SonarQube para realizar análisis de código estático del proyecto. Para ello busqué una imagen de Docker, lo arranqué con un volumen local, levanté Sonar en local y lo configuré.
El segundo reto de este Sprint fue incluir Jenkins en el proyecto. La instalación fue sencilla ya que el procedimiento es similar al que seguí con Sonar. Lo más complejo para mí fue entender el funcionamiento interno de Jenkins a la hora de bajarse un proyecto, construirlo, ejecutar tests, etc.
Para aprender sobre ello tuve una sesión presencial con Eladio y Pablo Fernández. Me ayudaron a comprender cómo funcionaba Jenkins de forma remota utilizando contenedores Docker, cómo iba a funcionar en mi máquina local y los requisitos para que la construcción fuera similar a la que hago en mi repositorio al desarrollar.
Además me ayudaron a configurar los plugins de Jenkins, accesos, permisos y la conexión con Gitlab y Sonar para dejar un entorno listo y poder empezar con el pipeline.
Tras esto ya estaba en disposición de crear mi primer archivo Jenkinsfile en la raíz de mi proyecto.
Creamos 3 stages basándonos en tres puntos básicos:
				
					pipeline {
    agent any
    tools {
        nodejs 'Node-16.15.0'
    }
    stages {
        stage('Checkout') {
            steps {
                echo 'Checking'
                checkout([$class: 'GitSCM', branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'gitlab-ssh', url: 'git@gitlab.com:qualtio/university/formacion-practia/calculadora-edu-v.git']]])
            }
        }
        stage('Build') {
            steps {
                echo 'Building..'
                sh 'npm ci'
            }
        }
        stage('Test unitarios') {
            steps {
                echo 'Testing....'
                sh 'npm run test:coverage'
            }
        }
    }
}
				
			
Tras este trabajo llegó el último día del Sprint. Hicimos una nueva Review, esta vez con Eladio en el rol de negocio, para enseñarle los avances en el proyecto.

Sprint 3

El Goal de este Sprint fue empezar a meter lógica a la API, concretamente exponer el endpoint de la función “suma” e implementarla.
En este punto también decidimos que los test unitarios los íbamos a hacer utilizando Jest, por lo que tuve que configurarlo y añadir los reportes de coverage. Mi mentor me explicó los puntos básicos de Jest e hicimos juntos una clase con tests unitarios sencillos, ayudándome a ver qué deberíamos probar en cada uno y así comprender también la estructura que debe tener el código de cara a ser mantenible, testeable y a separarlo por capas.
A medida que iba desarrollando la lógica de la aplicación fui incluyendo los tests unitarios asociados, siempre pendiente de cumplir con el porcentaje de cobertura. De igual modo cada tarea relativa a desarrollo de código se subía a una rama que era revisada en una Merge Request por mi Mentor, donde debatimos acerca de la codificación y estructura del proyecto.
Una vez más, llegó el último día del Sprint y, con ello, la Review para presentar el avance del proyecto. Una vez terminado, encaramos la penúltima planificación e iniciamos el penúltimo Sprint.

Sprint 4

En este Sprint investigué cómo incluir el paquete de Swagger como dependencia Node en mi proyecto y le asigné un endpoint propio para poder consultarlo cuando arrancase el servidor de Express.
También tenía la tarea de crear una colección de Postman para poder probar los endpoints del servidor. Para ello, creé una prueba de Postman con los endpoints de suma y resta (para posteriormente incluir también multiplicación y división) y, con esto, pudimos probar manualmente que los endpoints funcionaban como debían.
Por último, lo exportamos como Json y lo incluimos en el repositorio.
Y, con esto, llegamos al último día del Sprint 4 mostrándole a Eladio los progresos en una nueva Review. Finalizamos el Sprint y encaramos la última Planning.

Sprint 5

Para este Sprint seguí incluyendo la lógica de la API. En este caso, de las operaciones «resta», «multiplicación» y «división». Hecho esto, continué Dockerizando la aplicación creando un fichero Dockerfile. La modifiqué siguiendo las buenas prácticas de Node JS:
				
					FROM node:16

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm ci --only=production

COPY . .

EXPOSE 9090

CMD [ "npm", "start" ]

				
			
Tras esto construí la imagen con el comando:
				
					docker build . -t calculadora.js/node-web-app
				
			
Para, a continuación, arrancarla con el comando:
				
					docker run -p 9090:9090 -d calculadora.js/node-web-app
				
			
Como paso final comprobamos que los endpoints de mi calculadora y Swagger continuaban funcionando correctamente.
Por último y no menos importante, creamos un archivo README, donde dejamos toda la información relativa a la aplicación, sus requisitos y los comandos principales para construir y ejecutar el servicio.

Conclusión personal

Como opinión personal es una práctica que sin duda recomiendo hacer puesto que me ha permitido abarcar todas las fases de un desarrollo que, por sencillo que sea, requiere de un abanico de conocimientos bastante amplio para que sea un proyecto software moderno y sólido.
A lo largo de los Sprints me he enfrentado a retos muy diferentes y que no dominaba y que pienso que tienen un gran valor en el sector donde trabajamos:
  • Definición, refinamiento y planificación de Historias de Usuario siguiendo las prácticas recomendadas.
  • Estudio de los diferentes tipos de tests, su implementación, configuración y ejecución.
  • Herramientas de diseño de y pruebas de API como Swagger y Postman y Jest como framework de pruebas unitarias.
  • Configuración y administración de herramientas de desarrollo, gestión de código, análisis estático e integración continua.
  • Generación de artefactos desplegables mediante Docker.
Todo ello bajo framework de trabajo ágil, como Scrum y las herramientas de gestión más comunes, como Jira, te ayudan a diferenciar las buenas y malas prácticas que se ven día a día en los proyectos y empresas.
Además, tener la figura de un Mentor a la que consultar hace que no te bloquees, que continúes motivado hasta la finalización del proyecto y aporta ese valor extra que comparten los profesionales con experiencia.
Personalmente e independientemente de la práctica en sí misma me quedo con el esfuerzo y el conocimiento que me han transmitido los compañeros que me han acompañado. ¡Gracias!
Compartir:

Artículos relacionados