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!
Top comments (1)
Parabéns, Diego! Ótimo conteúdo.