Pruebas en Kotlin: unit, integration, e2e — guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a las pruebas en Kotlin: desde pruebas unitarias hasta end-to-end

Las pruebas son una parte esencial del desarrollo de software confiable. En el ecosistema de Kotlin, que se utiliza activamente para el desarrollo de Android, backend con Ktor y proyectos multiplataforma, existe un potente conjunto de herramientas para todos los niveles de prueba. En este artículo, analizaremos tres niveles clave: pruebas unitarias, pruebas de integración y pruebas end-to-end (e2e). Aprenderás en qué se diferencian, cuándo aplicarlas y cómo escribir pruebas efectivas en Kotlin con ejemplos de código.



Pruebas unitarias en Kotlin: la base de la confiabilidad

Las pruebas unitarias verifican el funcionamiento de componentes individuales (funciones, clases) de forma aislada. En Kotlin, el estándar de facto es el framework JUnit 5 junto con la biblioteca de mocks MockK.



Ejemplo de prueba unitaria con JUnit 5 y MockK

Consideremos un servicio simple para calcular descuentos:

class DiscountService(private val userRepository: UserRepository) {    fun calculateDiscount(userId: String, amount: Double): Double {        val user = userRepository.findById(userId) ?: return amount        return if (user.isPremium) amount * 0.9 else amount    }}

Prueba para este servicio:

import io.mockk.everyimport io.mockk.mockkimport org.junit.jupiter.api.Testimport kotlin.test.assertEquals

class DiscountServiceTest {

@Test fun `should apply 10% discount for premium user`() { // Arrange val userRepo = mockk<UserRepository>() every { userRepo.findById("123") } returns User("123", isPremium = true) val service = DiscountService(userRepo)

// Act val result = service.calculateDiscount("123", 100.0)

// Assert assertEquals(90.0, result) }

@Test fun `should not apply discount for regular user`() { val userRepo = mockk<UserRepository>() every { userRepo.findById("456") } returns User("456", isPremium = false) val service = DiscountService(userRepo)

val result = service.calculateDiscount("456", 100.0)

assertEquals(100.0, result) }}

Puntos clave:

  • Usa mockk{} para crear mocks.
  • El bloque every { ... } returns ... define el comportamiento del mock.
  • La estructura Arrange-Act-Assert hace que las pruebas sean legibles.
  • Las pruebas unitarias deben ejecutarse rápidamente y no depender de recursos externos.


Pruebas de integración: verificación de la interacción de componentes

Las pruebas de integración verifican cómo varios módulos funcionan juntos, por ejemplo, un servicio con una base de datos real o una API externa. Para Kotlin, son populares Testcontainers (para contenedores Docker) y Spring Boot Test (para backend).



Ejemplo de prueba de integración con Testcontainers y Ktor

Supongamos que tenemos una aplicación Ktor con PostgreSQL:

class UserRepository(private val database: Database) {    suspend fun findById(id: String): User? {        return database.query("SELECT * FROM users WHERE id = ?", id).singleOrNull { row ->            User(row.string("id"), row.boolean("is_premium"))        }    }}

Prueba de integración con Testcontainers:

import io.kotest.core.spec.style.StringSpecimport io.kotest.matchers.shouldBeimport org.testcontainers.containers.PostgreSQLContainerimport org.testcontainers.junit.jupiter.Containerimport org.testcontainers.junit.jupiter.Testcontainers

@Testcontainersclass UserRepositoryIntegrationTest : StringSpec({

@Container val postgres = PostgreSQLContainer<Nothing>("postgres:15").apply { withDatabaseName("testdb") withUsername("test") withPassword("test") }

"should

Blogs

Book Recommendations