Aprenda a implementar cucumber ao Cypress em testes automatizados
Diego Yuri
Posted on December 30, 2023
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
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
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
Após a instalação, abra o Cypress para criar uma estrutura inicial do projeto:
npx cypress open
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
.
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;
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())
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())
},
},
});
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"
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"
},
});
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"
}
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 pastastep_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"
}
}
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:
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
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';
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');
});
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');
});
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.
Obrigado!
Posted on December 30, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.