Pruebas en Swift: unit, integration, e2e de la A a la Z

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: por qué las pruebas son la base de una aplicación Swift confiable

\n\n

El desarrollo para iOS y macOS requiere una alta confiabilidad del código. Un error en la lógica de funcionamiento de la aplicación puede costar la experiencia del usuario y, en proyectos comerciales, dinero. Las pruebas en Swift no son solo una "buena práctica", sino una etapa obligatoria del desarrollo. Permiten detectar errores en etapas tempranas, simplificar la refactorización y mejorar la calidad del código.

\n\n

En este artículo analizaremos tres niveles de pruebas: unit (pruebas unitarias), integration (pruebas de integración) y e2e (pruebas de extremo a extremo). Aprenderá en qué se diferencian, cuándo aplicar cada una y verá ejemplos prácticos en Swift utilizando el framework XCTest.

\n\n

1. Pruebas unitarias en Swift: la base fundamental

\n\n

Las pruebas unitarias verifican módulos individuales (funciones, métodos, clases) de forma aislada. Su objetivo principal es asegurarse de que cada "unidad" de código funcione correctamente.

\n\n

Configuración de XCTest

\n\n

XCTest está integrado en Xcode. Para crear un target de prueba:

\n
    \n
  • Abra su proyecto en Xcode.
  • \n
  • Seleccione File → New → Target.
  • \n
  • Seleccione Unit Testing Bundle.
  • \n
\n\n

Después de la creación, obtendrá un archivo como YourAppTests.swift.

\n\n

Ejemplo de prueba unitaria

\n\n

Supongamos que tenemos una función para calcular un descuento:

\n\n
func calculateDiscount(price: Double, discount: Double) -> Double {\n    guard discount >= 0 && discount <= 100 else { return price }\n    return price * (1 - discount / 100)\n}\n
\n\n

Escribimos la prueba:

\n\n
import XCTest\n@testable import YourApp\n\nclass DiscountTests: XCTestCase {\n    func testCalculateDiscount_ValidInput() {\n        let result = calculateDiscount(price: 1000, discount: 20)\n        XCTAssertEqual(result, 800, accuracy: 0.01)\n    }\n    \n    func testCalculateDiscount_InvalidDiscount() {\n        let result = calculateDiscount(price: 500, discount: 150)\n        XCTAssertEqual(result, 500)\n    }\n}\n
\n\n

Best practices para pruebas unitarias:

\n
    \n
  • Una prueba, una verificación.
  • \n
  • Use setUp() para inicializar objetos comunes.
  • \n
  • Evite dependencias de red, base de datos o UI — use mocks.
  • \n
\n\n

2. Pruebas de integración: verificación de la interacción entre componentes

\n\n

Las pruebas de integración verifican cómo diferentes módulos trabajan juntos. Por ejemplo, la interacción del modelo de datos con la capa de red o la base de datos CoreData.

\n\n

Ejemplo: prueba de una solicitud de red

\n\n

Creemos un servicio simple:

\n\n
class NetworkService {\n    func fetchUser(completion: @escaping (Result<User, Error>) -> Void) {\n        // Solicitud real a la API\n    }\n}\n
\n\n

Una prueba de integración puede verificar que el servicio procesa correctamente la respuesta de un servidor real (o de un servidor mock local):

\n\n
class NetworkServiceIntegrationTests: XCTestCase {\n    var service: NetworkService!\n    \n    override func setUp() {\n        super.setUp()\n        service = NetworkService()\n    }\n    \n    func testFetchUser_ReturnsUser() {\n        let expectation = self.expectation(description: "Fetch user")\n        \n        service.fetchUser { result in\n            switch result {\n            case .success(let user):\n                XCTAssertNotNil(user.name)\n            case .failure:\n                XCTFail("Request failed")\n            }\n            expectation.fulfill()\n        }\n        \n        waitForExpectations(timeout: 5)\n    }\n}\n
\n\n

Importante: Las pruebas de integración son más lentas que las pruebas unitarias, por lo que se ejecutan con menos frecuencia (por ejemplo, antes de fusionar en main).

\n\n

3. Pruebas E2E (de extremo a extremo) con XCUITest

\n\n

Las pruebas E2E (End-to-End) simulan las acciones del usuario: presionar botones, ingresar texto, verificar la visualización de la UI. En Swift para esto

Blogs

Book Recommendations