Skip to content

Latest commit

 

History

History
581 lines (399 loc) · 24.4 KB

writing-your-first-test.md

File metadata and controls

581 lines (399 loc) · 24.4 KB

Escrevendo o Primeiro Teste

O que você vai aprender

- Como começar a testar um novo projeto com Cypress
- Como são reportados testes com sucesso e falhas
- Testando a navegação web, buscando por elementos no DOM e escrevendo asserções

Vídeo de exemplo.

Adicione um arquivo de teste

Assumindo que você tenha instalado e aberto o Cypress Test Runner, chegou a hora de escrever o primeiro teste. Vamos então:

  1. Criar um arquivo sample_spec.js.
  2. Checar que o Cypress atualizou a lista de arquivos de teste.
  3. Executar o Cypress Test Runner.

Vamos criar um novo arquivo na pasta cypress/integration, a qual já foi criada:

touch {your_project}/cypress/integration/sample_spec.js

Uma vez que o arquivo tenha sido criado, o Cypress Test Runner deve exibi-lo na lista de testes de integração. O Cypress monitora mudanças em seus arquivos de teste e os exibe imediatamente.

Mesmo que ainda não tenha escrito nenhum teste - tudo bem - clique em sample_spec.js e veja o Cypress iniciar o navegador.

O Cypress abre o teste em um navegador previamente instalado em seu sistema operacional. Você pode ler mais sobre como isso é feito em Iniciando Navegadores.

Vídeo de exemplo

Agora estamos oficialmente no Test Runner. É nele onde vamos gastar a maioria do tempo testando.

Note que o Cypress exibe a mensagem que não pode encontrar nenhum teste. Isso é normal - testes ainda não foram escritos! Você verá essa mensagem também caso exista algum erro ao analisar os arquivos de teste. Você pode abrir o Dev Tools para inspecionar o console e buscar por erros de sintaxe que impediu o Cypress de ler seus arquivos de testes.

Escreva seu primeiro teste

Chegou a hora de escrever o nosso primeiro teste. Vamos então:

  1. Escrever nosso primeiro teste com sucesso.
  2. Escrever nosso primeiro teste com falha.
  3. Ver o Cypress recarregar o teste em tempo real.

A medida que salvamos nosso novo teste, veremos que o navegador recarrega automaticamente em tempo real.

Abra sua IDE favorita e adicione o código abaixo no arquivo de teste sample_spec.js.

describe('My First Test', () => {
  it('Does not do much!', () => {
    expect(true).to.equal(true)
  })
})

Quando salvar esse arquivo você deve ver o navegador recarregar.

Embora não faça nada, esse é nosso primeiro teste com sucesso!

No log de comandos você vai ver que o Cypress exibe a suíte de teste, o teste e a primeira asserção (que deve estar em verde - sucesso).

Primeiro teste com sucesso

Observe que o Cypress exibe uma mensagem sobre essa ser a página padrão à direita. Cypress assume que você irá sair e visitar outra página na internet - mas também pode funcionar bem sem isso.

Agora vamos escrever nosso primeiro teste com falha.

describe('My First Test', () => {
  it('Does not do much!', () => {
    expect(true).to.equal(false)
  })
})

Quando você salvar, poderá observar que o Cypress exibe o teste com falha em vermelho, uma vez que true não é igual a false.

Cypress também exibe o log do erro e o pedaço do código onde a asserção falhou (quando disponível). Você pode clicar no link do arquivo em azul para abrir o arquivo em que o erro ocorreu em sua IDE. Para ler mais sobre exibição de erros, leia sobre Debugando Erros.

Teste com falha

Cypress fornece um ótimo Test Runner que exibe uma estrutura visual das suítes, testes e asserções. Em breve você verá também comandos, eventos, requisições de rede e mais.

Vídeo do primeiro teste com falha

O que é describe, it e expect? Todas essas funções vem das Bundled Tools que fazem parte do Cypress. Describe e it vem do Mocha. Expect vem do Chai.

Cypress utiliza dessas ferramentas e frameworks populares, os quais é esperado que você já tenha alguma familiaridade e conhecimento prévio. Mas se não tiver, tudo bem.

Escreva um teste real

Um teste sólido geralmente cobre 3 fases:

  1. Configurar o estado da aplicação
  2. Realizar uma ação
  3. Fazer uma asserção sobre o resultado da ação

Também conhecido pela tríade "Given, When, Then", ou "Arrange, Act, Assert". Mas a ideia é: primeiro a aplicação é colocada em um estado específico, então uma ação é realizada na aplicação, o que causa uma mudança, e finalmente o resultado da apicação é checado.

Hoje, vamos ver esses passos de perto e mapeá-los claramente em comandos do Cypress:

  1. Visitar uma página web.
  2. Consultar um elemento.
  3. Interagir com o elemento.
  4. Verificar o conteúdo da página.

Passo 1: Visitar uma página web

Primeiro, vamos visitar uma página web. Neste exemplo vamos usar a aplicação Kitchen Sink para que você possa experimentar o Cypress sem se preocupar em procurar uma página para testar.

Podemos passar a URL que queremos visitar para o cy.visit(). Vamos substituir nosso teste anterior pelo teste abaixo que de fato visita uma página:

describe('My First Test', () => {
  it('Visits the Kitchen Sink', () => {
    cy.visit('https://example.cypress.io')
  })
})

Salve o arquivo e retorne ao Cypress Test Runner. Você vai perceber algumas coisas:

  1. O Log de Comandos agora exibe a nova ação visit.
  2. A aplicação Kitchen Sink foi carregada no painel de pré visualização da aplicação.
  3. O teste está verde, mesmo não tendo nenhuma asserção.
  4. O visit exibe um estado pendente em azul até que a página termine de carregar.

Se essa solicitação tivesse retornado com um código de status diferente de 2xx, como 404 ou 500, ou se houvesse um erro de JavaScript no código do aplicativo, o teste teria falhado.

Vídeo de exemplo.

Teste apenas aplicações que você controla

Embora neste guia estamos testando nossa aplicação exemplo, você não deve testar aplicações que você 
não controla. Por quê?

1. São passíveis de mudanças a qualquer momento, o que pode quebrar os testes.
2. Podem fazer testes A/B o que torna impossível ter resultados consistentes.
3. Podem detectar que o usuário é um script e bloquear o acesso (como o Google faz).
4. Podem ter funcionalidades de segurança habilitadas que previne o Cypress de funcionar corretamente.

O ponto do Cypress é ser uma ferramente de uso diário para construir e testar suas próprias aplicações.

O Cypress não é uma ferramenta de automação de propósito geral. É pouco adequado para scripts em sites que
estão em produção, e não estão sob seu controle.

Passo 2: Consultar um elemento

Agora que temos a página web carregada, precisamos fazer algo nela. Porque não clicamos em um link? Parece ser fácil, vamos ver qual deles gostamos... que tal type?

Para encontrar esse elemento pelo seu conteúdo, usamos cy.contains().

Vamos adicionar isso em nosso teste e ver o que acontece:

describe('My First Test', () => {
  it('finds the content "type"', () => {
    cy.visit('https://example.cypress.io')

    cy.contains('type')
  })
})

Agora o teste deve exibir o comando CONTAINS e ainda estar verde.

Mesmo sem adicionar uma asserção, sabemos que está tudo certo! Isso acontece pois muitos dos comandos do Cypress são construídos para falhar caso não encontram o que é esperado. Isso é conhecido como uma Asserção Padrão.

Para confirmar, substitua type por qualquer palavra que não esteja na página, como hype. Perceba que o teste falha, mas só depois de 4 segundos!

Entende o que o Cypress está fazendo? Automaticamente espera e tenta novamente pois é esperado que eventualmente o elemento será encontrado no DOM. O teste não falha imediatamente.

Teste com falha

Tomamos o cuidado de escrever centenas de mensagens de erro personalizadas que tentam explicar claramente o que deu errado no Cypress. Nesse caso, o Cypress atingiu o tempo limite tentando encontrar o texto hype em toda a página. Para ler mais sobre a exibição do erro, leia sobre Erros de depuração.

Antes de adicionar outro comando - vamos consertar esse teste. Substitua hype por type.

Vídeo de exemplo

Passo 3: Clicar em um elemento

Ok, agora queremos clicar no link que encontramos. Como fazer isso? Adicione o comando .click() no final do comando anterior, como abaixo:

describe('My First Test', () => {
  it('clicks the link "type"', () => {
    cy.visit('https://example.cypress.io')

    cy.contains('type').click()
  })
})

É quase possível ler o teste como uma história! O Cypress chama isso de encadeamento e comandos são encadeados para contruir testes que realmente expressam o que a aplicação faz de forma declarativa.

Note também que o painel da aplicação foi atualizado depois do clique, abrindo o link e mostrando a página de destino.

Agora podemos fazer uma asserção nessa nova página!

Vídeo de exemplo

Você pode ver o IntelliSense em seus arquivos de teste ao adicionar uma única linha de comentário especial. Leia sobre isso aqui.

Passo 4: Fazer uma asserção

Vamos fazer uma asserção sobre algo na nova página em que clicamos. Gostaríamos de ter certeza de que o novo URL é o URL esperado. Podemos fazer isso procurando a URL e encadeando uma asserção a ela com .should().

Aqui está, algo parecido:

describe('My First Test', () => {
  it('clicking "type" navigates to a new url', () => {
    cy.visit('https://example.cypress.io')

    cy.contains('type').click()

    // Should be on a new URL which includes '/commands/actions'
    cy.url().should('include', '/commands/actions')
  })
})

Adicionando mais comandos e asserções

Não estamos limitados a uma única interação e asserção em um determinado teste. Na verdade, muitas interações em um aplicativo podem exigir várias etapas e provavelmente alterarão o estado do aplicativo em mais de uma maneira.

Podemos continuar as interações e asserções neste teste, adicionando outro encadeamento para interagir e verificar o comportamento dos elementos nesta nova página.

Podemos usar cy.get() para selecionar um elemento baseado em uma classe CSS.Então, podemos usar o comando .type() para inserir texto no campo de entrada de texto selecionado. Por fim, podemos verificar que o valor do campo de entrada de texto reflete o texto que foi digitado com outro .should().

describe('My First Test', () => {
  it('Gets, types and asserts', () => {
    cy.visit('https://example.cypress.io')

    cy.contains('type').click()

    // Should be on a new URL which includes '/commands/actions'
    cy.url().should('include', '/commands/actions')

    // Get an input, type into it and verify that the value has been updated
    cy.get('.action-email')
      .type('[email protected]')
      .should('have.value', '[email protected]')
  })
})

E aí está: um breve teste no Cypress que visita uma página, encontra e clica em um link, verifica a URL e, em seguida, verifica o comportamento de um elemento na nova página. Se lermos em voz alta, pode soar como:

  1. Visitar: https://example.cypress.io
  2. Encontrar o elemento que contém type
  3. Clicar no elemento
  4. Pegar a URL
  5. Verificar que ela inclui /commands/actions
  6. Pegar o campo de entrada de texto com a classe .action-email
  7. Digitar [email protected] no campo de entrada de texto
  8. Verificar que o campo de entrada de texto é preenchido com o novo valor

Ou na sintaxe Dado que, Quando, Então:

  1. Dado que um usuário visita https://example.cypress.io
  2. Quando ele clica no link com label type
  3. E ele digita [email protected] no campo de entrada de texto com a classe .action-email
  4. Então o URL deve incluir /comandos/ações
  5. E o campo de entrada de texto com a classe .action-email tem [email protected] como valor

E ei, este é um teste muito limpo! Não precisamos dizer nada sobre como as coisas funcionam, apenas que gostaríamos de verificar uma série particular de eventos e resultados.

Vídeo de exemplo

Transições de página

É importante notar que este teste fez a transição em duas páginas diferentes.

[//]: <> (TODO - Adicionar links cy.visit e .click() quando traduzidos)

1. O [`cy.visit()`](https://docs.cypress.io/api/commands/visit.html)
2. O [`.click()`](https://docs.cypress.io/api/commands/click.html) para nova página

O Cypress detecta automaticamente coisas como um evento de transição de página e interromperá automaticamente
os comandos em execução até que a próxima página termine de carregar.

Se a próxima página não tivesse terminado sua fase de carregamento, Cypress teria encerrado o teste
e apresentado um erro.

Feito automaticamente - isso significa que você não precisa se preocupar com comandos executados
acidentalmente em uma página desatualizada, nem precisa se preocupar com a execução de comandos em
uma página parcialmente carregada.

Mencionamos anteriormente que o Cypress esperou 4 segundos antes de atingir o tempo limite para encontrar
um elemento DOM - mas, neste caso, quando o Cypress detecta um evento de transição de página, ele aumenta
automaticamente o tempo limite para 60 segundos para o único evento CARREGAR PÁGINA.

Em outras palavras, com base nos comandos e nos eventos que acontecem, o Cypress altera automaticamente seus
tempos limite esperados para corresponder ao comportamento do aplicativo da web.

[//]: <> (TODO - Adicionar link Configuração quando traduzido)

Esses vários tempos limite são definidos no arquivo de
[configuração](https://docs.cypress.io/guides/references/configuration.html#Timeouts).

Debugando

O Cypress vem com uma série de ferramentas de depuração para ajudá-lo a entender um teste.

Damos a você a capacidade de:

  • Viaje de volta no tempo até o instante de cada comando.
  • Veja especiais eventos de página que aconteceram.
  • Receba saída adicional sobre cada comando.
  • Avance / retroceda entre vários instantâneos de comando.
  • Pause os comandos e percorra-os iterativamente.
  • Visualize quando elementos ocultos ou múltiplos forem encontrados.

Vamos ver um pouco disso em ação usando nosso código de teste existente.

Time travel

Passe o mouse sobre o comando CONTAINS no Log de Comandos.

Você vê o que aconteceu?

Primeiro teste do hover contains

O Cypress automaticamente viajou de volta no tempo para um instante de quando o comando foi resolvido. Além disso, como o cy.contains() encontra elementos do DOM na página, o Cypress também destaca o elemento e o rola para a visualização (no topo da página).

Agora, se você se lembrar, no final do teste, acabamos em uma URL diferente:

https://example.cypress.io/commands/actions

Mas conforme passamos o mouse sobre o CONTAINS, o Cypress volta para a URL que estava presente quando aquela captura foi feita.

Primeiro teste de reverter url

Snapshots

Os comandos também são interativos. Vá em frente e clique no comando CLIQUE.

Primeiro teste de reverter url

Observe que ele é destacado em roxo. Isso fez três coisas dignas de nota ...

  1. Snapshots fixadas

    Agora fixamos este instante. Passar o mouse sobre outros comandos não reverterá para eles. Isso nos dá a chance de inspecionar manualmente o DOM de nosso aplicativo em teste no momento em que a snapshot foi obtida.

  2. Evento hitbox

    Como .click() é um comando de ação, isso significa que também vemos uma hitbox vermelha nas coordenadas em que o evento ocorreu.

  3. Painel do menu da snapshot

    Também existe um novo painel de menu. Alguns comandos (como comandos de ação) irão tirar vários instantes: antes e depois. Agora podemos alternar entre eles.

O snapshot anterior é obtido antes do disparo do evento de clique. O snapshot posterior é obtido imediatamente após o evento de clique. Embora esse evento de clique tenha feito nosso navegador carregar uma nova página, não é uma transição instantânea. Dependendo da velocidade de carregamento de sua página, você ainda pode ver a mesma página ou uma tela em branco enquanto a página está sendo descarregada e em transição.

Quando um comando causa uma mudança visual imediata em nosso aplicativo, alternar entre antes e depois atualizará nosso snapshot. Podemos ver isso em ação clicando no comando TYPE no Log de Comandos. Agora, clicar antes nos mostrará a entrada em um estado padrão, mostrando o texto do espaço reservado. Clique depois para nos mostrar a aparência da entrada quando o comando TYPE for concluído.

Erros

O Cypress imprime várias informações quando ocorre um erro durante um teste.

  1. Nome do erro: este é o tipo de erro (por exemplo, AssertionError, CypressError)

  2. Mensagem de erro: geralmente informa o que deu errado. O comprimento pode variar. Alguns são curtos como no exemplo, enquanto outros são longos e podem dizer exatamente como corrigir o erro.

  3. Saiba mais: algumas mensagens de erro contêm um link Saiba mais que o levará à documentação relevante do Cypress.

  4. Arquivo de quadro de código: geralmente é a linha superior do rastreamento de pilha e mostra o arquivo, o número da linha e o número da coluna realçado no quadro de código abaixo. Clicar neste link abrirá o arquivo em seu visualizador de arquivos preferido e destacará a linha e a coluna nos editores que o suportam.

  5. Pedaço de código: mostra um trecho de código onde ocorreu a falha, com a linha e a coluna relevantes destacadas.

  6. Exibir rastreamento de pilha: Clicar aqui alterna a visibilidade do rastreamento de pilha. Os rastreamentos de pilha variam em comprimento. Clicar em um caminho de arquivo azul abrirá o arquivo em seu visualizador de arquivos.

  7. Botão Imprimir no console: Clique aqui para imprimir o erro completo no console do DevTools. Isso geralmente permitirá que você clique em linhas no rastreamento de pilha e abra arquivos em suas DevTools.

Erro de falha de comando

Página de eventos

Observe que também há um log de aparência engraçada chamado: (PAGE LOAD) seguido por outra entrada para (NEW URL). Nenhum desses foi um comando que emitimos - em vez disso, o próprio Cypress irá desconectar eventos importantes de seu aplicativo quando eles ocorrerem. Observe que eles têm uma aparência diferente (eles são cinza e sem um número).

Primeiro teste de carregamento de página

O Cypress guarda logs de eventos de página para:

  • Solicitações de rede XHR
  • Mudanças de hash de URL
  • Carregamentos de página
  • Envios de formulários

Saída do console

Além dos Comandos serem interativos, eles também geram informações adicionais de depuração em seu console.

Abra suas Ferramentas de Desenvolvimento e clique em GET para o seletor de classe .action-email.

Primeiro teste de carregamento de página

Podemos ver informações adicionais de saída do Cypress no console:

  • Command (que foi emitido)
  • Yielded (o que foi retornado por esse comando)
  • Elements (o número de elementos encontrados)
  • Selector (o argumento que usamos)

Podemos até expandir o que foi retornado e inspecionar cada elemento individual ou até clicar com o botão direito e inspecioná-los no painel Elementos!

Comandos especiais

Além de ter uma interface de usuário útil, também existem comandos especiais dedicados à tarefa de depuração.

Por exemplo, existe:

Vamos adicionar o cy.pause() para o nosso código teste e ver o que acontence.

describe('My First Test', () => {
  it('clicking "type" shows the right headings', () => {
    cy.visit('https://example.cypress.io')

    cy.pause()

    cy.contains('type').click()

    // Deve estar em uma nova URL que inclui '/commands/actions'
    cy.url().should('include', '/commands/actions')

    // Obtenha um campo de entrada, digite e verifique se o valor foi atualizado
    cy.get('.action-email')
      .type('[email protected]')
      .should('have.value', '[email protected]')
  })
})

Agora, o Cypress nos fornece uma interface de usuário (similar ao depurador) para avançar em cada comando.

Primeiro teste pausado

Em ação

Vídeo do primeiro debug

Próximos passos

Campo de busca

Voltar para o topo