Testar formulários da Web longos em vários navegadores e em resoluções não é apenas extremamente necessário, mas também pela terceira ou quarta vez - um processo extremamente chato e intensivo em concentração. Portanto, essa é exatamente a área que pede automação. Foi o que fizemos.
Neste artigo sobre Habr, falaremos sobre nossa experiência em testar telas grandes com as ferramentas de grade Transferidor, Zalênio e Selênio. Como gradualmente introduzimos essas ferramentas para o teste automático da interface do usuário e que dificuldades tivemos.

Criamos e mantemos um sistema no qual 7 mil usuários ativos. Na maioria das vezes eles usam esses navegadores:

E as seguintes resoluções de tela:

Cada vez após o lançamento de uma nova versão, você precisa verificar o desempenho nesses navegadores e permissões.
Para entender melhor como os testes de interface do usuário geralmente funcionam no nosso caso, considere um caso simples: testando a funcionalidade de um aplicativo de recuperação de senha. Consequentemente, existem duas páginas. Em um deles, você precisa especificar um nome de usuário ou email onde uma carta virá com um link para uma alteração de senha. Após o envio do aplicativo, o usuário acessa a página com a confirmação de que tudo correu bem.
Formulário de recuperação de senha
A página para a qual o redirecionamento ocorre após o envio bem-sucedido do aplicativoTestar esse mecanismo de uma forma simplificada se parece com isso:

O mesmo script que o código:
it(' ', async function(): Promise<boolean | void> { await browser.get(browser.baseUrl); await element(by.name('EmailOrLogin')).sendKeys(userLogin); await element(by.buttonText('')).click(); const screenshot = await browser.takeScreenshot(); const canonicalScreenshotPath = < >; await compareScreenshot(screenshot, canonicalScreenshotPath); });
Como você pode ver, o código de teste parece bastante simples, literalmente repete o que foi mostrado no diagrama de blocos.
Agora, mostramos quais ferramentas foram úteis para implementar esse esquema em diferentes resoluções de tela e que dificuldades encontramos.
Caixa de ferramentas selecionada
Iniciado com chrome
Para automação de teste, escolhemos o Protractor, uma estrutura e2e para testar aplicativos Angular. Nossa aplicação é apenas no Angular. Com o transferidor, fizemos dois tipos de testes:
- Sobre a funcionalidade geral: Um formulário de envio de aplicativo é aberto, preenchido com dados e um aplicativo é enviado, após o que verificamos que ocorreu um redirecionamento para o registro de todos os aplicativos.
- Testes de captura de tela: o transferidor permite tirar uma captura de tela a qualquer momento. Usando uma biblioteca separada de colheita azul, comparamos duas capturas de tela: uma referência e uma real. Se eles não corresponderem, uma captura de tela é criada imediatamente, na qual todas as diferenças são visíveis, assim como no Git.
Por exemplo, se você continuar analisando o exemplo descrito acima.
Captura de tela com mensagem de link inválida
As diferenças (texto e layout do botão) nas capturas de tela de referência e atuais são destacadas em lilásSe a página contiver dados alterados dinamicamente (por exemplo, a data ou o número do pedido), você precisará mascará-los - essa funcionalidade está na biblioteca de colheita azul. Caso contrário, a comparação de capturas de tela produzirá um resultado negativo.
Adicione FF e permissões diferentes
Com o tempo, nossos requisitos para o sistema de teste de interface do usuário existente aumentaram:
- execute testes não apenas no Chrome, mas também no FF,
- realize testes de captura de tela não em uma resolução, mas nas mais populares,
- executar testes em paralelo.
Então, vamos fazer nossos testes paralelos no Chrome e no FF.
Para fazer isso, na configuração dos recursos Transferidor, substitua-o por:
multiCapabilities: [ { shardTestFiles: true, maxInstances: 2, browserName: 'chrome' }, { shardTestFiles: true, maxInstances: 2, browserName: 'firefox' } ]
Tudo é óbvio aqui, pelo qual cada configuração é responsável. Só merece atenção
shardTestFiles: true
/** * If this is set to be true, specs will be shared by file (ie all files to be run by this set of capabilities will run in parallel). * Default is false. */
Com esse sinalizador, fornecemos o lançamento paralelo de todas as especificações em todos os navegadores especificados em multiCapabilities.
O parâmetro specs está oculto sob a palavra specs, que determina por qual modelo procurar arquivos com testes.
exports.config = { ... specs: ['./e2e/**/*.spec.ts'], ... }
A teoria de dividir todos os testes em vários arquivos de especificações parece bastante lógica. a simultaneidade funciona neles (por exemplo, crie um arquivo de especificação para cada recurso do aplicativo).
Além disso, em Transferidor, há a capacidade de destacar suítes.
exports.config = { ... suites: { suite01: './e2e/**/suite01.*.spec.ts', suite02: './e2e/**/suite02.spec.ts', suite03: './e2e/**/suite03.spec.ts' }, ... }
Como você pode ver nesta parte da configuração, ao iniciar um conjunto, os testes são executados a partir de apenas um arquivo de especificação. Isso provavelmente é útil se você deseja executar testes para apenas uma parte do aplicativo.
Quanto ao teste do aplicativo em diferentes resoluções, seguimos o seguinte caminho. Como permissões experimentais, foi selecionada uma das mais populares: 1920x1080, 1366x768, 1440x10900, 768x1024. Quando você executa cada teste, todas as ações necessárias foram executadas inicialmente e, em seguida, uma série de verificações de captura de tela é executada.

Conectamos o IE e capturas de tela em tamanho real
Infelizmente, os testes de captura de tela que obtivemos funcionaram apenas com base na parte visível da página. E se a rolagem estava presente na página, tudo abaixo permanecia inexplorado para o layout que foi.
Além disso, também precisamos oferecer suporte ao IE, para o qual nossos testes ainda não foram projetados. Começamos a procurar uma oportunidade adequada para executar testes no IE e fazer capturas de tela em tamanho real.

Decidimos duas soluções:
Zalenium e
Selenium-Grid . Omitimos a descrição de qual deles se orgulha de quê e contamos o que encontraram / não encontraram em nenhuma das soluções.
Zalenium : esta solução é executada em um contêiner do Docker e N outros contêineres sobem após o contêiner principal - para iniciar os navegadores. Permite especificar screenWidth, screenHeight durante a
docker run
e obter o tamanho da tela, por exemplo, 1920x6000. Não há suporte para o IE.
Dois navegadores com um tamanho de tela de 1920x6000Grade de selênio: os testes no IE começaram com muita facilidade.
Das desvantagens: não há como definir o tamanho da janela do navegador de qualquer tamanho.
Total: zalênio + grade de selênioNós decidimos por um monte de Zalenium + Selenium-grid: através do Zalenium, foi decidido executar testes no Chrome e FF, e através do Selenium-grid para verificar o desempenho mínimo do aplicativo no IE.
O que foi interessante encontrar no processo
1. Usando formControlName como um localizador de elementoUsando a pesquisa em formControlName, você pode pesquisar facilmente os campos obrigatórios no formulário e preenchê-los com dados de teste. O localizador por formControlName não é interno, mas é fácil adicionar:
exports.config = { ... onPrepare() { require('ts-node').register({ project: 'e2e/tsconfig.e2e.json' }); jasmine.getEnv().addReporter(new specReporter({ spec: { displayStacktrace: true } })); addFormControlNameLocator(protractor); } ... } function addFormControlNameLocator(protractor) { protractor.by.addLocator('formControlName', function(value, optParentElement) { var using = optParentElement || document; return using.querySelectorAll('[formControlName="' + value + '"]'); }); }
2. A diferença no trabalho do gerenciador de chaves da web instalado globalmente e localmente no TransferidorAo instalar o Transferidor no sistema (a documentação oficial aconselha a instalação global do Transferidor), além da própria estrutura de teste, obtemos o gerenciador de web instalado, que fornece drivers para os navegadores para executar testes com os quais um dos problemas foi detectado.
Depois de ir para a pasta do projeto e executar a atualização do gerenciador de driver da web, os drivers do Chrome, FF, IE são baixados. Depois disso, ao iniciar os testes, eles pegaram o erro:
No update-config.json found. Run 'webdriver-manager update' to download binaries.
Percebemos que o erro desaparece se empacotarmos a atualização do gerenciador de web em um script npm:
{ ... scripts:{ “webdriver-update”: “webdriver-manager update” } ... }
e, através do
npm run webdriver-update
, as fontes do driver e o update-config.json mencionado acima entram na pasta do projeto.
3. Executando o Zalenium através do docker-compositeA documentação do Zalenium é acompanhada de exemplos do comando
docker run
e do arquivo docker-compose. Tudo decola quase como se por mágica. O único problema que encontramos ocorreu ao iniciar o arquivo docker-compose
/var/run/docker.sock is not a valid windows path
. A solução está
aqui .
4. Visibilidade dos elementos pelo transferidorNo decorrer de nossas experiências, em um momento, fomos confrontados com a tarefa de perfurar algum menu da página, ou seja, vá para cada página do menu e faça uma captura de tela.

Após o processamento do primeiro elemento da lista, os testes começaram a cair, gerando um erro de que não havia nada para clicar em algumas coordenadas. Como se viu, independentemente do fato de todos os elementos da lista terem sido selecionados inicialmente, depois de se tornarem realmente invisíveis aos nossos olhos, eles desapareceram aos olhos do transferidor.
Resolvemos o problema configurando largura de tela suficiente para que o menu apareça novamente antes de clicar no próximo elemento.
5. Alteração da resolução no IE (Selenium-grid)Como você se lembra, no Chrome e no FF, ajustamos a alteração na resolução da tela. Quando se trata disso no IE, simplesmente capturamos o erro:
Failed: java.io.IOException: Server returned HTTP response code: 405 for URL: http://localhost:21800/session/8d14426d-6483-4bbf-90b3-2a3ed46ebe9b/window/size
.
Após uma longa depuração, foi possível descobrir que o erro ocorre exatamente no momento em que o código está tentando executar:
browser.driver.manage().window().setSize(x, y)
. Se você tentar executar o
browser.driver.manage().window().setPosition(x, y)
, em seguida, detectar o mesmo erro, apenas o tamanho será alterado para a posição. Isso nos leva ao fato de que é impossível controlar a resolução da tela quando os testes são executados no IE. A solução para o problema são muletas com as quais você precisa sobrepor seu código para não alterar a resolução \ posição quando o IE estiver em execução.
6. Zalenium e WebSocketDepois de coletar todos os obstáculos localmente, foi decidido levar o Zalenium à infraestrutura corporativa. O contêiner está aberto, o DNS está registrado, agora todos podem executar testes no Zalenium'e, simplesmente especificando o caminho para ele na configuração do Transferidor. Beleza, hein? Mas lá estava.
Nesse caso, tudo já foi implantado na máquina Linux, o Nginx foi usado como servidor. O contêiner com Zalenium subiu sem problemas, seguido por outros N contêineres para iniciar navegadores, mas ... não foi possível estabelecer conexões com eles. Foi fácil descobrir que o contêiner pai estava tentando se comunicar com os contêineres dos navegadores por meio do protocolo WebSocket, e o Nginx não podia fazer isso por padrão. O tratamento é muito simples.
location / { proxy_pass some_url; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; }
9. Lançamento da grade de selênioPara executar o Selenium-Grid, precisamos:
- servidor de selênio ,
- Driver IE, que é fácil de obter através da atualização do gerenciador de driver da web --ie32.
inicialização do servidor:
java -jar selenium-server-standalone.jar -role hub -hubConfig selenium-server-config.json
selenium-server-config.json { "host": "127.0.0.1", "maxSessions": 5, "port": 4445, "cleanupCycle": 5000, "timeout": 300000, "newSessionWaitTimeout": -1, "servlets": [], "prioritizer": null, "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", "throwOnCapabilityNotPresent": true, "nodePolling": 180000, "platform": "WINDOWS" }
iniciando o driver IE:
java -Dwebdriver.ie.driver=< > -jar selenium-server-standalone.jar -role node -nodeConfig .\\ie-driver-config.json
ie-driver-config.json { "capabilities": [ { "browserName": "internet explorer", "maxInstances": 1, "platform": "WINDOWS", "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe" } ], "cleanUpCycle": 2000, "timeout": 30000, "port": -1, "role": "node", "hub": "http://127.0.0.1:4445/grid/register/", "register": true, "maxSessions": 5 }
Preste atenção ao uso das mesmas portas ao iniciar o servidor e na URL do hub do driver. Como seleniumAddress na configuração do transferidor, usamos
http://127.0.0.1:4445/wd/hub
.
Conclusões
Assim, resolvemos nossa tarefa e, após o lançamento de uma nova versão, podemos verificar o desempenho nesses navegadores e resoluções.
Como integrar testes em um fluxo de trabalho
É importante entender que não basta elevar toda a infraestrutura para executar testes e escrevê-los. Você precisa pensar em como os usará em sua vida diária.
Não implementamos testes de interface do usuário no IC, porque eles são executados por tempo suficiente para permitir que eles aguardem sua execução para cada build.
Para testar a versão local do aplicativo ou instalada em um dos ambientes de teste (interno ou cliente), basta alterar baseUrl na configuração do Transferidor. Portanto, os testes podem ser executados pelo desenvolvedor e pelo testador.
Desenvolvedor - quando é necessário executar testes, por exemplo, para a versão local do aplicativo no processo de desenvolvimento de um novo recurso. Especialista em controle de qualidade - por exemplo, como teste de fumaça após uma implantação no produto ou como uma verificação no topo após várias refatorações.
Em conclusão, queremos enfatizar:- Lembre-se de que os testes de interface do usuário não pouparão a necessidade de realizar testes manuais detalhados. A automação ajuda apenas a cobrir áreas.
- Use a automação com sabedoria, principalmente para testes de fumaça. Cobrir tudo e tudo não faz sentido - é caro e difícil manter-se atualizado
- Escreva simplesmente. se seus testes de interface do usuário parecerem complicados, você estará fazendo algo errado. Bata simples e use como indicado (consulte o ponto 2)
Acreditamos que a automação do teste da interface do usuário é boa quando feita com facilidade. Então compartilhe conosco suas observações e ferramentas de sucesso nos comentários.
Links úteis nossos: