Aprenda a implementar cucumber ao Cypress em testes automatizados

Diego Yuri - Dec 30 '23 - - Dev Community

Neste artigo, iremos explorar uma abordagem para implementar Cucumber com Cypress em projetos de automação de testes. Antes de iniciarmos, precisamos que se tenha instalado e configurado os seguites pré-requisitos

Após a instalação dos itens, Vamos confirmar que o Node foi configurado corretamente.
Abra o terminal e execute os comandos npm -v para verificar a versão do Node.js.

npm -v
Enter fullscreen mode Exit fullscreen mode

Se a versão for exibida corretamente, a configuração foi bem-sucedida.

Agora, criaremos uma pasta para o projeto e abriremos-a no Visual Studio Code. Após isso No terminal( CTRL + SHIFT + ' ) do VS Code, execute o comando:

npm init -y
Enter fullscreen mode Exit fullscreen mode

Isso criará o arquivo package.json na pasta. Em seguida, instalaremos o Cypress e o plugin do Cucumber:

npm install cypress --save-dev
npm install cypress-cucumber-preprocessor --save-dev
Enter fullscreen mode Exit fullscreen mode

Após a instalação, abra o Cypress para criar uma estrutura inicial do projeto:

npx cypress open
Enter fullscreen mode Exit fullscreen mode

No Cypress, clique em "E2E Testing", escolha um navegador (por exemplo, Electron), crie um novo arquivo de especificação e execute o teste de exemplo, feito isso podemos fechar o cypress.

Neste ponto, é fundamental entender a estrutura das pastas do projeto. Teremos duas pastas principais: Cypress e Node_Modules. Além disso, serão encontrados os seguintes arquivos essenciais: Cypress.config.js, package-lock.json e package.json.

Estrutura de Pastas

Para iniciar a configuração do Cucumber, acessaremos o arquivo Cypress.config.js, onde importaremos o plugin necessário. Na primeira linha do código, adicionaremos o seguinte comando:

const cucumber = require('cypress-cucumber-preprocessor').default;
Enter fullscreen mode Exit fullscreen mode

Feito isso, dentro deste mesmo arquivo, iremos adicionar a configuração do preprocessor dentro do Module.exports. Dentro da função setupNodeEvents, adicionaremos o seguinte comando:

on('file:preprocessor', cucumber())
Enter fullscreen mode Exit fullscreen mode

Assim, o código neste momento ficará assim:

const cucumber = require('cypress-cucumber-preprocessor').default;
const { defineConfig } = require("cypress");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('file:preprocessor', cucumber())

    },
  },
});
Enter fullscreen mode Exit fullscreen mode

Além disso, dentro do bloco e2e, adicionaremos a localização das features. Embora isso possa ser configurado conforme preferência, por padrão, manteremos as features dentro da própria pasta e2e. A configuração será da seguinte forma:

specPattern: "cypress/e2e/step_definitions/*.feature"
Enter fullscreen mode Exit fullscreen mode

Isso indica que nossos arquivos .feature estarão dentro da pasta STEP_DEFINITIONS na pasta e2e.

O arquivo final terá a seguinte aparência:

const cucumber = require('cypress-cucumber-preprocessor').default;
const { defineConfig } = require("cypress");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('file:preprocessor', cucumber())

    },
    specPattern: "cypress/e2e/step_definitions/*.feature"
  },
});
Enter fullscreen mode Exit fullscreen mode

Entretanto, neste momento, a pasta necessária ainda não foi criada no projeto. Dentro da pasta e2e, encontraremos apenas o arquivo exemplo que criamos anteriormente ao abrir o Cypress. Portanto, podemos acessar a pasta e2e, excluir o arquivo de exemplo (spec.cy.js), e dentro desta mesma pasta, criar a pasta step_definitions.

Essa organização é crucial para estruturar o projeto de forma clara, eliminando arquivos desnecessários e preparando o terreno para a inclusão das definições de passos do Cucumber.

Com a estrutura inicial ajustada, é hora de realizar as configurações necessárias no arquivo package.json. Isso é crucial para garantir que o Cucumber e o Cypress funcionem harmoniosamente. Adicione a seguinte configuração dentro do bloco

"cypress-cucumber-preprocessor": {
  "nonGlobalStepDefinitions": true,
  "stepDefinitions": "cypress/e2e/step_definitions"
}
Enter fullscreen mode Exit fullscreen mode

Explicando cada parte:

  • nonGlobalStepDefinitions: Este é um comando padrão do plugin e é essencial para o seu correto funcionamento.

  • "stepDefinitions": "cypress/e2e/step_definitions": Aqui, especificamos o caminho para a pasta que contém as definições de etapas dos nossos testes. No exemplo, estamos definindo que nossos arquivos .js de definição de etapas estão na própria pasta step_definitions.

A estrutura final do seu arquivo package.json pode se assemelhar a este exemplo:

{
  "name": "artigo1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "cypress": "^13.6.2",
    "cypress-cucumber-preprocessor": "^4.3.1"
  },
  "cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": true,
    "stepDefinitions": "cypress/e2e/step_definitions"
  }
}
Enter fullscreen mode Exit fullscreen mode

Essas configurações são cruciais para garantir que o ambiente esteja devidamente preparado para a integração do Cucumber com o Cypress, e que as definições de etapas estejam devidamente reconhecidas.

Neste ponto, todas as configurações essenciais foram realizadas para criar um ambiente de trabalho alinhado com o escopo do projeto. É importante destacar que seguimos uma abordagem específica para organizar nossos arquivos.

Na raiz da pasta STEP_DEFINITIONS, a prática será deixar nossos arquivos .feature. Mas a organização não para por aí. Dentro da pasta STEP_DEFINITIONS, criaremos uma pasta para cada feature. Isso significa que na raiz teremos o arquivo .feature correspondente, e dentro da pasta, teremos outros elementos relacionados a essa feature.

Este método de organização facilita a manutenção e compreensão do projeto, tornando a estrutura mais intuitiva. Afinal, um arquivo .feature na raiz representa a feature em si, enquanto a pasta com o nome da feature contém elementos adicionais relacionados a ela.

Essa abordagem flexível e intuitiva proporciona uma experiência mais clara e eficiente ao trabalhar com os testes e cenários definidos no projeto.

o nosso exemplo, o escopo do projeto se apresenta conforme a imagem abaixo:

Escopo do Projeto

Vale ressaltar que este tutorial não visa aprofundar-se no ensino detalhado das ferramentas, mas sim orientar sobre como implementar o Cucumber com Cypress. Inicialmente, abordaremos a utilização prática dessas ferramentas, proporcionando um entendimento gradual.

Vamos começar criando, na raiz da pasta step_definitions, o arquivo .feature para nosso projeto, nomeando-o como form.feature. A seguir, apresentarei um exemplo prático, delineando os passos do BDD (Behavior-Driven Development):

Feature: Form

Scenario: Valid Form
Given que o site seja acessado
When preencher o formulário
Then Valido o acesso
Enter fullscreen mode Exit fullscreen mode

Este cenário fictício representa a interação com um formulário em um site. Durante a execução dos testes, cada passo (Given, When, Then) será associado a ações específicas no código de automação.

O intuito é proporcionar uma visão inicial do funcionamento do BDD/Cucumber no projeto, partindo de um exemplo simples.

Após criar e configurar o arquivo .feature, avançaremos para a criação da estrutura de funções. Dentro da pasta step_definitions, criaremos uma subpasta chamada form. Dentro dessa subpasta, será criado o arquivo form.js.

Para cada feature testada, será necessário implementar/importar os códigos dos passos do Cucumber, como Given, When, Then. Portanto, adicionaremos o seguinte código nos arquivos .js:

import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps';
Enter fullscreen mode Exit fullscreen mode

Este trecho de código localiza o caminho configurado no cypress.config.js, acessando o diretório steps.

O arquivo .js ficará da seguinte forma:

import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps';

Given("que o site seja acessado", () => {
    cy.visit("https://vinothqaacademy.com/demo-site/");
    cy.title().should('eq', 'Demo Site – Registration Form – Vinoth Q.A Academy');
});

When("preencher o formulario", () => {
    cy.get('#vfb-5').type('Yuri');
    cy.get('#vfb-7').type('Lima');
    cy.get('#vfb-31-1').click();
    cy.get('#vfb-14').type('teste@teste.com');
    cy.get('#vfb-3').type('99');
    cy.get('#vfb-4').click();
});

Then("Valido acesso", () => {
    cy.title().should('eq', 'Demo Site – Dynamic Transaction – Vinoth Q.A Academy');
});
Enter fullscreen mode Exit fullscreen mode

Aqui, utilizamos Given, When e Then em vez do habitual it do Cypress, construindo assim nosso ambiente conforme necessário. No exemplo, o passo Given valida o acesso ao site, onde é visitado e confirmado pelo título. O passo When realiza o preenchimento do formulário, e, por fim, o passo Then valida a página seguinte, para onde é redirecionado após o envio do formulário.

Essa abordagem básica exemplifica o comportamento do BDD/Cucumber no projeto, destacando a naturalidade da linguagem de especificação.

Ressalta-se a necessidade do entendimento do BDD e Cucumber, onde a nomenclatura inicial após abrir a função (Given, When, Then) deve ser exatamente a mesma definida no arquivo .feature.

No nosso exemplo:

Given("que o site seja acessado", () => {
    cy.visit("https://vinothqaacademy.com/demo-site/");
    cy.title().should('eq', 'Demo Site – Registration Form – Vinoth Q.A Academy');
});
Enter fullscreen mode Exit fullscreen mode

A frase "que o site seja acessado" deve ser estritamente idêntica à linha "Given que o site seja acessado" contida no arquivo .feature. Qualquer divergência nesses pontos resultará na falha da execução do teste.

Na imagem a seguir, podemos visualizar a execução do teste.

Espero que tenham apreciado o conteúdo e que seja produtivo para vocês. Para qualquer assistência adicional, estou à disposição.

Teste Executado

Gif do Teste em Ação

Obrigado!

. . . . .