Ir al contenido principal

De Coverlet a JaCoCo: Trayendo la magia de la cobertura a Android Studio

Todo comenzó un día cualquiera, mientras revisaba un reporte de cobertura de pruebas generado por Coverlet para un proyecto en .NET. Me quedé fascinado por el nivel de detalle y claridad que proporcionaba: saber exactamente qué partes del código estaban cubiertas por las pruebas, y cuáles no. Fue entonces cuando me pregunté: ¿Y si pudiera tener algo así en mi proyecto de Android con Kotlin y Jetpack Compose?


La Chispa Inicial ✨


Como desarrollador, siempre busco mejorar la calidad de mi código, y contar con herramientas que me permitan medir la cobertura de pruebas es clave. Después de una rápida búsqueda, me topé con **JaCoCo**, una herramienta muy popular para medir cobertura de código en proyectos Java y Kotlin. ¡Lo mejor de todo es que es compatible con Android Studio!


Mi objetivo estaba claro: debía integrar JaCoCo en mi proyecto de Android para tener reportes detallados de cobertura, tal como lo había visto en Coverlet.


El Desafío: Configurar JaCoCo en un Proyecto Android 🛠️


El proyecto con el que estaba trabajando no era cualquier proyecto. Era una aplicación moderna construida con **Jetpack Compose** y configurada con **Gradle Kotlin DSL** (`build.gradle.kts`). Sabía que el camino no sería tan sencillo como copiar y pegar configuraciones estándar, pero estaba listo para el reto.


Paso 1: Activar el Plugin de JaCoCo 🔌


Lo primero que hice fue agregar el plugin de JaCoCo en el archivo `build.gradle.kts` de mi módulo `app`. Esta línea mágica activó el soporte para JaCoCo:


plugins {

    id("jacoco")

}


Con esto, JaCoCo ya estaba listo para entrar en acción, pero aún necesitaba configurarlo para que generara los reportes que quería.


Paso 2: Configurando los Reportes de Cobertura ⚙️


El siguiente paso fue añadir una tarea personalizada en el archivo build.gradle.kts. Esta tarea se encargaría de generar los reportes en formato HTML y XML después de ejecutar las pruebas unitarias:

tasks.register("jacocoTestReport", JacocoReport::class) {

    dependsOn("testDebugUnitTest") // Ejecuta las pruebas antes del reporte


    reports {

        xml.required.set(true)

        html.required.set(true)

    }


  val debugTree = fileTree("${buildDir}/intermediates/javac/debug") {

        include("**/*.class")

        exclude(

            "**/R.class",

            "**/R$*.class",

            "**/BuildConfig.*",

            "**/Manifest*.*",

            "**/*Test*.*"

        )

    }


    val kotlinDebugTree = fileTree("${buildDir}/tmp/kotlin-classes/debug") {

        exclude(

            "**/R.class",

            "**/R$*.class",

            "**/BuildConfig.*",

            "**/Manifest*.*",

            "**/*Test*.*"

        )

    }


    classDirectories.setFrom(files(debugTree, kotlinDebugTree))

    sourceDirectories.setFrom(files("src/main/java"))

    executionData.setFrom(files("${buildDir}/jacoco/testDebugUnitTest.exec"))

}


💡 Un consejo extra: Asegúrate de que las rutas en classDirectories, sourceDirectories y executionData coincidan con la estructura de tu proyecto.


Paso 3: Ejecutar las Pruebas y Generar el Reporte 🚀


Con todo configurado, llegó el momento de la verdad. Corrí el comando para ejecutar las pruebas unitarias:

./gradlew testDebugUnitTest


Luego, generé el reporte de cobertura con:

./gradlew jacocoTestReport


Cuando abrí el archivo index.html en la carpeta app/build/reports/jacoco/jacocoTestReport/html, me sentí como un explorador descubriendo un nuevo mundo. Ahí estaba: un desglose detallado de la cobertura de cada clase, método y línea de mi proyecto. ¡Una verdadera radiografía de mi código! 🤩


El Resultado: Visualizando el Impacto 📊


JaCoCo no solo me dio una visión clara de cuánto de mi código estaba cubierto por pruebas, sino que también me motivó a mejorar. Podía ver exactamente qué partes necesitaban más atención y dónde estaba fallando mi estrategia de pruebas. Esta información visual es invaluable para tomar decisiones informadas sobre dónde enfocar mis esfuerzos de testing.


Conclusión: De Coverlet a JaCoCo, un Camino Valioso 🏆


Si alguna vez has disfrutado de los reportes de cobertura de Coverlet en proyectos .NET, te encantará saber que puedes lograr algo similar en proyectos de Android con Kotlin. JaCoCo es una herramienta poderosa que, con un poco de configuración, puede integrarse perfectamente en tu flujo de trabajo, brindándote la visibilidad que necesitas para escribir código más robusto y confiable. ¡Anímate a probarlo y descubre el impacto en la calidad de tu aplicación.



Comentarios

Entradas populares de este blog

Principios SOLID del Tio Bob

  Principios SOLID del Tio Bob Los principios sólidos son un conjunto de pautas de diseño de software que se centran en lograr código limpio, modular y mantenible. Estos principios fueron propuestos por Robert C. Martin (Uncle Bob) y se consideran fundamentales en el desarrollo de software orientado a objetos. Los cinco principios sólidos son los siguientes:   1. Principio de Responsabilidad Única (Single Responsibility Principle, SRP): Una clase debería tener una única responsabilidad. Esto significa que una clase debe tener una única razón para cambiar. Al tener una responsabilidad única, se logra un código más cohesivo y fácil de mantener.   2. Principio de Abierto/Cerrado (Open/Closed Principle, OCP): Las entidades de software (clases, módulos, etc.) deben estar abiertas para su extensión pero cerradas para su modificación. Esto significa que el comportamiento de una entidad puede ser extendido sin necesidad de modificar su código fuente original.  ...

Desarrollador junior C#

Habilidades que se esperan de un desarrollador junior (C#)   1.      Conocimientos básicos de programación: Debes tener una comprensión sólida de los conceptos fundamentales de programación, como variables, estructuras de control, bucles, funciones, etc. 2.      Dominio del lenguaje C#: Debes tener conocimientos sólidos del lenguaje C# y su sintaxis. Debes estar familiarizado con los conceptos orientados a objetos, como clases, herencia, polimorfismo, etc. 3.      Conocimientos de .NET Framework: C# se utiliza principalmente para el desarrollo en el entorno de .NET Framework, por lo que debes tener un conocimiento básico de esta plataforma, incluyendo las bibliotecas y clases comunes que se utilizan en el desarrollo de aplicaciones. 4.      Experiencia con Visual Studio: Visual Studio es el entorno de desarrollo integrado (IDE) más popular para C#. Debes estar familiarizado con su uso y ser capa...

Programación asíncrona comparación Kotlin y C#

La programación asíncrona es un enfoque en la programación que permite que las tareas se ejecuten de manera independiente y no bloqueante. En lugar de esperar a que una tarea se complete antes de pasar a la siguiente, las tareas se pueden ejecutar en paralelo o de manera secuencial, lo que mejora la eficiencia y la capacidad de respuesta de las aplicaciones. ¿Como implementar programación asíncrona en Kotlin? Usando Coroutines. Las coroutines en Kotlin son una forma de escribir código asíncrono de manera más concisa y legible. En lugar de bloquear el hilo principal mientras esperamos a que se complete una tarea, las coroutines permiten que el hilo siga ejecutándose mientras esperamos que una tarea asincrónica termine. Esto mejora la eficiencia y la capacidad de respuesta de las aplicaciones. Un ejemplo básico: KOTLIN import kotlinx.coroutines.* fun main() {     println("Inicio")     // Lanzar una coroutine     GlobalScope.launch {       ...