Teste de navegador automatizado com a API WebDriver

Publicados: 2022-03-10
Resumo rápido ↬ Este artigo fornece uma visão geral dos conceitos, tecnologias e técnicas de codificação envolvidas na execução de scripts de teste em navegadores automaticamente usando WebDriverJS no Windows 10 e Microsoft Edge.

Clicar manualmente em diferentes navegadores enquanto eles executam seu código de desenvolvimento, local ou remotamente, é uma maneira rápida de validar esse código. Ele permite que você inspecione visualmente se as coisas estão como você pretendia que fossem do ponto de vista do layout e da funcionalidade. No entanto, não é uma solução para testar toda a extensão da base de código do seu site na variedade de navegadores e tipos de dispositivos disponíveis para seus clientes. É aí que o teste automatizado realmente se destaca.

Liderado pelo projeto Selenium, o teste automatizado da Web é um conjunto de ferramentas para criar, gerenciar e executar testes em navegadores entre plataformas.

API WebDriverJS

A API do WebDriver é um padrão que abstrai as ligações específicas do dispositivo/navegador do desenvolvedor para que os scripts de teste escritos em sua linguagem de escolha possam ser escritos uma vez e executados em vários navegadores diferentes via WebDriver. Alguns navegadores têm recursos internos do WebDriver, outros exigem que você baixe um binário para sua combinação de navegador/SO.

API webdriverjs

Conduzindo o navegador por meio de APIs do WebDriver

A especificação WebDriver no W3C documenta as APIs disponíveis para desenvolvedores controlarem programaticamente o navegador. Este diagrama mostra uma página de amostra com algumas das coleções e APIs gerais do WebDriver que podem ser usadas para obter e definir as propriedades do navegador.

API webdriverjs

Testes de autoria

Você tem uma escolha de idiomas com base nas associações de idioma com suporte para WebDriver. As principais linguagens suportadas pelo projeto principal Selenium/WebDriverJS incluem:

  • C#
  • Java
  • JavaScript (via Node)
  • Pitão
  • Rubi
Mais depois do salto! Continue lendo abaixo ↓

Os testes podem variar desde a verificação do layout da página, os valores retornados das chamadas do lado do servidor, o comportamento esperado da interação do usuário até a verificação do fluxo de trabalho, como garantir que um fluxo de trabalho do carrinho de compras funcione conforme o esperado.

Para fins ilustrativos, vamos supor que estamos testando o aplicativo TODOMVC, um aplicativo de demonstração implementado em várias estruturas JavaScript de controle de exibição de modelo diferentes. Este aplicativo simples fornece interface do usuário para inserir itens de tarefas, editar, excluir e marcar itens como concluídos. Usaremos o exemplo baseado em React em https://todomvc.com/examples/react/.

Em seguida, poderemos demonstrar a execução dos testes para o exemplo React em relação aos exemplos Backbone.js e Vue.js simplesmente alterando a URL.

  • Gist do arquivo de exemplo JS completo

Para esta demonstração, vamos escrever testes em JavaScript rodando em node para:

  1. Adicione três itens de tarefas e verifique se o que digitamos foi criado em um item de tarefas.
  2. Modifique esse item clicando duas vezes, enviando comandos de teclado de retrocesso e adicionando mais texto.
  3. Exclua esse item usando as APIs do mouse.
  4. Marque um item da lista como concluído.

Configure seu ambiente de teste de automação básica

Vamos começar configurando nossa máquina Windows 10 para executar o WebDriver usando JavaScript. As chamadas para o WebDriver do nó serão quase sempre assíncronas. Para facilitar a leitura do código, usamos o async/await do ES2016 sobre Promises ou callbacks.

Você precisará instalar o node.js mais recente que a v7.6 ou usar o Babel para compilação cruzada para ter suporte para o recurso async/await. Além disso, usamos o Visual Studio Code para edição e depuração do nó.

WebDriverJS para Microsoft Edge

Cada navegador terá um arquivo binário que você precisará localmente para interagir com o próprio navegador. Esse binário é chamado pelo seu código por meio das APIs do Selenium WebDriver. Você pode encontrar os downloads e a documentação mais recentes para o Microsoft Edge WebDriver aqui.

Observe que a versão do Edge na qual você deseja executar os testes deve ser testada com a versão correspondente do MicrosoftWebDriver.exe . Usaremos a versão estável do Edge (16.16299) com o correspondente MicrosoftWebDriver.exe versão 5.16299.

Coloque o MicrosoftWebDriver.exe em seu caminho ou na mesma pasta que seu script de teste será executado. A execução deste executável iniciará uma janela de console mostrando a URL e o número da porta que o WebDriverJS estará esperando para lidar com as solicitações a serem enviadas.

WebDriverJS para outros navegadores

Você pode facilmente dizer ao WebDriverJS para executar testes em um navegador diferente definindo uma variável de configuração e tendo o driver binário apropriado para o respectivo navegador instalado. Você pode encontra-los aqui:

  • Apple Safari: fornecido com o Safari 10+
  • Google Chrome: ChromeDriver
  • Microsoft Internet Explorer: IEDriver do projeto Selenium
  • Mozilla Firefox: Geckodriver
  • Opera: OperaChromiumDriver

Selenium WebDriverJS para JavaScript

Para interagir com o driver binário que você acabou de baixar via JavaScript, você precisará instalar a biblioteca de automação Selenium WebDriver para JavaScript. Isso pode ser facilmente instalado como um pacote de nó usando:

npm install selenium-webdriver

Escrevendo código de automação

Uma vez que o binário do driver específico do seu navegador esteja no caminho do seu sistema ou pasta local e você instalou o Selenium WebDriver via npm, você pode começar a automatizar o navegador por meio de código.

Vamos dividir nosso código de exemplo nas várias etapas necessárias.

  1. Crie uma variável local para carregar e interagir com a biblioteca.
     var webdriver = require('selenium-webdriver');
  2. Por padrão, o WebDriverJS assumirá que você está executando localmente e que o arquivo de driver existe. Mais tarde, mostraremos como você pode passar informações de configuração para a biblioteca ao instanciar o navegador pela primeira vez. O WebDriverJS é instanciado com uma variável de configuração chamada “capabilities” para definir qual driver de navegador você deseja usar.
     var capabilities = { 'browserName': 'MicrosoftEdge' }; var entrytoEdit = "Browser Stack";
  3. Em seguida, você cria uma variável e chama build() com a variável de configuração de recursos para que o WebDriverJS instancie o navegador:
     var browser = new webdriver.Builder().withCapabilities(capabilities).build();
  4. Agora que podemos interagir com o navegador, dizemos a ele para navegar até uma URL usando o método `get`. Este método é assíncrono, então usamos `await` para esperar até que ele termine.
     // Have the browser navigate to the TODO MVC example for React await browser.get('https://todomvc.com/examples/react/#');
  5. Para alguns navegadores e sistemas, é melhor dar ao binário WebDriverJS algum tempo para navegar até a URL e carregar a página. Para o nosso exemplo, esperamos 1 segundo (1000ms) usando a função de gerenciamento do WebDriverJS:
     //Send a wait to the browser to account for script execution running await browser.manage().timeouts().implicitlyWait(1000);
  6. Agora você tem um gancho programático em um navegador em execução por meio da variável do navegador. Observe o diagrama de coleção anteriormente neste documento que mostra as coleções de API do WebDriver. Usamos a coleção Elements para obter elementos específicos da página. Neste caso, estamos procurando a caixa de entrada dentro do exemplo TODOMVC para que possamos inserir alguns itens TODO. Pedimos ao WebDriverJS para procurar elementos que correspondam à regra de classe .new-todo , pois sabemos que essa é a classe atribuída a este campo. Declaramos uma constante, pois não podemos alterar os dados que retornam - apenas consulte-os. Observe que isso encontrará o primeiro elemento no DOM que corresponde ao padrão CSS, o que é bom no nosso caso, pois sabemos que há apenas um.
     const todoEntry = await browser.findElement(webdriver.By.css('.new-todo'));
  7. Em seguida, enviamos pressionamentos de tecla para o campo para o qual acabamos de usar a função sendKeys. Colocamos a tecla enter com escape em sua própria linha de espera para evitar condições de corrida. Usamos o padrão de iteração for (x of y) pois estamos lidando com promessas. toDoTestItems é simplesmente uma matriz de 3 strings, uma variável de string (que testaremos mais tarde) e 2 literais. Nos bastidores, o WebDriverJS enviará caracteres individuais da string um de cada vez, mas apenas passamos a variável de string inteira para sendKeys :

     var toDoTestItems = [entrytoEdit, "Test Value1", "Test Value2"]; //Send keystrokes to the field we just found with the test strings and then send the Enter special character for (const item of toDoTestItems) { await todoEntry.sendKeys(item); await todoEntry.sendKeys("\n"); }

Neste ponto, vamos executar o script com node e ver se vemos um navegador que navega até a página e insere esses três itens TODO de teste. Envolva o código após a primeira declaração de variável em uma função async como esta:

 async function run() {

Feche a função } no final do código e chame essa função assíncrona com:

 run();

Salve seu arquivo JS. Vá para a janela de comando node, navegue até a pasta em que você salvou o arquivo JS e execute node yourfile.js

Você deverá ver uma janela do navegador aparecer e o texto enviado para o arquivo TODOMVC ser inserido como novas entradas TODO no aplicativo. Parabéns — você está pronto para usar o WebDriverJS.

Tente alterar a URL que o WebDriverJS carrega neste exemplo para uma das outras amostras TODOMVC e observe que o mesmo código de teste pode ser executado em diferentes estruturas.

 await browser.get('https://todomvc.com/examples/vue/');

Executando testes no BrowserStack

Mostramos como esse teste é executado localmente em sua máquina. O mesmo teste pode ser executado com a mesma facilidade usando serviços de teste online como o BrowserStack. Inscreva-se para obter acesso gratuito ao serviço BrowserStack para obter acesso aos navegadores Microsoft Edge para testes ao vivo e automatizados gratuitos. Depois de fazer login, vá para a seção "Automatizar" e procure as configurações automatizadas da sua conta de teste. Você precisará passá-los para a função WebDriverJS para entrar via código, nomear sua sessão de teste e passar seu token de acesso.

Em seguida, basta adicionar esses valores à variável de capabilities e chamar o construtor WebDriver novamente.

 var capabilities = { 'browserName': MicrosoftEdge, 'browserstack.user': 'yourusername', 'browserstack.key': 'yqniJ4quDL6s2Ak2EZpe', 'browserstack.debug': 'true', 'build': 'Name your test' }

Você pode aprender mais sobre a variável de capabilities e os valores que o BrowserStack pode aceitar aqui.

Em seguida, chame a função do builder e passe a URL do servidor BrowserStack:

 var browser = new webdriver.Builder(). usingServer('https://hub-cloud.browserstack.com/wd/hub'). withCapabilities(capabilities). build();

Por fim, você deve instruir o WebDriverJS a sair do navegador, caso contrário ele permanecerá em execução e, eventualmente, atingirá o tempo limite. Faça uma chamada para a função quit no final do arquivo de teste.

 browser.quit();

Agora, ao executar seu arquivo de teste JS usando o NodeJS, você enviará as instruções de teste para um navegador hospedado no serviço de nuvem do BrowserStack. Você pode ir para a seção "Automatizar" do BrowserStack e observar os trabalhos de teste iniciando e parando. Depois de concluído, você pode navegar pelos comandos do WebDriver que foram enviados, ver imagens da tela do navegador em intervalos durante a execução do teste e até ver um vídeo da sessão do navegador.

Uma captura de tela do recurso de log visual de um teste executado no serviço Automate do BrowserStack
Uma captura de tela do recurso de log visual de um teste executado no serviço Automate do BrowserStack

Testando valores com asserções

Ao testar seu site, você está comparando os resultados reais com os resultados esperados. A melhor maneira de fazer isso é por meio de declarações onde uma exceção será lançada se uma condição de declaração não for atendida. Em nosso exemplo, usamos uma biblioteca de asserções para expressar essas asserções e ajudar a tornar o código mais legível. Escolhemos o ChaiJS como flexível o suficiente para ser usado com qualquer biblioteca JavaScript e é bastante popular no momento em que escrevemos.

Você baixa e instala o Chai como um pacote de nó usando npm. No código, você precisa exigir chai :

 var expect = require('chai').expect;

Decidimos usar a interface Expect para usar linguagem natural para encadear nossas asserções.

Você pode testar o comprimento, a existência, contém um valor e muito mais.

 expect(testElements).to.not.have.lengthOf(0); //make sure that we're comparing the right number of items in each array/collection expect(testElements.length).to.equal(toDoTestItems.length);

Caso uma dessas asserções não seja verdadeira, uma exceção de asserção é lançada. Nosso código de exemplo parará de ser executado quando a exceção for lançada, pois não estamos manipulando a exceção. Na prática, você usará um executor de teste com nó que tratará as exceções e relatará erros e aprovações de teste.

Automatizando as passagens de teste com um executor de teste

Para lidar melhor com as exceções de asserção, um executor de teste é emparelhado com o nó para agrupar blocos de código contendo asserções de teste em funções de estilo try/catch que mapeiam as exceções para casos de teste com falha.

Neste exemplo, escolhemos o framework de teste MochaJS, pois combina bem com Chai e é algo que usamos para testar nosso código de produção.

Para integrar o executor, há código adicionado ao script de teste e uma alteração na maneira como você executa o código com node.

Adicionando código do executor de teste

Você envolve o código de teste em funções assíncronas com a função de nível superior usando a palavra-chave “describe” e a função de subteste usando a palavra-chave “it”. As funções são marcadas com uma descrição do que os testes estão procurando. Esta descrição é o que será mapeado para os resultados dos testes.

MochaJS é instalado como um pacote de nós via npm.

Aqui está a função de nível superior em nosso exemplo usando describe :

 describe('Run four tests against TODOMVC sample', async () => {

Subsequentemente, envolva seus testes lógicos em grupos com a palavra it chave it:

 it('TEST 3: Delete a TODO item from the list by clicking the X button', async () => {

Asserções encapsuladas nessas funções que causam uma exceção serão mapeadas de volta para essas descrições.

Executando o código com NodeJS e MochaJS

Finalmente, você precisa executar seu código de teste com o nó chamando o binário MochaJS para manipular as exceções corretamente. Mocha pode receber argumentos para configurar valores de tempo limite, a pasta a ser procurada que contém seus arquivos de teste e muito mais. Aqui está a configuração que usamos para o Visual Studio Code para anexar o depurador e usar os recursos de inspeção e passo a passo do Code:

 { "type": "node", "request": "launch", "name": "Mocha Tests", "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", "args": [ "-u", "tdd", "--timeout", "999999", "--colors", "${workspaceRoot}/test/**/*.js" ], "internalConsoleOptions": "openOnSessionStart" }

O teste automatizado é uma ótima maneira de garantir que seu site funcione em vários navegadores de forma consistente, sem o incômodo ou o custo de testar manualmente. As ferramentas que usamos aqui são apenas algumas das muitas opções disponíveis, mas ilustram as etapas comuns envolvidas na configuração e execução de testes automatizados para seus projetos.