Ferramentas: com qual martelo eu parafuso o encaixe da peça?

Eita, perai, que confusão é essa…

📑

Introdução

Se você passou pelo artigo de cenários, talvez tenha visto várias ferramentas, funções, e objetos, e deve ter se perguntado o que cada coisa faz.

[add imagens aqui]

Criando nossas próprias ferramentas

Para que você entenda melhor as ferramentas, vamos imaginar um cenário, onde você precisasse testar uma função que converte qualquer valor primitivo do javascript para string, como poderíamos fazer isso?

Pensando aqui sozinho, eu acho que implementaria o seguinte código:

export function realmenteEhUmaString (valorProposto) { ㅤㅤreturn typeof valorProposto === 'string' } realmenteEhUmaString(10)ㅤㅤㅤㅤㅤㅤ// false realmenteEhUmaString("Olá mundo!")// true

[imagem aqui]

Basicamente essa função verifica se o valor é do tipo string, e retorna um booleano, caso seja string, retorna true, caso não seja, retorna false

E como poderíamos usá-la para garantir que o código a seguir está correto?

const conversorDeQualquerCoisaParaString = (qualquerCoisa) => { ㅤㅤif (typeof qualquerCoisa === 'object') return JSON.stringify(qualquerCoisa) ㅤㅤelse return String(qualquerCoisa) }

[imagem aqui]

Teríamos que criar um ambiente que saiba lidar com o retorno da função verificadora:

// ferramental-de-teste.js import { realmenteEhUmaString } from './realmente-eh-uma-string' function testarCenario (nome, resultado) { ㅤㅤif (resultado === true) return "PASSOU " + nome ㅤㅤif (resultado === false) return "FALHOU " + nome ㅤㅤif (resultado === undefined || resultado === null) return "ERRO " + nome } export { realmenteEhUmaString, testarCenario }

E então temos que escrever o que queremos que seja verificado:

import { conversorDeQualquerCoisaParaString } from './ferramental-de-teste' import { realmenteEhUmaString, testarCenario } from './realmente-eh-uma-string' testarCenario("Deve converter o numero 10 para texto: '10'", () ㅤㅤconst resultado = conversorDeQualquerCoisaParaString(10) ㅤㅤreturn realmenteEhUmaString(resultado) }) testarCenario("Deve converter um objeto para string", () => { ㅤㅤconst resultado = conversorDeQualquerCoisaParaString({ id: 1, valor: '1579' }) ㅤㅤreturn realmenteEhUmaString(resultado) })

[imagem aqui]

Como podemos ver, nossa função de testarCenario é dinâmica, e aceita outros verificadores, além de só o de verificar string. Podemos fazer algo como:

testarCenario("Deve retornar um booleano", () => { ㅤㅤconst resultado = false ㅤㅤreturn typeof resultado === 'boolean' })

[imagem aqui]

Como assim passou sendo que o resultado é false? Calma, um false é do tipo booleano, ou seja, o return foi verdadeiro, porque garante que o tipo retornado é um Boolean

E então!!! Parabéns hehe.

🥳 Acabamos de criar uma mini ferramenta de testes, um pequeno ambiente de execução.

Espero que você tenha conseguido entender como que é feito um código que testa outro código.

Comparadores

Os matchers ou comparadores, são métodos que validam alguma condição, como o que criamos com nossa pequena ferramenta de testes. A seguir teremos uma tabela com alguns matchers e qual o objetivo de cada um, ou quando usar.

Esses exemplos são importantes para que possamos entender melhor para que serve cada ferramenta de uma biblioteca de testes (no caso das imagens no começo do artigo, a lib é o Jest o Vue Testing Library).

NomeDescrição
*.spec.js ou *.test.jsExtensões de arquivos de teste, assim os test runners podem ler e rodar somente esses arquivos atrás de testbeds
describe()Descreve uma seção e executa os testes dentro de si de maneira “escopada”, sem que alguma de suas funções interfira na execução de outro describe .
it()Executa um teste e indica se passou ou se falhou, pode ser executado em um describe ou não.
test()O mesmo que o it(). Executa um teste e indica se passou ou se falhou, pode ser executado em um describe ou não.
expect()É um verificador, ele recebe o valor, e você pode chamar outra função a partir de para fazer uma afirmação como exemplo o toEqual() para verificar se o valor é igual outro, ficando assim o seu uso: expect(valor).toEqual(10) e então ele dirá que o teste passou caso o valor seja igual a 10 ou irá falhar, caso não seja.
beforeEach()Executa qualquer coisa necessária antes de cada teste (por ex. alguma limpeza de objeto, ou de mocks, etc)
afterEach()Executa qualquer coisa necessária depois de cada teste (por ex. alguma limpeza de objeto, ou de mocks, etc)
jest.fn()Cria uma função mockada, para substituir a implementação original e conseguir capturar eventos, instancias, etc
jest.resetAllMocks()Limpa os mocks atuais, para evitar interferência de um mock de um teste em outro ou de múltiplas chamadas do mesmo mock em um teste.
renderÉ um método da VTL (Vue Testing Library) que permite renderizar o componente ou tela desejada, dentro do teste
screenÉ um objeto da VTL que permite acessar o conteúdo do componente renderizado, permitindo queries e ações em cima do mesmo. Veja a seguir alguns recursos que o screen oferece.
getBy… queryBy… findBy…São os métodos usados para encontrar elementos na página. A diferença entre eles é se a consulta lançará um erro se nenhum elemento for encontrado ou se retornará uma promise e tentará novamente.
getAllBy… queryAllBy… findAllBy…Métodos usados para encontrar múltiplos elementos na página.

Abaixo temos um resumo dos tipos de queries e na documentação você pode encontrar mais detalhes de cada método:

Tipos de consultasNada encontrado1 encontrado>1 encontradosTenta Novamente (Async/Await)
Único elemento
getBy...Lança erroRetorna elementoLança erroNão
queryBy...Retorna nullRetorna elementoLança erroNão
findBy...Lança erroRetorna elementoLança erroSim
Múltiplos elementos
getAllBy...Lança um erroRetorna arrayRetorna arrayNão
queryAllBy...RetornaRetorna arrayRetorna arrayNão
findAllBy...Lança um erroRetorna arrayRetorna arraySim
  • queryBy é útil quando queremos verificar que um elemento não está na tel.

    • Exemplo: expect(screen.queryByText("Hello")).not.toBeInTheDocument()

Baseado no princípio que testes devem assemelhar ao modo como as páginas são usadas, temos uma recomendação de prioridade para escolher as queries:

  1. Consultas que refletem a experiência de usuários

    (visual, mouse ou através de tecnologia assistiva).

    1. getByRole: Deve ser a primeira preferência. Pode ser usado para consultar todos os elementos expostos na árvore de acessibilidade. Se existem muitos elementos que você não consiga obter com dessa forma é possível que o componente não esteja acessível.
    2. getByLabelText: Indicado para campos de formulário. Quando os usuários navegam por um formulário eles encontram elementos usando o texto da label. Esse método simula esse comportamento.
    3. getByPlaceholderText: Pode ser utilizado quando um campo não possui label. (lembrando que o placeholder não substitui o papel da label)
    4. getByText: Este método pode ser usado para encontrar elementos não interativos (como divs, spans e parágrafos).
    5. getByDisplayValue: Pode ser útil ao navegar em uma página com formulário preenchido.
  2. Consultas semânticas

    (a experiência do usuário ao interagir com esses atributos varia muito entre os navegadores e a tecnologia assistiva.)

    1. getByAltText
    2. getByTitle
  3. IDs de teste

    1. getByTestId: É recomendado apenas para casos em que você não pode obter o elemento pela role ou pelo texto não faz sentido (por exemplo, o texto é dinâmico).

    2. Exemplo:

      1. <div data-testid=”teste” /> | const div = await screen.findByTestId('teste')
Nertec logo