TDD em Swift: como escrever código que não quebra

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

«Primeiro o teste — depois o código»: por que isso funciona em Swift?

\n\n

Você já reescreveu o mesmo módulo pela terceira vez porque «precisava lançar com urgência»? Ou já pegou um bug em produção que era mais fácil prevenir na fase de escrita? Se sim — bem-vindo ao mundo do TDD (Test-Driven Development).

\n\n

Desenvolvimento orientado a testes não é apenas uma metodologia da moda. É uma forma de pensar que faz você formular como o código deve se comportar antes de escrevê-lo. Em Swift, com sua tipagem forte e o poderoso framework XCTest, o TDD se transforma em um escudo confiável contra regressões e falhas inesperadas.

\n\n

Neste artigo, vamos explorar o TDD com exemplos reais, escrever testes para a camada de rede e modelo de dados e, principalmente, entender como implementar essa prática sem dor. Vamos lá!

\n\n

Vermelho-Verde-Refatoração: a magia do ciclo

\n\n

A base do TDD é um ciclo de três etapas:

\n\n
    \n
  • Vermelho (Red) — escrevemos um teste que não passa (porque o código ainda não existe).
  • \n
  • Verde (Green) — escrevemos o código mínimo para o teste passar.
  • \n
  • Refatoração (Refactor) — melhoramos o código sem alterar seu comportamento (os testes protegem).
  • \n
\n\n

Parece simples? Vamos tentar em Swift.

\n\n

Primeiro teste: verificando o modelo User

\n\n

Suponha que temos um modelo simples de usuário. Queremos que ele formate corretamente o nome completo. Primeiro — o teste:

\n\n
import XCTest\n@testable import MyApp\n\nfinal class UserTests: XCTestCase {\n    \n    func testFullName_GivenFirstNameAndLastName_ReturnsFormattedString() {\n        // Arrange\n        let user = User(firstName: "Ana", lastName: "Karenina")\n        \n        // Act\n        let fullName = user.fullName()\n        \n        // Assert\n        XCTAssertEqual(fullName, "Ana Karenina", "O nome completo deve consistir no nome e sobrenome separados por espaço")\n    }\n}\n
\n\n

Executamos — o teste falha (vermelho). O compilador reclama que User não existe. Ótimo, é exatamente o que queremos.

\n\n

Agora escrevemos o código mínimo para o teste passar:

\n\n
struct User {\n    let firstName: String\n    let lastName: String\n    \n    func fullName() -> String {\n        return "\\(firstName) \\(lastName)"\n    }\n}\n
\n\n

Executamos — verde! Podemos passar para a refatoração. Por exemplo, adicionar tratamento para strings vazias ou nome do meio. Mas não se apresse — os testes indicarão quando isso for necessário.

\n\n

Testando a camada de rede assíncrona

\n\n

Um dos problemas mais comuns no desenvolvimento iOS é o trabalho com rede. O TDD é especialmente útil aqui, pois você separa claramente a lógica das chamadas de rede.

\n\n

Escrevendo o protocolo e o objeto mock

\n\n

Primeiro, definimos como nosso serviço deve ser:

\n\n
protocol WeatherServiceProtocol {\n    func fetchWeather(for city: String, completion: @escaping (Result<Weather, Error>) -> Void)\n}\n
\n\n

Agora — o teste. Não queremos depender de uma API real, então criamos um mock:

\n\n
class MockWeatherService: WeatherServiceProtocol {\n    var shouldReturnError = false\n    var mockWeather: Weather?\n    \n    func fetchWeather(for city: String, completion: @escaping (Result<Weather, Error>) -> Void) {\n        if shouldReturnError {\n            completion(.failure(NetworkError.serverError))\n        } else if let weather = mockWeather {\n            completion(.success(weather))\n        }\n    }\n}\n\nfinal class WeatherViewModelTests: XCTestCase {\n    \n    func testFetchWeather_Success_UpdatesModel() {\n        // Arrange\n        let mockService = MockWeatherService()\n        mockService.mockWeather = Weather(temperature: 25.0, condition: "sunny")\n        let viewModel = WeatherViewModel(service: mockService)\n        let expectation = XCTestExpectation(description: "Aguardando carregamento do clima")\n        \n                

Blogs

Book Recommendations