Mutation testing en kotlin

0
503

Kotlin se está convirtiendo en un lenguaje cada vez más popular.
A medida que va ganando popularidad y su ecosistema crece, es interesante ver el grado de integración de herramientas conocidas. En este articulo vamos a probar en que estado está el mutation testing con PIT para tener una herramienta más de testing en nuestra caja de herramientas en este lenguaje.

Índice de contenidos

1. Introducción

Mi incansable lucha por entrar en la academia del profesor Charles Xavier y el aumento de mi uso de kotlin me han llevado a investigar que tal se llevan los tests de mutación con este lenguaje.

En un artículo previo hablamos de extreme mutation testing y en otro de otros compañeros de Mutation Testing con PIT por lo que aquí iremos más a la parte técnica de como usarlo con Kotlin para dar esa primera toma de contacto y animar a usarlo en los proyectos, por lo que si se echa de menos detalle, se recomienda la lectura de los artículos anteriores.

En este artículo también usaremos el ejemplo anterior de la calculadora que es bastante ilustrativo.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Lenovo t480 (1.80 GHz intel i7-8550U, 32GB DDR4)
  • Sistema Operativo: Linux Mint 20.2 Uma base: Ubuntu 20.04 focal Kernel: 5.13.0-27-generic x86_64 bits
  • Entorno de desarrollo: IntelliJ IDEA 2021.3.2 (Ultimate Edition).
  • Apache Maven 3.8.4
  • OpenJDK 64-Bit Server VM Temurin-17.0.1+12 (build 17.0.1+12, mixed mode, sharing)

3. Mutation testing

Mutation testing nace de la inquietud de saber si nuestros tests son correctos o no. Normalmente se usa la métrica de cobertura de código, esto es, si el test ha pasado por una determinada línea o no, pero eso no nos garantiza que los casos de prueba sean los más adecuados.

Mutation testing cambia el código del programa (mutaciones) para generar mutantes de tal forma que si los tests pasan se dice que el mutante sobrevive y si los tests no pasan, se dice que el mutante muere. El objetivo es que los mutantes mueran, ya que si cambiamos el comportamiento del código, pero las pruebas siguen pasando, es que no son del todo buenas. Se basa en dos hipótesis:

  • Hipótesis del programador competente: La mayoría de los errores introducidos son errores de sintaxis. Es interesante mencionar que esta hipótesis sigue siendo un área de investigación[1] y que de momento parece ser que se cumple, pero que faltarían operadores de mutación para que mutation testing diera todavía mejores resultados.
  • Hipótesis del efecto de acoplamiento: Pequeños fallos acoplados pueden juntarse y hacer que salgan otros defectos mayores.

Mutation testing parece que nos ayuda a mejorar la calidad de nuestros tests:

Nuestros resultados muestran que los desarrolladores que trabajan en proyectos con mutation testing escriben más pruebas de media durante más tiempo, en comparación con los proyectos que solo consideran la cobertura de código.
Los mutantes ayudan a hacer tests más efectivos: los desarrolladores expuestos a los mutantes escriben tests más efectivos en respuesta a ellos

[2]

Por lo que parece que además de estar vigente, puede ayudarnos, por eso buscar su ayuda en diferentes lenguajes de programación parece una buena idea.

4. Incluyendo mutation testing en kotlin

Vamos a ir viendo las clases que hemos creado y como añadir PIT a nuestro proyecto kotlin.

4.1. Clase calculadora

Tenemos nuestra clase calculadora

Calculator.kt

A la que por supuesto le hemos puesto tests

CalculatorTest.kt

En este apartado es importante destacar que aunque no es necesario poner el paquete (package org.example) para que funcione el programa, si es necesario ponerlo para que funcione PIT, si no lo ponemos obtenemos:

Los tests están en junit5, con las siguientes dependencias se ejecutan correctamente

Antes de seguir vemos como todos los tests pasan

Todos los tests pasan

Y tenemos un 100% de cobertura

Tenemos el 100% de cobertura

4.2. Añadiendo PIT

Ahora, lo que tenemos que hacer es añadir a nuestro pom las dependencias necesarias

Ademas del plugin de PIT

Quedando el pom.xml asi:

pom.xml

Si ejecutamos:

Podemos ir a target/pit-reports/[FECHA] y vemos el index.html con la información.

Desde la consola también se nos da información:

Y este seria en informe de cobertura en formato html

Informe de cobertura en html

Si vamos al detalle, al contrario que ocurría en java, aquí no se nos muestra el código, pero aun asi nos da pistas de que puede estar mal, en este caso el tercer test ha reemplazado la multiplication por la division y no ha muerto el mutante.

Detalle del informe de cobertura en html

El test es malo, porque hemos elegido multiplicar 1 * 1, y no nos permite detectar errores (1 / 1 = 1, o simplemente return firstNumber darían como bueno ese test). Lo podemos corregir así:

Si volvemos a ejecutar:

Tenemos:

Informe de cobertura arreglado

Vemos que ya no hay fallos:

Tests arreglados

5. Conclusiones

Tal y como se puede leer en los artículos de las referencias, mutation testing es un campo de estudio y puede resultar muy útil. En el caso de usar kotlin es sencillo incluirlo en nuestro proyecto, pero es algo menos informativo que cuando lo usamos con java.

Al principio se uso un estilo mas conciso para la definición de la clase como se puede ver a continuación:

Se cambio al que esta en el apartado anterior por si este era el motivo de que no apareciera el código en el informe final, pero no era el caso. Aun así se dejó el que esta actualmente por legibilidad.

Existe un plugin para kotlin en github pero no se encuentra en maven central ni parece que tenga mucho movimiento, pero habrá que estar atentos a ver las herramientas que van saliendo.

6. Referencias

Dejar respuesta

Please enter your comment!
Please enter your name here