O que você vai aprender:
- O que são novas tentativas de teste?
- Por que as novas tentativas de teste são importantes?
- Como configurar novas tentativas de teste
Os testes ponta a ponta (E2E) são excelentes para testar sistemas complexos. No entanto, ainda existem comportamentos que são difíceis de verificar e tornam os testes instáveis (ou seja, não confiáveis) e às vezes falham devido a condições imprevisíveis (por exemplo, interrupções temporárias em dependências externas, erros de rede aleatórios, etc.). Algumas outras condições de corrida comuns que podem resultar em testes não confiáveis incluem:
- Animações
- Chamadas de API
- Teste de disponibilidade do servidor / banco de dados
- Disponibilidade de dependências de recursos
- Problemas de rede
Com novas tentativas de teste, o Cypress é capaz de repetir os testes que falharam para ajudar a reduzir a fragilidade do teste e as falhas de construção de integração contínua (CI). Ao fazer isso, você economizará tempo e recursos valiosos para que você possa se concentrar no que é mais importante para você.
Por padrão, os testes não serão repetidos quando falharem. Você precisará habilitar novas tentativas de teste em sua configuração para usar este recurso.
Depois que as novas tentativas de teste são habilitadas, os testes podem ser configurados para ter um número X de tentativas de repetição. Por exemplo, se as novas tentativas de teste foram configuradas com 2 novas tentativas, o Cypress tentará novamente os testes até 2 vezes adicionais (para um total de 3 tentativas) antes de ser potencialmente marcado como um teste com falha.
Quando cada teste é executado novamente, os seguintes ganchos também serão executados novamente:
beforeEach
afterEach
No entanto, as falhas em
after
ebefore
hooks não dispararão uma nova tentativa.
Supondo que configuramos novas tentativas de teste com 2
tentativas (para um total de 3 tentativas), aqui está como os
testes podem ser executados:
-
Um teste é executado pela primeira vez. Se o teste passar, o Cypress seguirá em frente com todos os testes restantes, como de costume.
-
Se o teste falhar, o Cypress informará que a primeira tentativa falhou e tentará executar o teste uma segunda vez.
-
Se o teste for aprovado após a segunda tentativa, o Cypress continuará com os testes restantes.
-
Se o teste falhar uma segunda vez, o Cypress fará a terceira tentativa final para executar o teste novamente.
-
Se o teste falhar pela terceira vez, o Cypress marcará o teste como reprovado e, em seguida, executará os testes restantes.
A seguir está uma captura de tela de como as novas tentativas de teste se parecem no mesmo teste com falha quando executado através do cypress run.
Durante o cypress open, você poderá ver o número de tentativas feitas no Log de comandos e expandir cada tentativa para revisão e depuração, se desejar.
Normalmente, você desejará definir diferentes tentativas de repetição para a execução do Cypress e a abertura do
Cypress. Você pode configurar isso em seu
arquivo de configuração
(cypress.json
por padrão), passando a opção de retries
em um objeto com as seguintes opções:
-
runMode
permite-lhe definir o número de tentativas de teste ao executar ocypress run
-
openMode
permite-lhe definir o número de tentativas de teste ao executar ocypress open
{
"retries": {
// Configurar novas tentativas para `cypress run`
// Padrão é 0
"runMode": 2,
// Configurar novas tentativas para `cypress open`
// Padrão é 0
"openMode": 0
}
}
Se você deseja configurar as tentativas de repetição para todos os testes executados no cypress run
e no
cypress open
, você pode configurar isso em seu
arquivo de configuração
(cypress.json
por padrão) definindo a
propriedade retries
e configurando o número de tentativas desejado.
{
"retries": 1
}
Se quiser configurar novas tentativas em um teste específico, você pode definir isso usando a configuração de teste
// Personalize novas tentativas para um teste individual
describe('User sign-up and login', () => {
// bloco de teste `it` sem configuração personalizada
it('should redirect unauthenticated user to sign-in page', () => {
// ...
})
// bloco de teste `it` com configuração personalizada
it(
'allows user to login',
{
retries: {
runMode: 2,
openMode: 1,
},
},
() => {
// ...
}
)
})
Se quiser configurar tentativas de tentativa para um conjunto de testes, você pode fazer isso definindo a configuração do conjunto.
// Personalização de novas tentativas para um conjunto de testes
describe('User bank accounts', {
retries: {
runMode: 2,
openMode: 1,
}
}, () => {
// A configuração por suíte é aplicada a cada teste
// Se um teste falhar, ele será repetido
it('allows a user to view their transactions', () => {
// ...
})
it('allows a user to edit their transactions', () => {
// ...
})
})
Você pode encontrar mais informações sobre configurações personalizadas aqui: Configuração de teste
Quando um teste é repetido, o Cypress continuará a fazer capturas de tela para cada tentativa falhada ou
cy.screenshot() com sufixo a nova captura de tela com (attempt n)
,
correspondendo ao número da tentativa de repetição atual.
Com o seguinte código de teste, você veria os nomes de arquivo de captura de tela abaixo quando todas as 3 tentativas falhassem:
describe('User Login', () => {
it('displays login errors', () => {
cy.visit('/')
cy.screenshot('user-login-errors')
// ...
})
})
// nome do arquivo de captura de tela de cy.screenshot() na primeira tentativa
'user-login-errors.png'
// nome do arquivo de captura de tela na primeira tentativa falhada
'user-login-errors (failed).png'
// nome do arquivo de captura de tela de cy.screenshot() na 2ª tentativa
'user-login-errors (attempt 2).png'
// nome do arquivo de captura de tela na segunda tentativa falhada
'user-login-errors (failed) (attempt 2).png'
// nome do arquivo de captura de tela de cy.screenshot() na terceira tentativa
'user-login-errors (attempt 3).png'
// nome do arquivo de captura de tela na terceira tentativa falhada
'user-login-errors (failed) (attempt 3).png'
Você pode usar o listener de evento after:spec
do Cypress que dispara após cada arquivo de especificação ser
executado para excluir o vídeo gravado para especificações que não tiveram novas tentativas ou falhas. A exclusão de
vídeos aprovados e não repetidos após a execução pode economizar espaço de recursos na máquina e também ignorar o tempo
usado para processar, compactar e enviar o vídeo para o Serviço de Dashboard.
O exemplo abaixo mostra como excluir o vídeo gravado para especificações que não tiveram novas tentativas ou falhas ao usar novas tentativas de teste Cypress.
// plugins/index.js
// precisa instalar essas dependências
// npm i lodash del --save-dev
const _ = require('lodash')
const del = require('del')
module.exports = (on, config) => {
on('after:spec', (spec, results) => {
if (results && results.video) {
// Temos falhas para qualquer tentativa de repetição?
const failures = _.some(results.tests, (test) => {
return _.some(test.attempts, { state: 'failed' })
})
if (!failures) {
// exclua o vídeo se a especificação for aprovada e nenhum teste for repetido
return del(results.video)
}
}
})
}
Se você estiver usando o Cypress Dashboard, as informações relacionadas às novas tentativas de teste serão exibidas na guia 'Test Results' para uma execução. Selecionar o filtro 'Flaky' mostrará os testes que foram repetidos e foram aprovados durante a execução.
Esses testes também são indicados com um emblema "Flaky" na página 'Latest Runs' e na guia 'Test Results na página 'Run Details'.
Video com exemplo de um teste com o filtro 'flaky'
Clicar em um 'Test Result' abrirá a tela 'Test Case History'. Isso demonstra o número de tentativas malsucedidas, as capturas de tela e/ou vídeos das tentativas malsucedidas e o erro das tentativas malsucedidas.
Você também pode ver a 'Flaky Rate' (taxa de instabilidade) para um determinado teste.
Para uma visão abrangente de como o floco está afetando seu conjunto de testes geral, você pode revisar os recursos de Flake Detection e Flake Alerting destacados em 'Test Flake Management Guide'.
Não. Os testes gravados durante o cypress run
com o sinalizador --record
serão contados da mesma forma com ou sem
novas tentativas de teste.
Consideramos cada vez que a função it()
é chamada um único teste para fins de faturamento. A repetição do teste não
contará como resultados de teste extras em seu faturamento.
Você sempre pode ver quantos testes você registrou na página 'Billing & Usage ' da sua organização no Dashboard.
Sim, embora normalmente você não precise, pois este é um detalhe de baixo nível. Mas se quiser usar o número da tentativa atual e o total de tentativas permitidas, você pode fazer o seguinte:
it('does something differently on retry', { retries: 3 }, () => {
// cy.state('runnable') retorna o objeto de teste atual
// podemos pegar a tentativa atual e
// o total de tentativas permitidas de suas propriedades
const attempt = cy.state('runnable')._currentRetry
const retries = cy.state('runnable')._retries
// use os valores "attempt" e "retries" de alguma forma
})
A variável de attempt
acima terá valores de 0 a 3 (a primeira execução de teste padrão mais três tentativas permitidas).
A constante de novas tentativas neste caso é sempre 3.
Dica: Cypress agrupa a biblioteca Lodash. Use seus métodos auxiliares para acessar com segurança uma propriedade de um objeto. Vamos nos certificar de que a função oferece suporte a diferentes versões do Cypress voltando aos valores padrão.
it('does something differently on retry', { retries: 3 }, () => {
// _.get: se o objeto ou propriedade estiver faltando use o valor padrão fornecido
const attempt = Cypress._.get(cy.state('runnable'), '_currentRetry', 0)
const retries = Cypress._.get(cy.state('runnable'), '_retries', 0)
// use os valores "attempt" e "retries" de alguma forma
})