No artigo anterior, nos encontramos com o AirTest IDE , mas, por precaução, vamos repetir: o AirTest IDE foi desenvolvido pela NetEase e foi projetado para aplicativos "difíceis de automatizar", como jogos. Na verdade, eles são o foco principal dos desenvolvedores, embora isso não pare de usar o AirTest para outros aplicativos.
Este trabalho é o segundo de uma série dedicada ao AirTest IDE. Você pode encontrar o primeiro artigo sobre o AirTest IDE aqui e o terceiro e último, dedicado à estrutura de automação da interface do usuário do Poco, por este link .
Hoje vou falar sobre uma das duas estruturas principais - AirTest. O AirTest é uma estrutura de plataforma cruzada para automatizar a interface do usuário, com base nos princípios de reconhecimento de imagem (reconhecimento de imagem), que, segundo os desenvolvedores, são adequados para jogos e aplicativos. O Projeto AirTest no GitHub contém 4 projetos: Airtest , Poco , iOS-Tangent , multi-device-runner .
E agora vamos à parte divertida!

Como funciona o AirTest
O AirTest processa as capturas de tela resultantes com base no processo de limiar . A linha inferior é comparar a intensidade dos pixels na imagem com um determinado número ( valor limite ) e, se o valor do pixel for maior, atribua uma cor a ele (o branco é o mais usado). Caso contrário, uma cor diferente é atribuída - preto. Como resultado, a saída é uma imagem em preto e branco. Uma limitação natural se segue: o AirTest não leva em consideração a cor durante o reconhecimento. Por exemplo, se você usar um objeto com a mesma silhueta, mas diferente, por exemplo, colorir e precisar verificar a presença de um elemento com uma paleta de cores específica, isso será extremamente difícil e poderá não funcionar.
Por exemplo, como parte do teste do AirTest IDE, foi decidido trabalhar com o jogo Marvel Puzzle Quest . Ao carregar, os personagens desse universo de quadrinhos piscam na tela em uma determinada ordem. De vez em quando, os figurinos mudam e é a primeira vez que sou alertado. No exemplo abaixo, eu esperava, como parte do teste, o Homem-Aranha no clássico e recebi um traje furtivo. O teste, de fato, foi bem-sucedido, mas isso aconteceu por causa do exposto acima - o uso de uma imagem em preto e branco durante o reconhecimento. Um exemplo do que era esperado e do que finalmente aconteceu:

Aumentando a probabilidade de conclusão bem-sucedida de testes
Como você já entendeu, o reconhecimento de imagem está longe de ser uma panacéia, embora funcione bem aqui. Para escrever testes de qualidade, você não pode evitar escrever código e, consequentemente, conhecer o básico do Python. Por exemplo, antes de procurar um elemento específico, seria bom garantir que ele realmente esteja na tela. Há momentos em que o AirTest “erra” e pode levar o item errado para o que você precisa. Ocasionalmente, há problemas com o reconhecimento do texto que você deseja encontrar usando o Reconhecimento de imagem. O AirTest pode confundir os resultados e assumir que o texto que você precisa está na tela, mas, na verdade, o texto é completamente diferente. O processo de análise de resultados foi projetado para simplificar o sistema de relatórios que já está integrado ao AirTest IDE. Você pode criar e abrir um relatório após a conclusão do teste / script usando o atalho de teclado Ctrl / Cmd + L.
De acordo com recomendações gerais, eu também destacaria o seguinte.
- Faça capturas de tela exatamente dos elementos que você precisa. Quero dizer, se você precisar de um botão que, por exemplo, esteja localizado em um pano de fundo de textura complexo, tente fazer uma tela apenas do botão para não perder tempo processando o pano de fundo, o que, de fato, você não precisa. Nesse caso, a pesquisa não dependerá do que é mostrado no pano de fundo e você obterá um resultado mais preciso em menos tempo.
- Tente evitar o reconhecimento de imagens que contêm apenas texto, como o reconhecimento bem-sucedido ("taxa de sucesso") nesse caso será bastante reduzido.
- Embora a criação de capturas de tela durante a gravação automática de código (gravação automática de script) seja uma função bastante conveniente, em alguns locais, as capturas de tela não são muito informativas. É melhor criá-los manualmente para armazenar informações de pesquisa mais úteis nas suas fotos.
E se você quiser perguntar “É possível alterar as configurações do processo de busca de imagens?”, Responderei: sim, é possível.
Configurações de reconhecimento de imagem
O usuário é permitido e incentivado a trabalhar com as configurações de Reconhecimento de imagem para alcançar os resultados desejados, otimizar o tempo e a probabilidade de reconhecimento bem-sucedido de elementos (taxa de sucesso) na tela. Essas configurações são armazenadas na janela do Editor de imagens e, para abri-la, é necessário clicar duas vezes na imagem desejada no Editor de scripts. As configurações de reconhecimento para cada imagem precisam ser alteradas separadamente ou variáveis globais devem ser usadas se, por exemplo, você desejar aumentar os requisitos de precisão para a operação de limite do seu projeto.
O Image Editor contém uma área de trabalho, bem como os botões "Snapshot + Recognition" e "Show Help". O primeiro é responsável por comparar sua foto atual com a versão do instantâneo. A foto instantânea é capturada na janela atual do seu dispositivo. O segundo botão abre o manual funcional do Image Editor. À direita da janela, a imagem atual para pesquisa é exibida, além de configurações como nome do arquivo, limite, target_pos e rgb.
- O campo nome do arquivo é responsável pelo nome da imagem salva no momento (todas as imagens são salvas na pasta do projeto).
- O limite armazena o valor da porcentagem de coincidência (de 0 a 1) de imagens após o reconhecimento. Quanto maior o valor, maior o requisito de precisão da correspondência de imagem. Como mencionado acima, o AirTest converte imagens em preto e branco (dependendo da implementação do limite) e, portanto, a cor não é levada em consideração durante o reconhecimento.
- A caixa de seleção rgb foi projetada para "ativar e adicionar" cores durante o reconhecimento de imagem e, assim, começar a levar em consideração. No entanto, lembre-se de que a inclusão dessa funcionalidade ainda não garante 100% do resultado. Por exemplo, se você tiver 2 botões idênticos que diferem apenas na cor do plano de fundo, a probabilidade de reconhecimento incorreto (por exemplo, dentro de assert_exists / assert_not_exists) será bastante alta.
- target_pos é responsável pelo ponto na imagem em que o AirTest clica após o reconhecimento. O valor padrão é 5, mas você pode alterá-lo de 1 para 9, onde 1 é o canto superior esquerdo da sua imagem de trabalho e 9 é o canto inferior direito. A localização de todos os nove pontos é mostrada claramente na captura de tela abaixo. Você também pode ler sobre isso na documentação oficial.
Neste exemplo, o botão do meio está selecionado para reconhecimento. O esboço mostra as bordas da seleção.

Escrevendo testes automatizados com AirTest
Todos os comandos de trabalho da estrutura AirTest podem ser encontrados na janela AirTestAssistant, no canto superior esquerdo do Airtest IDE. Se não estiver lá, você poderá definir o layout da janela padrão usando Janela -> Layout padrão .
Localização da janela do AirTest Assistant Na versão atual do programa, você pode usar os seguintes comandos disponíveis na janela do AirTest Assistant:
- toque - este comando simula um gesto de toque em um dispositivo móvel. O toque possui os seguintes parâmetros - toque (v, tempos = 1, duração = 0,01, clique com o botão direito = Falso).
- v - imagem ou coordenada (x, y)
- vezes - o número de cliques. O valor padrão é 1
- duration - a duração da espera após tocar na tela. Com este parâmetro, você pode simular um "toque longo" (long_touch). O valor padrão é 0,01 segundos.
- clique direito - clique no "botão direito do mouse". Só pode ser usado em programas do Windows.
- wait - aguardando o elemento da interface do usuário. O comando possui os seguintes parâmetros - wait (v, timeout = TIMEOUT, interval = 5, intervalfunc = None).
- v - a imagem que o programa espera
- timeout - timeout. O valor padrão é 20.
- intervalfunc - função de usuário (personalizada). Se a imagem não for encontrada, esta função será executada.
- intervalo - intervalo entre comparação de imagens
A função retorna o seguinte: se uma imagem for encontrada, as coordenadas centrais da imagem especificada serão retornadas, caso contrário, TargetNotFoundError será lançado
- furto - este comando simula um gesto de furto em um dispositivo móvel ("deslizando a tela"). Swipe possui os seguintes parâmetros: swipe (v1, v2 = Nenhum, vetor = Nenhum, duração = 0,01).
- v1 - o valor a partir do qual svayp começa. Pode ser uma imagem ou uma determinada coordenada (x, y)
- v2: deslize o valor final (o comando é executado da v1 para a v2). Este parâmetro tem prioridade mais alta que o parâmetro "vetor"
- vetor [x, y] - é criado durante a operação do AirTest ou você pode configurá-lo você mesmo. Indica o caminho a percorrer. Para deslizar para a direita, X deve ser positivo, por sua vez, Y deve ser positivo para deslizar para baixo.
- steps - não usou esse parâmetro e não encontrou como ele é aplicado na prática. A dica de ferramenta fornece o seguinte: "o nó no caminho de furto, padrão 5". Suponho que o vetor de direção do furto seja dividido em “seções” e, em vez de trocar instantaneamente do ponto A para o ponto B, o furto será simulado com pequenas pausas nos nós especificados neste parâmetro, como se estivesse simulando um movimento em fases. Por exemplo, se o valor for 5, o vetor será dividido em 5 segmentos.
- duration - a duração do furto. O valor padrão é 0,5 segundos.
- existe - verifique se o elemento que você espera na tela do monitor do dispositivo existe . existe possui os seguintes parâmetros: existe (v)
- v - imagem
A função retorna o seguinte: se uma imagem for encontrada, as coordenadas do centro da imagem serão retornadas, caso contrário, False.
- texto - comando de entrada de texto . text possui os seguintes parâmetros: text (text, enter = True, search = False)
- texto - sequência de texto para inserir
- enter - este parâmetro é responsável por usar "Enter" após inserir o texto. O valor padrão é True.
- search - não usou esse parâmetro e não encontrou como ele é aplicado na prática. A dica de ferramenta fornece o seguinte: "force" Pesquisar "ou não após a entrada". O valor padrão é Falso.
- keyevent - emulação de pressionar botões físicos no dispositivo, como HOME, BACK, MENU, POWER, etc. Parâmetros para este comando: keyevent (keyname)
- keyname - nome do botão (POWER, HOME, etc.)
- instantâneo - crie uma captura de tela da tela no estado atual. Opções padrão: instantâneo (nome do arquivo = Nenhum, msg = "ponto de teste")
- filename - salve a captura de tela atual como um arquivo separado. Você pode ignorar esta opção.
- msg - descrição deste ponto de teste. Este texto será exibido no relatório HTML, que pode ser criado após o teste.
Esta função retorna o seguinte: nome do arquivo (nome do arquivo).
- sono - o teste de corrida "adormece" por um tempo. Valores padrão: suspensão (s = 1,0)
- segundos - tempo limite. O valor padrão é 1 segundo.
- assert_exists - verifica se existe um elemento. Parâmetros para este comando: assert_exists (v, msg = "test-point")
- v - imagem com o elemento, cuja presença é verificada
- msg - descrição deste ponto de teste. Este texto será exibido no relatório HTML, que pode ser criado após o teste.
Esta função retorna o seguinte: se uma imagem for encontrada, as coordenadas do ponto central dessa imagem serão retornadas; caso contrário, um AssertionError será lançado
- assert_not_exists - verifique se o item não está presente na tela do dispositivo. Parâmetros para este comando: assert_not_exists (v, msg = "test-point")
- v - imagem com o elemento, cuja presença é verificada
- msg - descrição deste ponto de teste. Este texto será exibido no relatório HTML, que pode ser criado após o teste.
- assert_equal - verifique se o atributo é igual ao valor especificado. Parâmetros para este comando: assert_equal (primeiro, segundo, msg = "ponto de teste")
- first - o primeiro item a comparar
- second - o segundo elemento a comparar
- msg - descrição deste ponto de teste. Este texto será exibido no relatório HTML, que pode ser criado após o teste.
- assert_not_equal - verifique se o atributo não é igual ao valor especificado. Parâmetros para este comando: assert_not_equal (primeiro, segundo, msg = "ponto de teste")
- first - o primeiro item a comparar
- second - o segundo elemento a comparar
- msg - descrição deste ponto de teste. Este texto será exibido no relatório HTML, que pode ser criado após o teste.
Esses comandos estão divididos em 3 grupos principais: Operações, Funções Auxiliares e Asserções . Você pode selecionar o grupo necessário usando o filtro apropriado (um menu suspenso imediatamente abaixo do nome da janela).
Filtro de grupo de equipes As equipes que precisam de uma imagem ativam as funções de gravação de captura de tela imediatamente após clicar no botão correspondente. Por exemplo, para selecionar em qual item clicar na tela, selecione o comando de toque no AirTest Assistant e, na janela Tela do dispositivo, no dispositivo ativo, circule o item em que deseja clicar. Depois disso, o comando correspondente aparecerá na janela principal (Editor de scripts), no nosso caso, toque com a imagem como parâmetro. Como resultado, o processo de automação é o seguinte (o gif foi gravado de uma versão obsoleta do AirTest IDE):

Se, por algum motivo, você não desejar criar capturas de tela manualmente e / ou escrever código em geral, poderá usar a função de gravação automática. Você pode ativá-lo clicando no botão "câmera" do lado oposto ao menu suspenso com grupos de comandos na janela do Assistente Airtest. A gravação automática é uma coisa bastante precisa e conveniente, mas, é claro, não é uma panacéia e não substitui a discagem manual.

Vale mencionar mais 3 teclas de atalho - F5 (iniciar o script), F10 (interromper o script em execução), Ctrl + L / Cmd + L (crie um relatório com base no teste finalizado).
Você pode executar testes prontos sem uma interface do usuário usando o terminal (linha de comando). Mais informações sobre isso em geral e sobre a execução de testes em particular podem ser encontradas aqui .
Um exemplo de um trecho de um teste escrito usando a estrutura AirTest pode ser encontrado no spoiler!
Exemplo de autoteste escrito usando AirTest (reconhecimento de imagem) A interface do usuário no seu aplicativo / jogo não consiste inteiramente de ícones, botões, costas, etc. exclusivos Além disso, elementos visualmente periodicamente idênticos podem ser encontrados em uma tela, por exemplo, botões, controles deslizantes, etc. Na maioria dos casos, nesses casos, o AirTest não poderá reconhecer o elemento necessário e o teste falhará com erro ou o elemento de interface errado será selecionado para outras manipulações.
Um exemplo de uma janela com vários elementos idênticos Especialmente para esses casos, outra estrutura foi desenvolvida que já está incorporada no AirTest IDE. Ele é Poco e foi brevemente descrito em um artigo com uma visão geral do Airtest IDE . Vou falar mais sobre essa estrutura no próximo artigo.
Diga-nos se você já usou o AirTest IDE e o que pensa sobre esta ferramenta. Ficarei feliz em discutir nos comentários!