Blog > Qualidade > Testes automatizados com Cypress e Cucumber

Testes automatizados com Cypress e Cucumber

26/10/2020
  • 9 min. de leitura
  • Recentemente tive a oportunidade de começar a automatizar os testes do meu projeto utilizando Cypress com Cucumber. Por tal motivo, decidi fazer este tutorial explicando como você pode iniciar a automatização de seus testes.

    Abaixo você encontrará como configurar o ambiente, os principais comandos, a estruturação do projeto, um exemplo prático de utilização e alguns links úteis. Utilizaremos Cypress com Cucumber e seguiremos o conceito de page objects.

    Além disso, caso você não queira configurar todo o ambiente, pode utilizar este repositório como base para iniciar. Nele encontram-se diversos exemplos de utilização e comandos.

    Contextualizando

    O que é Cypress:

    Cypress é um framework utilizado para automação de testes end to end. Atualmente, utiliza JavaScript como linguagem de programação e executa os testes no Chrome.

    Suas principais vantagens são de possuir uma curva de aprendizado pequena e ser de fácil instalação e configuração. Em contrapartida, possui limitações por utilizar somente o Chrome como browser e não trocar de janela durante os testes.

    O que é Cucumber:

    Cucumber é uma ferramenta que pode ser utilizada em conjunto com o Cypress e permite a escrita de testes automatizados no formato BDD (Behaviour-Driven Development). É possível utilizar o Cypress sem cucumber, mas não é o foco deste tutorial.

    Exemplo de uso da ferramenta Cucumber. Disponível no site da própria ferramenta.

    Configurando o Ambiente

    Não é necessário muito esforço para preparar sua máquina, apenas temos que cumprir quatro etapas:

    1. Instalar Node.js: acesse o site oficial, baixe e instale a versão para seu computador.

    2. Escolher uma IDE de JavaScript para programar: usaremos o VS Code neste tutorial.

    3. Instalar o Cypress com Cucumber:

    I) Crie uma pasta onde ficarão os arquivos do seu projeto. Abra o terminal do windows e acesse essa mesma pasta com o seguinte comando:

    cd /your/project/path

    II) Tendo acessado a pasta do projeto, execute o comando de instalação:

    npm install --save-dev cypress cypress-cucumber-preprocessor

    III) Ainda dentro da pasta do seu projeto, execute o seguinte comando para que o Cypress termine de criar os arquivos locais:

    npx cypress open

    4. Configurar o Cucumber no Cypress:

    Adicione ao arquivo cypress/plugins/index.js o seguinte script:

    const cucumber = require('cypress-cucumber-preprocessor').default
    module.exports = (on, config) => {
      on('file:preprocessor', cucumber())
    }

    Entendendo os principais comandos do Cypress

    O funcionamento do Cypress é baseado em localizar elementos do site (botões, inputs, textos, imagens, etc.) e interagir com os mesmos. Podemos automatizar todas as ações que executamos manualmente ao utilizar a página web (e mais algumas).

    O Cypress possui uma boa documentação com todos os seus comandos. Abaixo vamos ver os principais para iniciar.

    GET:

    Sintaxe: cy.get(‘seletor’)

    Este comando é responsável por selecionar o elemento da tela no qual executamos uma ação. Funcionamento semelhante ao de levar o cursor do mouse em cima do que queremos.

    cy.get('#idDoElemento') // seleciona elemento por seu id
    cy.get('.class') // seleciona elemento por sua classe 
    cy.get('[atributo="doElemento"]') // seleciona elemento por seu atributo

    Para entender melhor como capturar seletores de elementos, você pode acessar um bom tutorial neste link.

    CLICK:

    Sintaxe: .click()

    O comando click é utilizado para realizar a ação de clicar em um elemento da página e, para isso, deve ser utilizado em conjunto com o comando GET ou outro comando de mesma função. Funcionamento semelhante ao de clicar com o botão esquerdo do mouse no elemento que queremos.

    cy.get('#idDoElemento').click() //clique simples
    cy.get('.class').click({ force: true }) //força o clique mesmo em elementos que estejam invisíveis
    cy.get('button').click({ multiple: true }) //clica em todos os elementos que forem selecionados

    TYPE:

    Sintaxe: .type(‘texto’)

    Type é utilizado para setar informações em campos. Funcionamento semelhante ao de digitarmos com nosso teclado.

    cy.get('#input-email').type('gabriel.fer@gmail.com') // insere 'gabriel.fer@gmail.com' no campo do elemento selecionado
    cy.get('.senha-class').type('123456') // insere '123456' no campo do elemento selecionado

    VISIT:

    Sintaxe: cy.visit(‘http://dev-testqa.com’)

    O comando visit é utilizado para acessar endereços virtuais. Com ele acessamos o site em que iremos realizar os testes.

    cy.visit('http://localhost:8000') // acessa local informado
    cy.visit('https://dev-qa.com') // acessa site informado
    cy.visit('url, { timeout: 30000 }') // acessa site configurado no arquivo cypress.json e configura timeout de 30 segundos

    SHOULD:

    Sintaxe: .should(‘configurações’)

    Should é um comando utilizado para fazer asserções na página. Este é normalmente o último comando a ser utilizado no cenário e serve para validar se o teste passou ou reprovou.

    cy.get('.class').should('contain', 'Texto esperado') // Verifica se o elemento selecionado contém o texto que é esperado.
    cy.get('#id-name').should('be.visible') // Verifica se o elemento está visível na página.
    cy.get('div').should('not.be.empty') // Verifica se o elemento não está vazio.

    Estruturando o projeto

    O Cypress pode ser utilizado sem Cucumber com uma estrutura simples explicada na documentação do mesmo. Neste tutorial veremos como estruturar utilizando a ferramenta de escrita de testes em BDD. Para isso, temos que conhecer as principais pastas e arquivos iniciais do projeto:

    Estrutura inicial

    A pasta ‘fixtures’ e os arquivos ‘commands.js’‘index,js’ e package-lock.json’ oferecem configurações avançadas que não serão abordadas neste tutorial.

    1. integration: nesta pasta colocamos os nossos arquivos com os cenários de teste escritos no formato BDD.
    2. plugin/index.js: este arquivo é destinado para configuração de plugins. Utilizamos ele ao configurar o Cucumber.
    3. support: dentro desta pasta colocamos os steps, os scripts e o mapeamento de elementos de nossos testes.
    4. node_modules: aqui ficam os arquivos de funcionamento do Cypress e do Cucumber. Normalmente não precisamos mexer nesta pasta.
    5. cypress.json: neste arquivo podemos realizar configurações globais do nosso projeto. Ex.: criar variáveis globais, definir resolução do navegador, setar uma URL padrão, entre outros.

    Criando algumas pastas e arquivos adicionais:

    Para iniciar a estrutura do projeto, precisamos criar três pastas em cypress/support, pois iremos utilizar o conceito de page object. São elas: elements, pageobjects e steps.

    Pastas criadas dentro de cypress/support
    1. steps: nesta pasta colocamos os passos que farão a conexão entre o que escrevemos em BDD e os scripts que fazemos em Cypress.
    2. pageobjects: aqui deixamos os scripts feitos em Cypress.
      A ideia do page objects é a de criarmos um arquivo.js para cada página ou fluxo do site. Dessa forma, mantemos a organização e facilitamos a manutenção do código, pois colocamos no arquivo os comandos que são executados na página/fluxo correspondentes ao nome do arquivo.
      Ex.: HomePage.js, PdpPage.js, Checkout.js.
    3. elements: possui o mesmo conceito do page objects, mas aqui colocamos os elementos da página. Tal organização permite que elementos sejam reutilizados e tenham fácil manutenção.
      Ex.: HomeElements.js, PdpElements.js, CheckoutElements.js.

    Além disso, pelo próprio VS Code, precisamos criar um arquivo na pasta raíz do projeto com o nome e formato package.json, conforme a imagem abaixo:

    Arquivo package.json

    Adicione o seguinte código no arquivo package.json:

    {
        "scripts": {
            "test:chrome": "cypress run --browser chrome --no-exit"
        },
        "cypress-cucumber-preprocessor": {
            "step_definitions": "cypress/support/steps"
        }
    }

    Os scripts são facilitadores para executarmos o teste via terminal. Já a configuração de step_definitons permite definir o local do projeto onde estarão os steps de nosso cenário.

    Exemplo de utilização

    Com o ambiente configurado e o projeto estruturado, faremos agora um exemplo prático de automatização de testes.

    Objetivo: automatizar o processo de testar o login do site da CWI Software.

    Passo 1: configurar o arquivo cypress.json. Você pode copiar o código abaixo para seu arquivo e personalizar com as configurações para seu projeto. Abaixo configuramos para nosso teste de exemplo.

    {
        "viewportWidth": 1024,
        "viewportHeight": 768,
        "defaultCommandTimeout": 10000,
        "baseUrl": "https://cwi.com.br/"
    }
    Passo 1
    1. ViewportWidth e viewportHeight permitem configurar a resolução do navegador em que nossos testes serão executados.
    2. DefaultCommandTimeout define um dos tipos de timeout para 10 segundos.
    3. BaseUrl é onde configuramos a url padrão de nossos testes.
    4. Local onde está o arquivo cypress.json.

    Várias configurações podem ser feitas em cypress.json. Confira na documentação as possibilidades.

    Passo 2: criar um arquivo com o cenário de teste escrito em BDD. Ele deve ficar dentro de cypress/integration e ter a extensão .feature.

    Feature: Login site CWI
    
        Scenario: Visualizar opção de recuperar senha esquecida
            Given acesso o site CWI
            When acesso a pagina de login
            Then devo visualizar botao de recuperar senha esquecida
    Passo 2
    1. Nome da suíte de testes.
    2. Nome do cenário de teste.
    3. Given é o equivalente ao “Dado que” do BDD.
    4. When é o equivalente ao “Quando” do BDD.
    5. Then é o equivalente ao “Então” do BDD.
    6. Arquivo com nome da suíte e formato .feature dentro de cypress/integration.

    Neste arquivo podemos criar vários cenários de testes. Além disso, podemos ter quantos arquivos .features com cenários forem necessários. Normalmente separamos por fluxos ou testes e nomeamos esses arquivos conforme seus respectivo conteúdo.

    Passo 3: criar um arquivo com os passos do teste. Ele deve ter formato .js e ficar dentro de cypress/support/steps. Criamos um arquivo de steps para cada arquivo de feature que temos e utilizamos o mesmo nome nos dois, apenas acrescentando “Steps”.

    /* global Given, Then, When */
    
    import LoginPage from '../pageobjects/LoginPage'
    const loginPage = new LoginPage
    
    Given("acesso o site CWI", () => {
        loginPage.acessarSite();
    })
    
    When("acesso a pagina de login", () => {
        loginPage.clicarBotaoPaginaLogin();
    })
    
    Then("devo visualizar botao de recuperar senha esquecida", () => {
        loginPage.visualizarBotaoRecuperarSenha();
    })
    Passo 3
    1. Configuração para importar globalmente os passos que escrevemos nos arquivos .feature.
    2. Comando para importar o arquivo LoginPage.js que criaremos no próximo passo.
    3. Cria uma constante para que utilizemos as funções que serão criadas no arquivo LoginPage.js.
    4. Função que associa o nosso passo escrito em BDD com a função que deve executar.
    5. Função com nossos comandos que será criada dentro do arquivo LoginPage.js.
    6. Passo que escrevemos em BDD no arquivo Login.feature. Deve ser exatamente igual ao que foi digitado.
    7. Arquivo criado no formato .js dentro da pasta cypress/support/steps.

    Passo 4: criar um arquivo com as funções e comandos que executaremos. Deve ter formato .js e ficar dentro de cypress/support/pageobjects.

    /// <reference types="Cypress" />
    
    import LoginElements from '../elements/LoginElements'
    const loginElements = new LoginElements
    const url = Cypress.config("baseUrl")
    
    class LoginPage {
        // Acessa o site que será testado
        acessarSite() {
            cy.visit(url)
        }
    
        // Clica no botão que acessa a página de login do site
        clicarBotaoPaginaLogin() {
            cy.get(loginElements.botaoLogin()).click()
        }
      
        // Verifica se o botão tem o texto "Esqueceu sua senha?"
        visualizarBotaoRecuperarSenha() {
            cy.get(loginElements.botaoRecuperarSenha()).should('contain', 'Esqueceu sua senha?')
        }
    }
    
    export default LoginPage;
    Passo 4
    1. Comando especial para VS Code. Exibe sugestões de complemento de comandos do Cypress enquanto digitamos.
    2. Comando para importar o arquivo LoginElements.js que criaremos no próximo passo.
    3. Cria uma constante para que utilizemos as funções que serão criadas no arquivo LoginElements.js.
    4. Cria uma constante que recebe a URL colocada no arquivo cypress.json.
    5. Comando Cypress que permite trazer valores configurados no arquivo cypress.json.
    6. Função que foi chamada no arquivo anterior e executa nossos comandos.
    7. Comando Cypress que acessa um site.
    8. URL que será acessada pelo comando visit.
    9. Comando Cypress que seleciona o elemento da página que será utilizado.
    10. Função que retorna o seletor do elemento da página. Será criada no próximo passo.
    11. Comando Cypress que realiza a ação de clicar em um elemento.
    12. Comando Cypress que realiza uma verificação. Neste caso utilizamos a opção ‘contain’ que analisa se o elemento contém um texto.
    13. Texto que deve estar contido no elemento analisado.
    14. Arquivo criado no formato .js dentro da pasta cypress/support/pageobjects.
    15. Comando para exportar a LoginPage.js e possibilitar sua importação no arquivo LoginSteps.js.

    Passo 5: criar o arquivo no qual faremos a listagem dos elementos da página. Deve ter formato .js e ficar dentro de cypress/support/elements.

    class LoginElements {
        botaoLogin = () => { return '.main-header-login-content .title' }
    
        botaoRecuperarSenha = () => { return '.forgot' }
    }
    
    export default LoginElements;
    Passo 5
    1. Função que retorna para a LoginPage.js o seletor do elemento que será utilizado.
    2. Seletor do elemento do botão de recuperar senha. Nesse caso utilizamos a class forgot. Para entender melhor como pegar os seletores, volte para a explicação do comando GET.
    3. Comando para exportar a LoginElements.js e possibilitar sua importação no arquivo LoginPage.js.
    4. Arquivo criado no formato .js dentro da pasta cypress/support/elements.

    Passo 6: executar o teste. Após ter salvo todos os arquivos, execute pelo terminal do próprio VS Code o comando abaixo que configuramos no arquivo package.json:

    npm run test:chrome

    Você também pode executar o comando completo:

    npx cypress run --browser chrome --no-exit

    Feito isso, o chrome será aberto e poderemos acompanhar a execução do teste. Teremos o seguinte resultado:

    1. Exibe a quantidade de testes executados com sucesso.
    2. Exibe a quantidade de testes que falharam.
    3. Executa novamente todos os testes.
    4. Abre o seletor de elementos do Cypress.
    5. Resumo dos passos executados no teste.
    6. Botão de login que clicamos ao acessar o site.
    7. Botão de recuperar senha que verificamos se continha o texto “Esqueceu sua senha?”.

    Outras configurações podem ser feitas a partir do comando digitado para executar o teste. Acesse a documentação para visualizar as opções.

    Conclusão

    O que foi exposto acima é o básico para iniciar os testes automatizados com Cypress. Entretanto, muitas outras funcionalidades são possíveis, como, por exemplo, o uso de tags, a criação de cenários com exemplos e o teste de APIs.

    Cypress continua sendo desenvolvido e futuramente possibilitará testes em outros navegadores além do Chrome. Aprofunde seus estudos e aprimore cada vez mais os seus testes.


    Referências:

    Site oficial Cypress

    Documentação Cypress

    Site oficial do Cucumber

    Repositório do Cucumber para Cypress

    Tutorial de seletores CSS

    Repositório com projeto Cypress + Cucumber base

    Gostou? 6
    Compartilhe esse post: