
-
Grave, reproduza e revise: automação de interface com o Xcode
Aprenda a gravar, executar e manter testes do XCUIAutomation no Xcode. Reproduza seus testes de interface de usuário do XCTest em dezenas de idiomas, tipos de dispositivos e condições de sistema usando as configurações do plano de teste. Revise os resultados dos testes usando o relatório de testes do Xcode e baixe capturas de tela e vídeos das execuções. Também abordaremos as melhores práticas para preparar seu app para automação com acessibilidade e para escrever código de automação estável e de alta qualidade.
Capítulos
- 0:00 - Introdução
- 3:58 - Visão geral da automação da interface de usuário
- 6:26 - Preparar seu app para automação
- 11:32 - Gravar suas interações
- 17:30 - Reproduzir em várias configurações
- 20:54 - Revisar vídeos e resultados
- 24:16 - Próximas etapas
Recursos
- Delivering an exceptional accessibility experience
- Improving code assessment by organizing tests into test plans
- Performing accessibility testing for your app
Vídeos 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 neste vídeo...
Olá! Meu nome é Max. Sou engineer na equipe Xcode. Há tantos recursos e experiências incríveis no Xcode que pode ser difícil saber por onde começar. Por exemplo, você sabia que é possível ver seu app ser executado em dezenas de dispositivos, idiomas e configurações com um clique? Além disso, você pode gravar cada execução em vídeo, em alta qualidade. Isso é totalmente possível com a automação de interface no Xcode. Vamos descobrir como isso funciona. Vamos começar com uma visão geral da automação de interface. Em seguida, vamos preparar seu app, gravar suas interações como código de automação, reproduzir a automação em vários dispositivos e idiomas, assistir aos vídeos dos resultados e ver um relatório indicando se cada execução foi bem-sucedida ou não.
Vamos começar pela visão geral de como a automação de interface funciona.
No Xcode, temos dois frameworks de teste: Swift Testing e XCTest. Ambos testam rapidamente seu app e código-fonte em muitas configurações.
Ao importar o XCTest, um framework chamado XCUIAutomation é incluído automaticamente. O XCUIAutomation pode ser usado para automatizar seu app e interagir com ele como uma pessoa. Esses frameworks trabalham juntos para fornecer um pacote de testes completo. Eu acho isso muito legal. Um pacote completo de testes de app geralmente inclui testes de automação de interface e de unidade. Os testes de unidade testam a lógica e os modelos do app. Com o Swift Testing, é possível executar testes em frameworks e pacotes do Swift que não têm interface. Os testes de automação de interface validam a experiência do usuário do app, a integração dele com o hardware da Apple e o comportamento de fluxos de trabalho comuns.
Geralmente, seu pacote de teste tem mais testes de unidade do que de interface, e o ideal é buscar cobertura completa do seu código. Os testes de automação de interface permitem ver a aparência do seu app e como ele se comporta e se integra ao sistema operacional. Há muitos benefícios em fazer isso.
Por exemplo, você pode testar seu app como uma pessoa faria, com movimentos como toques, deslizamentos e cliques. Você pode entender a experiência que pessoas que usam tecnologias assistivas, como VoiceOver, Controle por Voz e Fonte Dinâmica, têm com seu app.
Você pode ver o app em execução em todos os idiomas e regiões compatíveis, além de focar nos idiomas com maior impacto visual, como aqueles com strings mais longas e layout da direita para a esquerda. Você pode testar a integração do app com recursos de hardware da Apple, como o botão de Ação, o botão da câmera, o Apple TV Remote e a Digital Crown do Apple Watch. Por fim, você pode testar o desempenho de abertura do app, que é fundamental para entender a rapidez com que as pessoas podem começar a usar seu app. Para configurar um fluxo de trabalho de automação de interface, há três fases principais: gravar, reproduzir e revisar. Grave suas interações, como toques, deslizamentos e pressionamentos de botões físicos e veja o Xcode transformar tudo em código. Em seguida, reproduza as interações em vários dispositivos, idiomas, regiões e orientações de dispositivo, tanto nos dispositivos quanto no Xcode Cloud. Por fim, revise os vídeos e os resultados de executar seu app em todas essas configurações e veja o que deu certo e o que não deu. A automação de interface é compatível com todas as plataformas Apple: iOS, iPadOS, macOS, watchOS, tvOS e visionOS (desenvolvido para iPad). A mesma automação pode ser executada em várias plataformas. Assim, você cria uma automação uma vez e a executa em todos os dispositivos compatíveis. Assim, você vê como seu app é executado no Mac, iPhone e Vision Pro com um clique e sem alterar o código. Vamos ver brevemente como a automação de interface funciona. A automação de interface interage com seu app como uma pessoa faz, usando movimentos e eventos de hardware. A automação é executada de forma independente do seu app. Seus modelos e dados não ficam diretamente acessíveis.
A automação de interface informa ao sistema operacional quais movimentos realizar e aguarda de forma síncrona que eles sejam executados, um por vez.
Essas ações incluem iniciar seu app, interagir com botões e navegação, definir o estado do sistema como Modo Escuro e até definir um local simulado para o dispositivo, se você quiser. A acessibilidade é um dos principais valores na Apple. As tecnologias assistivas da Apple garantem que todos possam usar seu app independentemente de deficiências físicas, visuais, auditivas ou motoras. Trabalhamos muito para garantir que a maioria dessas tecnologias funcione com seu app por padrão, sem exigir que você mexa no código. Dito isso, incluir compatibilidade adicional pode melhorar a experiência no seu app e facilitar a automatização dele. A questão é que a acessibilidade é o framework subjacente que possibilita a automação de interface. Ter uma ótima experiência de acessibilidade também significa ter uma ótima experiência de automação de interface. A acessibilidade passa informações direto para a automação de interface, como element type, label, value e frame, mas o que ela enxerga nem sempre corresponde ao que uma pessoa vê. Vamos ver um exemplo. Nesta tela, o botão Great Barrier Reef está visível na interface, mas a acessibilidade vê além. Claro, a acessibilidade pode ver os valores de element type e label e expô-los à automação de interface, mas a propriedade identifier também é exposta. O accessibility identifier descreve qualquer elemento na tela de forma única em relação a todos os elementos ao seu redor. Ele não foi criado para ser localizado, então pode ser usado para fazer referência ao mesmo elemento da interface em qualquer idioma ou dispositivo.
Em caixas de seleção e outros elementos com estado, uma propriedade value pode ser usada. Isso revela o estado atual do elemento para a acessibilidade e a automação de interface.
Para saber mais sobre acessibilidade, confira "Criar apps acessíveis com a SwiftUI e UIKit", da WWDC23, ou "Acessibilidade da SwiftUI: além do básico", da WWDC21.
Já vimos como a automação de interface e a acessibilidade trabalham juntas. Vamos preparar seu app para automação.
Primeiro, adicionaremos accessibility identifiers. Depois, vamos analisar a acessibilidade do seu app. Por fim, adicionaremos um novo destino do teste de interface na preparação para gravar as interações como código. Antes de continuar, lembre-se de que seu app já é totalmente compatível com automação e gravação de interface, sem que você precise mexer no código. As próximas etapas não são obrigatórias, mas podem levar a resultados melhores. A adição de accessibility identifiers pode ser feita no código da sua visualização escrito em SwiftUI, UIKit ou AppKit. Essa é a melhor maneira de identificar exclusivamente qualquer elemento do seu app para automação. Recomendamos adicionar accessibility identifiers a elementos com strings localizadas ou conteúdo dinâmico. Isso inclui o conteúdo encontrado em qualquer um dos seus modelos de dados ou baixado da internet.
Bons identifiers são únicos em todo o app, descritivos o suficiente para detalhar o elemento em que estão e estáticos, não reagindo a alterações no conteúdo.
Embora títulos e descrições possam mudar, bons identifiers sempre descrevem o conteúdo do elemento a que estão vinculados. Assim, podemos garantir que meus pontos de referência permaneçam para sempre.
Além da SwiftUI, você pode incluir o modificador accessibilityIdentifier em qualquer elemento da interface. Ele será reconhecido se a sua visualização e as visualizações principais não estiverem ocultas da acessibilidade.
É recomendável criar identifiers específicos para uma instância de uma visualização, especialmente para as que são usadas muitas vezes no app. Neste exemplo, usamos a propriedade id para tornar o identificador exclusivo para cada ponto de referência.
No UIKit, a propriedade accessibilityIdentifier pode ser definida em qualquer UIView em que a visualização é um elemento de acessibilidade. A maioria das visualizações de interface (controles, texto, imagens) são elementos de acessibilidade por padrão, então não precisa fazer nada.
Propriedades como accessibilityLabel, accessibilityTraits e accessibilityValue são úteis para tecnologias assistivas como VoiceOver e para automação de interface.
Mas a propriedade accessibilityIdentifier não é lida em voz alta pelo VoiceOver e não é exposta a ninguém que usa seu app. Por isso, ela é útil para fornecer informações apenas à automação, como o índice de uma célula de tabela ou o nome do símbolo de uma imagem. Posso até fazer o assistente de programação do Xcode adicionar accessibility identifiers para mim. Por exemplo, posso escrever "Adicione accessibility identifiers às partes relevantes desta visualização", e ele fará isso. O assistente de programação sabe até mesmo usar a propriedade id em um ponto de referência para tornar cada identificador exclusivo. Muito legal. É recomendável revisar o comportamento geral de acessibilidade do seu app antes de iniciar a gravação da interface. É como usar fio dental antes de ir ao dentista. Em breve você vai saber se está se saindo bem. Mas assim você pode ter uma prévia. O Xcode vem com um app chamado Accessibility Inspector, que permite encontrar, diagnosticar e corrigir problemas de acessibilidade. O Inspector pode ser iniciado no menu superior do Xcode, em Open Developer Tool. Ele também pode ser aberto do Spotlight.
O Accessibility Inspector lista os valores de acessibilidade de qualquer visualização no app, em qualquer plataforma. Selecione a plataforma que deseja inspecionar, clique no Element Inspector e interaja com o elemento sobre o qual você quer saber mais nessa plataforma. Uma lista de propriedades do elemento será exibida. Alguns deles, como os da seção Basic, são bem úteis para a automação de interface. Para visualizações com informações faltando, convém alterar o código-fonte do app e adicionar algumas. Você pode descobrir detalhes sobre cada propriedade clicando no nome dela. O popover informará exatamente qual propriedade definir, fornecerá documentação sobre ela e muito mais.
Saiba ainda mais sobre os recursos de acessibilidade com nosso projeto de código de exemplo "Oferecer uma experiência de acessibilidade excepcional". Ele tem exemplos de código de um app que usa muitos recursos de acessibilidade e é compatível com automação de interface. Além disso, confira o artigo "Fazer testes de acessibilidade com seu app" para conhecer modos de verificar a acessibilidade do app usando várias tecnologias assistivas. Quando for a hora de automatizar, precisamos adicionar um novo destino de teste de interface para ter onde colocar nosso código de automação.
Na tela de ajustes do projeto no Xcode, adicione um novo destino com o botão de adição abaixo da lista de destinos.
Depois, selecione UI Testing Bundle no popover.
Clique em Finish. Uma nova pasta de teste de interface e um novo modelo serão incluídos no projeto. O modelo tem alguns testes simples para ajudar você a começar. Agora estamos prontos para gravar magicamente nossas interações como código do Swift. Vamos usar o Simulador do iOS e o Xcode para isso. Há alguns anos, minha mãe e minha irmã fizeram uma viagem de um mês para a Austrália sem mim, e fiquei chateado por não ter ido com elas. Para minha sorte, existe um app para isso. Posso usar o projeto de exemplo Landmarks da WWDC deste ano para planejar minhas próprias férias. Vou gravar algumas interações que planejam minha viagem para garantir que esse fluxo de trabalho continue funcionando em versões futuras do app. Quando abro o arquivo de origem do teste de interface pela primeira vez, um popover informa como iniciar uma gravação da interface. Agora, iniciarei uma gravação da interface usando o botão na barra lateral. O Xcode vai compilar e reiniciar meu app no Simulador.
Agora que o app abriu, vou para a visualização de coleções.
Conforme interajo com o app, o código que representa minhas interações é gravado no editor do código-fonte. Vou tocar no botão de adição para adicionar uma nova coleção e planejar minha viagem para a Austrália. Agora vou tocar no botão Edit para renomear a viagem e vou usar o nome Aventura na Austrália do Max.
O Xcode manterá meu teste atualizado enquanto eu digito.
Agora vou editar a coleção de pontos de referência. Vou adicionar alguns locais da Austrália, como a Grande Barreira de Corais e Uluru, e tocar na marca de seleção.
Na visualização de coleções, posso ver que minha coleção foi adicionada com alguns pontos de referência australianos incluídos.
Você pode parar a gravação da interface com o botão de parar no Xcode. Ao terminar de gravar, há algumas etapas importantes para garantir que você conseguiu a automação desejada. Primeiro, revise o código gravado. Adicione validações usando as APIs XCTest para garantir que o app esteja se comportando como esperado. Por fim, explore outras APIs de automação que podem deixar seu teste ainda mais robusto.
Vamos revisar as consultas de interface que foram gravadas e ver se quero fazer algum ajuste. Cada linha de código gravado terá várias opções para tratar cada elemento da interface, e a escolhida depende dos seus objetivos. Clique no menu suspenso em cada linha do código-fonte para ver as opções.
Dica rápida: escolher a opção certa vai ajudar você a embarcar para a Austrália mais rápido.
Temos algumas recomendações para ajudar na escolha das opções.
Para visualizações com strings localizadas, como elementos de texto ou botões, recomendamos escolher um accessibility identifier, se houver. A gravação da interface tenta usar o identificador por padrão, se houver.
Para visualizações profundamente aninhadas, como texto em áreas roláveis, escolha a consulta mais curta possível. Isso ajudará sua automação a se manter resiliente à medida que o app mudar.
Por fim, para conteúdo dinâmico baixado da internet ou que muda com frequência, como registros de data e hora ou temperatura, recomendamos usar uma consulta mais genérica ou um accessibility identifier, se houver.
Neste exemplo, nem sequer usamos um identifier ou qualquer string e sempre nos referimos só à primeira parte do texto.
Agora é hora de escolher. Vou clicar na linha do código-fonte que quero editar para ver as opções. Essas consultas identificam exclusivamente o elemento com que você interagiu. Então, não há escolha errada. É só escolher como você quer armazenar uma referência a essa parte da interface para uso futuro. Vou selecionar textFields.firstMatch para que o campo de texto seja sempre tocado no meu teste, independentemente do nome dele. Clique duas vezes em qualquer uma das listas suspensas para armazenar esse resultado no código-fonte. Agora vamos executar a automação de novo e ver se ela gravou minhas ações corretamente. Vou clicar no losango de teste. Estamos testando seu app, mas não estamos tentando testar sua paciência. A reprodução da automação é bem rápida.
A coleção é criada rapidamente com o nome certo, os locais são adicionados e a automação é bem-sucedida. Incrível. Foi muito mais rápido que um voo de 19 horas. Agora podemos adicionar validações ao código para verificar o comportamento esperado. Neste exemplo, vou validar que a Grande Barreira foi adicionada à minha coleção.
Posso chamar métodos como waitForExistence para que minha automação espere a aparição de um elemento antes de seguir em frente. Também posso chamar o método mais genérico, wait(for:toEqual:), para validar se as propriedades em um XCUIElement correspondem ao resultado esperado.
Posso combinar esses dois métodos com instruções XCTAssert do XCTest para que o teste falhe caso esses métodos retornem false.
Agora, vou voltar ao código e adicionar um waitForExistence no nome da minha coleção para garantir que ela esteja sempre presente em execuções futuras.
Este é um bom momento para explorar outras APIs de automação e deixar o código ainda mais eficiente.
Pode ser útil usar o método de instância setUp da XCTestCase para garantir que o dispositivo esteja no mesmo estado em execuções futuras. Posso chamar APIs como orientation e appearance ou até simular uma localização para deixar o dispositivo no estado certo antes da execução.
Antes de iniciar meu app, posso usar propriedades como launchArguments e launchEnvironment para que ele use esses parâmetros ao chamar o método launch.
Se o app for compatível com um esquema de URL personalizado, você poderá abri-lo em um URL correspondente usando o método open da XCUIApplication.
Existe até uma versão global, que abre um URL usando o app padrão do dispositivo para ela.
Por fim, é possível auditar a acessibilidade do seu app em um teste de interface. A WWDC23 tem uma ótima sessão sobre isso: "Auditar a acessibilidade do seu app". Agora que gravamos as interações e configuramos a automação, vamos definir os testes para reprodução em várias configurações, localmente e na nuvem. É muito útil adicionar seu teste a um plano de teste novo ou atual. Esses planos permitem incluir ou excluir testes, definir configurações do sistema sobre onde e como executar os testes e gerenciar propriedades como tempo limite, repetições, paralelismo, ordem de execução, etc.
Planos de teste também são associados a um esquema, que permite associá-los a configurações de compilação específicas.
Saiba mais sobre isso no artigo "Melhorar a avaliação de código organizando testes em planos de teste", na documentação para desenvolvedores.
No plano de teste, você pode adicionar ou remover testes na primeira tela ou fazer mudanças na execução do teste na aba Configurations. Posso definir várias configurações para executar meu app em diversos idiomas.
Normalmente, cada local é uma configuração separada no plano de teste.
Você pode ter ajustes para uma configuração de local específica ou outras que são compartilhadas entre todas elas.
Pode ser útil incluir configurações para idiomas com strings mais longas, como alemão, ou escritos da direita para a esquerda, como árabe e hebraico.
A aba Configurations também tem configurações focadas na automação de interface. Elas incluem capturar vídeo ou capturas de tela durante a execução e se algum material será mantido depois.
Por padrão, vídeos e capturas são mantidos só para execuções com falha, para permitir análise de problemas. Para mantê-los em todas as execuções, mesmo as aprovadas, selecione On, and keep all. Esse ajuste permite manter gravações de vídeo para outros fins, como documentação, tutoriais ou marketing. Há tantos outros ajustes incríveis para explorar na aba Configurations. Para saber mais, confira a sessão "Criar testes rápidos e confiáveis para Xcode Cloud", da WWDC22.
O Xcode Cloud é um serviço integrado ao Xcode, também disponível no App Store Connect. Ele pode ajudar a criar seu app, executar testes, fazer upload na App Store e muito mais. Tudo isso acontece na nuvem, sem exigir o uso de dispositivos da sua equipe ou seus. Acho que você vai concordar: no Xcode Cloud, o clima é sempre bom. Para o app Landmarks, configuramos um fluxo de trabalho do Xcode Cloud que executa as automações que acabei de escrever, usando o plano de teste que criei. Esse plano será executado na nuvem assim como foi executado no meu Simulador, em qualquer dispositivo e configuração, como inglês, árabe, hebraico e alemão, no iPhone e iPad.
Você pode ver um histórico da execução do Xcode Cloud no Xcode ou na seção Xcode Cloud do App Store Connect. Lá, você encontra uma visão geral das informações de compilação, logs, descrições de falha, etc.
No Xcode Cloud, toda a minha equipe pode ver um histórico das minhas execuções e baixar resultados e gravações de vídeo delas. Eles podem fazer isso mesmo que eu esteja literalmente nas nuvens, quero dizer, no meu voo para Sydney.
Há tanto para aprender sobre o Xcode Cloud. Para configurações mais avançadas, confira "Criar fluxos de trabalho práticos no Xcode Cloud", da WWDC23. Agora que executamos os testes gravados usando um plano de teste em várias configurações, podemos revisar os resultados e as gravações com o relatório de teste. O relatório de teste do Xcode tem ótimas ferramentas para visualizar, entender e diagnosticar resultados de testes. Parece que uma das execuções da minha automação falhou. Acho que ainda não posso fazer as malas e ir para a Austrália. Para navegar até o teste que falhou, clico no botão Tests e clico duas vezes na execução com falha para ver a gravação e a descrição do que aconteceu.
Posso ver todas as execuções desse teste na lista suspensa de execuções. Assim, posso alternar entre gravações de vídeo do meu teste executado em diferentes configurações, como idiomas diferentes. Outra opção é baixar o vídeo clicando com o botão direito e escolhendo Save.
Pressiono Play para iniciar o vídeo.
Durante o vídeo, aparecem pontos que mostram as interações com a interface. Essas ações também são representadas na linha do tempo abaixo como pontos.
Parece que ainda falta um pouco para a falha, então vamos adiantar. Vou passar direto para o momento da falha usando o losango de falha na linha do tempo.
Vejo uma mensagem de falha, mas é difícil dizer o que deu errado. A mensagem diz que estamos procurando um botão chamado Aventura na Austrália do Max. Vamos ver o que estava presente no ponto da falha.
No momento da falha, vejo uma sobreposição com todos os elementos da interface na parte de cima do vídeo.
Se eu clicar em um deles, recebo recomendações de como abordar esse elemento no meu código de automação. Posso até clicar em Show All para ver outros exemplos e encontrar um que funcione para mim. Acho que entendi o erro. Esperávamos um botão, mas não há botão aqui. É só texto. Deixe-me corrigir o problema.
Eu seleciono o exemplo que quero e clico com o botão direito para copiá-lo.
Em seguida, clico em View Source para ir direto para meus testes e colo a nova linha de código sobre a atual.
Agora, posso substituir a variável XCUIApplication temporária pela variável app da gravação da interface. Tudo certo.
Ótimo, agora deve funcionar como esperado. Eu clico no losango de teste para assistir à repetição do teste. Desta vez, vou executar o teste em árabe para ver se a automação funciona quando o app é executado em um layout da direita para a esquerda.
A automação cria rapidamente minha coleção e a renomeia como faz em inglês. Muito legal.
Parece que a automação foi aprovada. Hora de finalizar aqui e partir para minha viagem dos sonhos. Talvez minha mãe e minha irmã possam ir junto para me apresentar o lugar. Podemos fazer muito mais com o relatório de teste do Xcode. Felizmente, a sessão "Corrigir falhas mais rápido com relatórios de teste do Xcode", da WWDC23, traz todos os detalhes. É incrível como a automação de interface, a acessibilidade, a localização, o Xcode Cloud e o relatório de teste trabalham juntos para aumentar a qualidade do seu app e torná-lo mais fácil de usar para todos. Reunir essas tecnologias em um único fluxo tem sido um prazer, e mal posso esperar para ver como os desenvolvedores vão usá-las.
Saiba mais sobre testes de unidade e Swift Testing no vídeo "Conhecer o Swift Testing", da WWDC24. Se você tiver mais perguntas ou comentários, entre nos Fóruns para desenvolvedores. Agradeço sua participação. Vejo você na Austrália.
-
-
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 - Introdução
A automação da interface do Xcode, impulsionada pelo framework XCUIAutomation, permite que você teste seus apps de forma abrangente. Ele funciona em conjunto com o Swift Testing e o framework XCTest, fornecendo um pacote completo de teste de app. Os testes de automação da interface validam a experiência do usuário de um app, sua integração com o hardware da Apple e o comportamento de fluxos de trabalho comuns, complementando os testes de unidade que abordam lógica e modelos de dados do app. O processo envolve três fases principais: Interações de gravação, que são automaticamente convertidas em código. Reprodução dessas interações em vários dispositivos, idiomas, regiões e orientações. Revisão de gravações de vídeo e resultados de cada teste de interface executado. Essas automações permitem que você teste seus apps como usuários reais, garantindo acessibilidade, suporte a idiomas e integração de hardware. Esse processo é compatível com todas as plataformas da Apple, permitindo que você crie e execute testes de automação uma vez para vários dispositivos, como iPhone, iPad, Mac, Apple TV e Apple Watch, com um clique.
- 3:58 - Visão geral da automação da interface de usuário
A automação da interface simula as interações do usuário com o app ao abri-lo, tocar nos botões e navegar pelas telas. São usados os recursos de acessibilidade do app, que fornecem rótulos, valores e identificadores exclusivos para elementos a fim de executar essas ações de forma independente. A acessibilidade, um dos principais valores da Apple, garante que os apps possam ser usados por todos, além de potencializar a automação da interface.
- 6:26 - Preparar seu app para automação
Para preparar a automação do app, várias etapas estão envolvidas. Primeiro, adicione identificadores de acessibilidade aos elementos do app. Esses identificadores são rótulos exclusivos escritos em SwiftUI, UIKit ou AppKit que ajudam as ferramentas de automação a reconhecer e interagir com partes específicas do app. Eles são particularmente úteis para elementos com strings localizadas ou conteúdo dinâmico e precisam ser descritivos, estáticos e exclusivos em todo o app. Depois, faça uma revisão rápida da acessibilidade do app usando o Inspetor de Acessibilidade. Essa ferramenta ajuda a identificar e corrigir eventuais problemas de acessibilidade, garantindo que o app esteja preparado para a automação. O Inspetor de Acessibilidade permite que você visualize e modifique as propriedades de acessibilidade de cada visualização, tornando o app mais funcional para tecnologias assistivas e scripts de automação. Por fim, adicione um novo destino de teste de interface ao projeto do Xcode. Esse destino fornece um espaço dedicado para armazenar o código de automação. Assim que o destino estiver configurado, você pode começar a gravar as interações com o app, que serão automaticamente traduzidas em código Swift, agilizando o processo de automação.
- 11:32 - Gravar suas interações
O projeto modelo Landmarks, mostrado no Xcode e Simulador, demonstra o planejamento de férias virtuais na Austrália. As gravações da interface capturam as interações dentro do app como código. O exemplo adiciona uma nova coleção, renomeia-a como “Max's Australian Adventure” e a preenche com pontos de referência como a Grande Barreira de Corais e Uluru. Quando a gravação é interrompida, o exemplo revisa o código gerado, seleciona as consultas de interface apropriadas e adiciona validações usando o XCTest para garantir a funcionalidade do app. O teste é então executado novamente, verificando a criação da coleção e a adição dos pontos de referência. É possível aprimorar ainda mais os testes ao ajustar estados de dispositivo específicos, simular locais e realizar auditorias de acessibilidade.
- 17:30 - Reproduzir em várias configurações
O Xcode Cloud permite testes automatizados do app em várias configurações na mesa e na nuvem, bem como em diferentes idiomas e dispositivos. Os planos de teste organizam os testes, definem os ajustes do sistema e gerenciam propriedades. As configurações permitem o teste em locais específicos, incluindo idiomas com strings mais longas ou scripts da direita para a esquerda. O Xcode Cloud executa testes na nuvem, salvando vídeos e capturas de tela de falhas para análise. Uma equipe inteira pode visualizar o histórico, os registros e os resultados, o que facilita a colaboração e o monitoramento remoto. Configurações avançadas e mais detalhes estão disponíveis na Documentação do Desenvolvedor.
- 20:54 - Revisar vídeos e resultados
O relatório de teste do Xcode fornece uma ferramenta abrangente para analisar os resultados do teste. Ao identificar uma execução de teste com falha, é possível acessar gravações de vídeo e descrições detalhadas. O relatório sobrepõe interações da interface ao vídeo e inclui uma linha do tempo com marcadores de falha para navegação rápida. É possível exibir os elementos da interface presentes no ponto de falha, receber sugestões de código e editar o código de teste diretamente. Após as correções, o teste pode ser executado novamente, e o relatório permite que você verifique a funcionalidade em diferentes idiomas e layouts, melhorando a qualidade e a acessibilidade do app.
- 24:16 - Próximas etapas
Para ter mais informações sobre teste de unidade e teste do Swift, consulte a sessão “Meet Swift Testing” da WWDC24. Se tiver dúvidas ou comentários, acesse os Fóruns para desenvolvedores.