Fixtures randômicas? Sim, é possível!
Este é um conteúdo da série “Pitadas de Cypress“.
Um dia desses, no grupo Cypress-BR no Telegram, surgiu a seguinte pergunta:
Tem como colocar faker no json?
A resposta é não.
Mas é possível criar um arquivo .json dinamicamente, com o uso da funcionalidade cy.writeFile, e com ajuda do faker, tornar todos os dados deste arquivo dinâmicos também.
Vejamos um exemplo, criando uma fixture para uso em um teste que faz o mock do backend e testa o frontend de forma isolada.
A aplicação em teste é a Hacker Stories.
Esta aplicação se comunica com a API pública do Hackernews para a listagem das histórias.
Porém, conforme comentado anteriormente, faremos o mock desta API.
O arquivo de testes é o seguinte.
describe('Hacker Stories', () => {
beforeEach(() => {
cy.generateFixture()
cy.intercept(
'GET',
'**/search?query=React&page=0',
{ fixture: 'stories' }
).as('getStories')
cy.visit('/')
cy.wait('@getStories')
})
it('renders 20 stories, then 19 when dismissing one', () => {
cy.get('.item').should('have.length', 20)
cy.get('.button-small').first().click()
cy.get('.item').should('have.length', 19)
})
})
Veja que no hook beforeEach há um comando customizado chamado generateFixture(). Veremos o que este comando faz logo mais.
Perceba também que estamos interceptando uma requisição, a qual iremos responder com uma fixture chamada stories.
Depois, visitamos a página da aplicação em teste, aguardamos por tal requisição mockada acontecer e o teste propriamente dito é executado, o qual verifica que existem 20 itens na lista e que ao remover o primeiro sobram 19.
Você deve estar curioso(a) sobre a implementação do comando generateFixture(), certo?
Aí vai ele.
Cypress.Commands.add('generateFixture', () => {
const faker = require('@faker-js/faker')
cy.writeFile('cypress/fixtures/stories.json', {
'hits':Cypress._.times(20, () => {
return {
'title':`${faker.lorem.words(3)}`,
'url':`${faker.internet.url()}`,
'author':`${faker.name.firstName()} ${faker.name.lastName()}`,
'num_comments':`${faker.datatype.number()}`,
'points':`${faker.datatype.number()}`,
'objectID':`${faker.datatype.uuid()}`,
}
})
})
})
Para os dados aleatórios, importamos o faker ao comando, com o uso da função require do JavaScript.
Daí, fazemos uso do cy.writeFile, para escrever um arquivo chamado stories.json no diretório cypress/fixtures/. Como segundo argumento, passamos um objeto, o qual conterá o valor de tal arquivo.
Tal objeto terá uma propriedade hits, que é exatamente o que o frontend espera, e tal propriedade espera um array de objetos.
Para este array, fazemos uso da funcionalidade .times do lodash (o qual é empacotado junto com o Cypress), visto que ela retorna exatamente um array.
Então a função .times executa 20 vezes, para criar 20 histórias (stories) aleatórias, cada uma com seu título (title), url (url), autor (author), número de comentários (num_comments), pontuação (points) e ID do objeto (objectID), utilizando diferentes funcionalidades oferecidas pela biblioteca faker.
Para um exemplo da fixture criada, acesse este arquivo.
Obs.: Visto que tal fixture é dinâmica, devemos adicioná-la ao arquivo .gitignore, pois não queremos versioná-la.
E assim, temos um teste que consome uma fixture criada dinamicamente, com dados aleatórios. 🥳
Ou seja, para cada execução, a fixture será sobrescrita com novos dados.
Te convido a baixar o projeto em seu computador, instalar as dependências seguindo a documentação, e então rodar os testes (tanto em modo interativo, como em modo headless).
Acesse o projeto completo no GitHub.
Aproveita pra deixar uma ⭐.
Fiz um vídeo com base nesta publicação, onde fui um pouco além, mostrando como alternativa, a intercepção da requisição sobrescrevendo o body da resposta, sem a necessidade de fixtures. Assista aqui!
Gostou do conteúdo? Deixa um comentário!
Ficou curioso e quer aprender mais sobre automação de testes com Cypress? Conheça meus cursos no Udemy.
- Cypress básico
- Cypress intermediário
- Cypress avançado
- Boas práticas em automação de testes com Cypress
- Testes end-to-end com Cypress
- Testes de regressão visual com Cypress e Percy (básico)
👋 Até a próxima e bons testes!
Este conteúdo foi traduzido para inglês e pode ser encontrado no DEV Community.
Boa dica senhor. 😉
Fico feliz que gostou Richard!
Boa tarde, muito bom o artigo.
Eu fiquei com uma duvida.
Caso eu precise fazer um intercept em um método que não é chamado pelo frontend, como pode ser feito?
Por exemplo: Eu tenho uma tela de consulta, e nessa tela eu quero que apareça um registro especifico (intercept em um POST). Só que esse POST em nenhum momento é realizado, e quero apenas usar para o teste, não quero “sujar” o banco de dados com valores aleatórios ou incorretos.
Qual seria a sua abordagem?
Oi Luiz, não entendi bem tua necessidade. Poderia explicar melhor, por favor?
Pois não há como aguardar por uma requisição que nunca vai ocorrer.