-
Grabar, reproducir y revisar: Automatización de IU en Xcode
Aprende a grabar, ejecutar y mantener pruebas de XCUIAutomation en Xcode. Reproduce tus pruebas de IU de XCTest en distintas ubicaciones, dispositivos y condiciones con configuraciones de plan de prueba. Revisa los resultados de tus pruebas con el reporte de Xcode y descarga capturas y videos de tus ejecuciones. Hablaremos sobre las prácticas que te permitirán preparar la app para la automatización con accesibilidad y escribir código estable y de calidad.
Capítulos
- 0:00 - Introducción y agenda
- 3:58 - Descripción de la automatización de IU
- 6:26 - Prepara tu app para la automatización
- 11:32 - Registra tus interacciones
- 17:30 - Reproducción en múltiples configuraciones
- 20:54 - Revisar videos y resultados
- 24:16 - Próximos pasos
Recursos
- Performing accessibility testing for your app
- Improving code assessment by organizing tests into test plans
- Delivering an exceptional accessibility experience
Videos relacionados
WWDC24
WWDC23
- Build accessible apps with SwiftUI and UIKit
- Create practical workflows in Xcode Cloud
- Fix failures faster with Xcode test reports
- Perform accessibility audits for your app
WWDC22
WWDC21
-
Buscar este video…
-
-
7:52 - Adding accessibility identifiers in SwiftUI
// Adding accessibility identifiers in SwiftUI import SwiftUI struct LandmarkDetailView: View { let landmark: Landmark var body: some View { VStack { Image(landmark.backgroundImageName) .accessibilityIdentifier("LandmarkImage-\(landmark.id)") Text(landmark.description) .accessibilityIdentifier("LandmarkDescription-\(landmark.id)") } } } -
8:19 - Adding accessibility identifiers in UIKit
// Adding accessibility identifiers in UIKit import UIKit struct LandmarksListViewController: UIViewController { let landmarks: [Landmark] = [landmarkGreatBarrier, landmarkCairo] override func viewDidLoad() { super.viewDidLoad() for landmark in landmarks { let button = UIButton(type: .custom) setupButtonView() button.accessibilityIdentifier = "LandmarkButton-\(landmark.id)" view.addSubview(button) } } } -
13:54 - Best practice: Prefer accessibility identifiers over localized strings
// Example SwiftUI view struct CollectionDetailDisplayView: View { var body: some View { ScrollView { Text(collection.name) .font(.caption) .accessibilityIdentifier("Collection-\(collection.id)") } } } // Example of a worse XCUIElementQuery XCUIApplication().staticTexts["Max's Australian Adventure"] // Example of a better XCUIElementQuery XCUIApplication().staticTexts["Collection-1"] -
14:09 - Best practice: Keep queries as concise as possible
// Example SwiftUI view struct CollectionDetailDisplayView: View { var body: some View { ScrollView { Text(collection.name) .font(.caption) .accessibilityIdentifier("Collection-\(collection.id)") } } } // Example of a worse XCUIElementQuery XCUIApplication().scrollViews.staticTexts["Collection-1"] // Example of a better XCUIElementQuery XCUIApplication().staticTexts["Collection-1"] -
14:21 - Best practice: Prefer generic queries for dynamic content
// Example SwiftUI view struct CollectionDetailDisplayView: View { var body: some View { ScrollView { Text(collection.name) .font(.caption) .accessibilityIdentifier("Collection-\(collection.id)") } } } // Example of a worse XCUIElementQuery XCUIApplication().staticTexts["Max's Australian Adventure"] // Example of a better XCUIElementQuery XCUIApplication().staticTexts.firstMatch -
15:49 - Add validations to a test case
// Add validations to the test case import XCTest class LandmarksUITests: XCTestCase { func testGreatBarrierAddedToFavorites() { let app = XCUIApplication() app.launch() app.cells["Landmark-186"].tap() XCTAssertTrue( app.staticTexts["Landmark-186"].waitForExistence(timeout: 10.0)), "Great Barrier exists" ) let favoriteButton = app.buttons["Favorite"] favoriteButton.tap() XCTAssertTrue( favoriteButton.wait(for: \.value, toEqual: true, timeout: 10.0), "Great Barrier is a favorite" ) } } -
16:36 - Set up your device for test execution
// Set up your device for test execution import XCTest import CoreLocation class LandmarksUITests: XCTestCase { override func setUp() { continueAfterFailure = false XCUIDevice.shared.orientation = .portrait XCUIDevice.shared.appearance = .light let simulatedLocation = CLLocation(latitude: 28.3114, longitude: -81.5535) XCUIDevice.shared.location = XCUILocation(location: simulatedLocation) } } -
16:54 - Launch your app with environment variables and arguments
// Launch your app with environment variables and arguments import XCTest class LandmarksUITests: XCTestCase { func testLaunchWithDefaultCollection() { let app = XCUIApplication() app.launchArguments = ["ClearFavoritesOnLaunch"] app.launchEnvironment = ["DefaultCollectionName": "Australia 🐨 🐠"] app.launch() app.tabBars.buttons["Collections"].tap() XCTAssertTrue(app.buttons["Australia 🐨 🐠"].waitForExistence(timeout: 10.0)) } } -
17:04 - Launch your app using custom URL schemes
// Launch your app using custom URL schemes import XCTest class LandmarksUITests: XCTestCase { func testOpenGreatBarrier() { let app = XCUIApplication() let customURL = URL(string: "landmarks://great-barrier")! app.open(customURL) XCTAssertTrue(app.wait(for: .runningForeground, timeout: 10.0)) XCTAssertTrue(app.staticTexts["Great Barrier Reef"].waitForExistence(timeout: 10.0)) } } -
17:12 - Launch your app using custom URL schemes and the system default app
// Launch your app using custom URL schemes import XCTest class LandmarksUITests: XCTestCase { func testOpenGreatBarrier() { let app = XCUIApplication() let customURL = URL(string: "landmarks://great-barrier")! XCUIDevice.shared.system.open(customURL) XCTAssertTrue(app.wait(for: .runningForeground, timeout: 10.0)) XCTAssertTrue(app.staticTexts["Great Barrier Reef"].waitForExistence(timeout: 10.0)) } } -
17:13 - Perform an accessibility audit during an automation
// Perform an accessibility audit during an automation import XCTest class LandmarksUITests: XCTestCase { func testPerformAccessibilityAudit() { let app = XCUIApplication() try app.performAccessibilityAudit() } }
-
-
- 0:00 - Introducción y agenda
La automatización de la interfaz de usuario de Xcode, impulsada por la estructura XCUIAutomation, te permite probar tus apps de manera integral. Funciona junto con Swift Testing y la estructura XCTest, proporcionando un conjunto completo de pruebas de apps. Las pruebas de automatización de interfaz de usuario validan la experiencia del usuario de una app, su integración con el hardware de Apple y el comportamiento de los flujos de trabajo comunes al complementar las pruebas unitarias que se centran en la lógica de la app y los modelos de datos. El proceso consta de tres fases principales: Registrar interacciones que luego se convierten automáticamente en código. Reproducir estas interacciones en distintos dispositivos, idiomas, regiones y orientaciones. Revisión de grabaciones de video y resultados de cada ejecución de prueba de la interfaz de usuario. Estas automatizaciones te permiten probar tus apps como lo harían los usuarios reales, lo que garantiza la accesibilidad, la compatibilidad de idiomas y la integración de hardware. Es compatible con todas las plataformas de Apple, lo que le permite crear y ejecutar pruebas de automatización una vez para varios dispositivos, como el iPhone, el iPad, la Mac, la Apple TV y el Apple Watch, con un solo clic.
- 3:58 - Descripción de la automatización de IU
La automatización de la interfaz de usuario imita las interacciones del usuario con una app: iniciándola, tocando botones y navegando por las pantallas. Se basa en las funciones de accesibilidad de la app, lo que proporcionan etiquetas, valores e identificadores únicos para que los elementos realicen estas acciones de forma independiente. La accesibilidad, un valor fundamental de Apple, garantiza que las apps puedan ser utilizadas por todos y también potencia la automatización de la interfaz de usuario.
- 6:26 - Prepara tu app para la automatización
Para preparar la automatización de la app se requieren varios pasos. Primero, agrega identificadores de accesibilidad a los elementos de la app. Estos identificadores son etiquetas únicas escritas en SwiftUI, UIKit o AppKit que ayudan a las herramientas de automatización a reconocer e interactuar con partes específicas de la app. Son particularmente útiles para elementos con cadenas localizadas o contenido dinámico y deben ser descriptivos, estáticos y únicos dentro de toda la app. Luego, realiza una revisión rápida de la accesibilidad de la app con Accessibility Inspector. Esta herramienta ayuda a identificar y solucionar cualquier problema de accesibilidad, garantizando que la app esté bien preparada para la automatización. Accessibility Inspector te permite ver y modificar las propiedades de accesibilidad para cada vista, lo que hace que la app sea más utilizable tanto para tecnologías de asistencia como para scripts de automatización. Por último, agrega un nuevo objetivo de prueba de interfaz de usuario al proyecto Xcode. Este objetivo proporciona un espacio dedicado para almacenar el código de automatización. Una vez configurado el objetivo, puedes comenzar a grabar tus interacciones con la app, las cuales se traducirán automáticamente en código Swift, agilizando el proceso de automatización.
- 11:32 - Registra tus interacciones
El proyecto de muestra Landmarks, que se muestra en Xcode y Simulator, demuestra cómo planificar unas vacaciones virtuales a Australia. Las grabaciones de interfaz de usuario capturan interacciones dentro de la app como código. El ejemplo agrega una nueva colección, la renombra "La aventura australiana de Max" y la llena con lugares emblemáticos como la Gran barrera de coral y Uluru. Una vez que se detiene la grabación, el ejemplo revisa el código generado, selecciona consultas de la interfaz de usuario adecuadas y agrega validaciones utilizando XCTest para garantizar la funcionalidad de la app. Luego se vuelve a ejecutar la prueba y se verifica con éxito la creación de la colección y la adición de los puntos de referencia. Puedes mejorar aún más las pruebas al configurar estados de dispositivos específicos, simular ubicaciones y realizar auditorías de accesibilidad.
- 17:30 - Reproducción en múltiples configuraciones
Xcode Cloud permite realizar pruebas de apps automatizadas en diversas configuraciones en el escritorio y en la nube, así como para diferentes idiomas y dispositivos. Los planes de prueba organizan pruebas, establecen configuraciones del sistema y administran propiedades. Las configuraciones permiten realizar pruebas en lugares específicos, incluidos idiomas con cadenas más largas o escrituras de derecha a izquierda. Xcode Cloud ejecuta pruebas en la nube y guarda videos y capturas de pantalla de fallas para su revisión. Un equipo completo puede ver el historial de ejecución, los registros y los resultados, lo que facilita la colaboración y la supervisión remota. Las configuraciones avanzadas y más detalles están disponibles en la Documentación para desarrolladores.
- 20:54 - Revisar videos y resultados
El informe de pruebas de Xcode proporciona una herramienta integral para analizar los resultados de las pruebas. Al identificar una prueba fallida, podrás acceder a grabaciones de video y descripciones detalladas. El informe superpone las interacciones de la interfaz de usuario en el video e incluye una línea de tiempo con diamantes de fallas para una navegación rápida. Puedes ver los elementos de la interfaz de usuario actuales en el punto de falla, recibir sugerencias de código y editar directamente tu código de prueba. Después de realizar las correcciones, se puede volver a ejecutar la prueba y el informe permite verificar la funcionalidad en diferentes idiomas y diseños, lo que en última instancia mejora la calidad y la accesibilidad de la app.
- 24:16 - Próximos pasos
Para obtener más información sobre pruebas unitarias y pruebas Swift, consulta la sesión "Meet Swift Testing" de WWDC24; si tienes preguntas o comentarios, visita los foros para desarrolladores.