Introdução aos Testes em Kotlin: Dos Módulos à Experiência do Usuário
Kotlin é uma linguagem moderna usada ativamente para desenvolvimento server-side (Ktor, Spring Boot), aplicativos Android e projetos multiplataforma. No entanto, a qualidade do código é impossível sem testes adequados. Neste artigo, abordaremos três níveis principais: testes unitários, de integração e e2e (ponta a ponta). Você aprenderá quais ferramentas usar, como escrever testes em Kotlin e como construir uma estratégia de testes confiável para sua aplicação.
1. Testes Unitários em Kotlin: A Base da Estabilidade
Testes unitários verificam funções, classes ou métodos individuais isoladamente de dependências externas. Em Kotlin, JUnit 5 e MockK são os mais comumente usados para isso.
Ferramentas e Configuração
Adicione as dependências ao build.gradle.kts:
dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") testImplementation("io.mockk:mockk:1.13.8")}Exemplo de Teste Unitário com MockK
Suponha que temos um serviço que depende de um repositório:
class UserService(private val repo: UserRepository) { fun getUserName(id: Int): String { val user = repo.findById(id) return user?.name ?: "Unknown" }}Teste usando MockK:
import io.mockk.everyimport io.mockk.mockkimport org.junit.jupiter.api.Assertions.assertEqualsimport org.junit.jupiter.api.Test
class UserServiceTest { @Test fun `getUserName retorna nome quando usuario existe`() { val mockRepo = mockk<UserRepository>() every { mockRepo.findById(1) } returns User(1, "Alice") val service = UserService(mockRepo) assertEquals("Alice", service.getUserName(1)) }}Melhores Práticas para Testes Unitários
- Um teste — uma asserção (use
assertcom sabedoria). - Isole dependências: use mocks (MockK) ou stubs.
- Nomeie testes claramente:
deveRetornarX_quandoY. - Teste casos de borda: null, listas vazias, exceções.
2. Testes de Integração: Verificando a Interação entre Componentes
Testes de integração verificam como componentes reais funcionam juntos: banco de dados, API, sistema de arquivos. Em Kotlin, Testcontainers e Ktor Client (se você estiver escrevendo um servidor) são convenientes para isso.
Exemplo: Testando um Repositório com PostgreSQL
Adicione Testcontainers e exposed (uma biblioteca para trabalhar com bancos de dados):
dependencies { testImplementation("org.testcontainers:postgresql:1.19.3") implementation("org.jetbrains.exposed:exposed:0.44.1")}Teste para UserRepository:
import org.junit.jupiter.api.*import org.testcontainers.containers.PostgreSQLContainerimport org.testcontainers.junit.jupiter.Containerimport org.testcontainers.junit.jupiter.Testcontainersimport org.jetbrains.exposed.sql.*
@Testcontainersclass UserRepositoryIntegrationTest {
@Container val postgres = PostgreSQLContainer<Nothing>("postgres:15").apply { withDatabaseName("testdb") withUsername("test") withPassword("test") }
private lateinit var repo: UserRepository
@BeforeEach fun setUp() { Database.connect(postgres.jdbcUrl, driver = "org.postgresql.Driver", user = postgres.username, password = postgres.password) transaction { SchemaUtils.create(Users) } repo = UserRepository() }
@Test fun `salvar e encontrar usuario por id`() { val user = User(1, "Bob") repo.save(user) val found = repo.findById(1) assertEquals("Bob", found?.name) }
@AfterEa