Skip to main content

Escrever um teste do Jest

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:

  • Escrever um teste para verificar sua configuração.
  • Escrever um teste com falha e alterar seu componente para fazer com que seja aprovado.
  • Identificar os comandos básicos do Jest.
  • Explicar os ganchos do ciclo de vida.

Iniciar com um componente web do Lightning

Para testar um componente web do Lightning, precisamos primeiro ter um componente para testar.

Criar um componente web do Lightning

  1. No Visual Studio Code, abra a paleta de comandos ao pressionar Ctrl+Shift+P (Windows) ou Cmd+Shift+P (macOS).
  2. Insira lightning web.
  3. Selecione SFDX: Criar componente web do Lightning.
  4. Digite unitTest como nome do novo componente.
  5. Pressione Enter.
  6. Pressione Enter novamente para aceitar o padrão force-app/main/default/lwc.

Isso cria o diretório unitTest no diretório lwc com os arquivos de base iniciais.

Diretório unitTest no projeto test-lwc.

Escrever um teste básico

Os testes do Jest são escritos, salvos e executados de modo diferente dos testes Jasmine ou Mocha escritos para o Lightning Testing Service para componentes do Aura. Os testes do Jest são apenas locais e são salvos e executados independentemente do Salesforce. Na verdade, você receberá um erro se tentar implantar os testes do Jest na sua organização do Salesforce. Embora os testes do Jest para componentes web do Lightning não sejam implantados na sua organização do Salesforce, certifique-se de submetê-los ao controle de versão junto com o próprio componente.

A pasta __tests__

Os arquivos de teste precisam ser separados dos outros arquivos de componente. Se não for criada automaticamente, crie uma pasta chamada __tests__ no nível superior da pasta do pacote do seu componente. Salve todos os testes deste componente dentro da pasta __tests__.

  1. No Visual Studio Code, clique com o botão direito no diretório unitTest e selecione Nova pasta.
  2. Insira __tests__.
  3. Pressione Enter.

Configure .forceignore

Compartilhe testes com outros membros da equipe ou sistemas ao submeter a pasta __tests__ ao controle de versão. Eles são uma parte valiosa de seu projeto e processo de integração contínua. Para evitar que eles sejam implantados no Salesforce, o arquivo .forceignore tem uma exclusão inserida para ele.

  • Verifique se o arquivo .forceignore de seu projeto contém as exclusões a seguir. Caso contrário, adicione-as e salve o arquivo.
    # LWC configuration files
    **/jsconfig.json
    **/.eslintrc.json
    # LWC Jest
    **/__tests__/**

Criar um arquivo de teste do Jest

Nosso primeiro teste é simples. Temos uma função sum () que deve adicionar dois números que são transmitidos a ele como argumentos.

  1. No Visual Studio Code, clique com o botão direto no diretório __tests__ e selecione Novo arquivo.
  2. Insira sum.test.js.
  3. Pressione Enter.
  4. Insira o código a seguir no novo arquivo de teste:
    import { sum } from '../sum';
        
    describe('sum()', () => {
      it('should add 1 and 2 returning 3', () => {
        expect(sum(1, 2)).toBe(3);
      });
    });
  5. Salve o arquivo.

Executar o teste

  1. No Visual Studio Code, selecione Exibir e, em seguida, selecione Terminal. Isso abre um terminal no Visual Studio Code. O padrão do terminal é o diretório de nível superior do projeto atual.
  2. No terminal, execute o comando da unidade anterior a seguir:
    npm run test:unit
  3. O teste falha devido à função de soma ausente.

Vejamos como solucionar a questão.

  1. No Visual Studio Code, clique com o botão direito no diretório unitTest e selecione novo arquivo.
  2. Insira sum.js.
  3. Pressione Enter.
  4. Insira o bloco de código a seguir no novo arquivo:
    export function sum(x, y) {
      return x + y;
    }
  5. Salve o arquivo.
  6. No terminal, execute o teste novamente:
    npm run test:unit
  7. O teste passa.

Parabéns! Você acabou de confirmar que o Jest está configurado e funcionando.

Vejamos o código de teste para conferir o que está acontecendo.

import { sum } from '../sum';
    
describe('sum()', () => {
  it('should add 1 and 2 returning 3', () => {
    expect(sum(1, 2)).toBe(3);
  });
});
  • A linha 1 importa a função de sum exportada do arquivo sum JavaScript.
  • A linha 3 é o início do conjunto de testes do Jest. A função ou bloco describe é um conjunto de testes e aceita dois argumentos. O primeiro é a descrição da unidade que estamos testando, que geralmente está na forma de um substantivo. O segundo é uma função callback que contém um ou mais testes. Você também pode aninhar conjuntos de teste describe uns dentro dos outros para gerar maior clareza.
  • A linha 4 é o teste (it é um alias para test). A função ou bloco it também aceita dois argumentos. O primeiro é outra descrição do que estamos esperando, geralmente começando com um verbo. Em seguida, uma função callback que constrói o teste e contém as asserções ou expectativas para o teste.
  • A linha 5 é a declaração expect que declara a condição de sucesso: que a função sum adicionaria os dois argumentos, 1 e 2, e retornaria 3. toBe é um dos muitos Jest matchers.
    Adicione outra asserção com a linha a seguir logo após a linha 5:
        expect(sum(1, 2)).not.toBeGreaterThan(3);
  • Adicionar .not e .toBeGreaterThan garante que o número não seja maior que 3. Você pode adicionar outra declaração expect com .not.toBeLessThan(3).

Agora, para o teste de componente web do Lightning.

Os testes do Jest para um componente web do Lightning devem testar o comportamento de um único componente isoladamente, com dependências mínimas de componentes ou serviços externos.

Passe pelo processo novamente com um arquivo de teste unitTest

Esse teste verificará se uma propriedade está definida e se, quando adicionada ao DOM, exibirá o texto correto. O arquivo unitTest.test.js foi criado com a pasta __tests__ quando o comando SFDX: Create Lightning Web Component foi executado.

  1. Substitua o código em unitTest.test.js pelo seguinte:
    import { createElement } from 'lwc';
    import UnitTest from 'c/unitTest';
      
    describe('c-unit-test', () => {
      afterEach(() => {
        // The jsdom instance is shared across test cases in a single file so reset the DOM
        while(document.body.firstChild) {
          document.body.removeChild(document.body.firstChild);
        }
      });
        
      it('displays unit status with default unitNumber', () => {
        const element = createElement('c-unit-test', {
          is: UnitTest
        });
        expect(element.unitNumber).toBe(5);
        // Add the element to the jsdom instance
        document.body.appendChild(element);
        // Verify displayed greeting
        const div = element.shadowRoot.querySelector('div');
        expect(div.textContent).toBe('Unit 5 alive!');
      });
    });
  2. Salve o arquivo.
  3. No terminal, execute os testes novamente:
    npm run test:unit
  4. Os testes falham com isso:
    Test Suites: 1 failed, 1 passed, 2 total
    Tests:       1 failed, 1 passed, 2 total

Vejamos esse código de teste para ver quais são os requisitos antes de atualizar o código para obter um teste que seja aprovado.

  • A linha 1 é nova. Ela importa o método createElement a partir da estrutura lwc. Só está disponível em testes.
  • A linha 2 importa a classe UnitTest do controlador JavaScript do componente.
  • A linha 4 inicia o bloco de conjunto de testes describe.
  • A linha 5 é um método de limpeza do Jest. afterEach() é um dos métodos de configuração e limpeza do Jest. afterEach() é executado após cada teste no bloco describe em que ele se encontra. Esse método afterEach() redefine o DOM no final do teste. O Jest não está executando um navegador quando os testes são executados. O Jest usa jsdom para fornecer um ambiente que se comporta como o DOM ou documento de um navegador. Cada arquivo de teste obtém uma única instância do jsdom, e as alterações não são redefinidas entre os testes dentro do arquivo. Uma prática recomendada é realizar uma limpeza entre os testes para que a saída de um teste não afete nenhum outro teste. Existem outros métodos de configuração e limpeza disponíveis. Verifique os recursos.
  • A linha 12 inicia o bloco de teste it.
  • A linha 13 é onde o método importado createElement é utilizado. Ele cria uma instância do componente e a atribui à constante element.
  • A linha 16 contém o expect declarando que a variável unitNumber está definida como 5. Esse é o primeiro requisito para o qual estamos testando, que unitNumber esteja definido como 5 primeiro.
  • Na verdade, a linha 18 adiciona o element à versão do jsdom do document.body usando o método appendChild. A chamada anexa o componente web do Lightning ao DOM e o renderiza, o que também significa que os ganchos do ciclo de vida connectedCallback() e renderedCallback() são chamados (mais sobre o assunto posteriormente).
  • A linha 20 usa o querySelector (um método de consulta DOM padrão) para pesquisar o DOM para uma marca div. Use element.shadowRoot como o principal para a consulta. É uma API somente de teste que permite espreitar pelo limite de sombra para inspecionar a árvore de sombra de um componente.
  • Por fim, a linha 21 contém o expect vendo o textContent da marca div para declarar “Unidade 5 viva!”. Esse é o requisito final. Declarando que o texto está correto.

Para fazer o teste passar, é necessário adicionar código aos arquivos HTML e JavaScript do unitTest. Adicionaremos código para cumprir os requisitos.

  1. Clique no arquivo unitTest.html para abri-lo.
  2. Substitua unitTest.html por:
    <template>
      <lightning-card title="Unit Status" icon-name="standard:bot">
        <div class="slds-m-around_medium">
          Unit {unitNumber} alive!
        </div>
      </lightning-card>
    </template>
  3. Salve o arquivo.
  4. Clique no arquivo unitTest.js para abri-lo e substituí-lo por:
    import { LightningElement, api } from 'lwc';
    import { sum } from './sum';
      
    export default class UnitTest extends LightningElement {
      @api unitNumber = sum(2,3);
    }
  5. Salve o arquivo e execute os testes:
    npm run test:unit
  6. Todos os testes passam.

Testar atualizações de DOM assíncronas

Quando o estado de um componente web do Lightning é alterado, o DOM atualiza de forma assíncrona. Para garantir que seu teste aguarde as atualizações serem concluídas antes de avaliar o resultado, retorne uma Promessa resolvida. Para fazer isso, encadeie o resto do seu código de teste à Promessa resolvida. O Jest aguarda a conclusão da cadeia de Promessas antes de encerrar o teste. Se a Promessa terminar no estado rejeitado, o Jest falhará o teste.

  1. Abra unitTest.test.js.
  2. Adicione este segundo teste após o último teste.
    Nesse teste, queremos verificar se uma alteração de propriedade atualizará o texto no DOM.
      it('displays unit status with updated unitNumber', () => {
        const element = createElement('c-unit-test', {
         is: UnitTest
        });
        // Add the element to the jsdom instance
        document.body.appendChild(element);
        // Update unitNumber after element is appended
        element.unitNumber = 6
          
        const div = element.shadowRoot.querySelector('div');
        // Verify displayed unit status
        expect(div.textContent).toBe('Unit 6 alive!');
      });
  3. Salve o arquivo e execute os testes.
    npm run test:unit
  4. Você receberá essa mensagem de falha:
    Expected: "Unit 6 alive!"
    Received: "Unit 5 alive!"

O que está acontecendo? A declaração expect está declarando que o div.textContext deve ser “Unidade 6 viva”, mas ainda é “Unidade 5 viva!”. Para ver a mudança, precisamos esperá-la retornando uma Promessa resolvida.

  1. Substitua a declaração expect com falha pelo seguinte, logo após o comentário // Verify display unit status:
        expect(div.textContent).not.toBe('Unit 6 alive!');
        
        // Return a promise to wait for any asynchronous DOM updates. Jest
        // will automatically wait for the Promise chain to complete before
        // ending the test and fail the test if the promise rejects.
        return Promise.resolve().then(() => {
          expect(div.textContent).toBe('Unit 6 alive!');
        });
  2. Execute o teste usando o mesmo comando da última vez ou use uma das outras opções da seção Executar testes do Jest da unidade anterior.
  3. O teste passa.

Por enquanto, tudo bem. Você conta com três testes bem-sucedidos em dois conjuntos de teste. Em seguida, adicione um quarto teste para que, quando um campo de entrada for atualizado, você possa verificar se o status da unidade é atualizado. Para fazer isso, use um evento de mudança no campo de entrada.

  1. Abra unitTest.test.js, se ainda não estiver aberto.
  2. Adicione uma linha após o último teste que você adicionou e adicione este terceiro teste ao conjunto:
      it('displays unit status with input change event', () => {
        const element = createElement('c-unit-test', {
          is: UnitTest
        });
        document.body.appendChild(element);
        const div = element.shadowRoot.querySelector('div');
          
        // Trigger unit status input change
        const inputElement = element.shadowRoot.querySelector('lightning-input');
        inputElement.value = 7;
        inputElement.dispatchEvent(new CustomEvent('change'));
          
        return Promise.resolve().then(() => {
          expect(div.textContent).toBe('Unit 7 alive!');
        });
      });
  3. Salve o arquivo e execute o teste para ver a mensagem de falha.
    Mensagem de erro. Você pode ver que apenas um teste foi executado e os outros dois foram ignorados.

Vamos verificar o que está sendo testado:

  • As primeiras linhas devem ser familiares. Você está adicionando o UnitTest ao document.body e, em seguida, criando uma referência à div.
  • A constante inputElement é definida com uma referência a um campo de entrada do Lightning.
  • Em seguida, o valor desse campo de entrada é definido como 7.
  • Em seguida, usamos o dispatchEvent para acionar um evento com um CustomEvent usando um tipo de evento de “mudança”.
  • A Promessa é familiar e só mudou para o valor do campo de entrada alterado.

Vamos atualizar o código para fazer com que seja aprovado. Para fazer isso, adicione o lightning-input ao arquivo HTML e o método handleChange ao controlador JavaScript.

  1. Abra unitTest.html.
  2. Adicione o código a seguir dentro do lightning-card e antes da div:
      <lightning-input
        label="Unit Number"
        value={unitNumber}
        onchange={handleChange} >
      </lightning-input>
  3. Salve o arquivo.
  4. Abra unitTest.js.
  5. Adicione o código a seguir após a declaração @apiunitNumber:
      handleChange(event) {
        this.unitNumber = event.target.value;
      }
  6. Salve o arquivo e execute os testes.
  7. Os testes são aprovados devido ao elemento de entrada adicionado e manipulador de JavaScript.

Testar ganchos do ciclo de vida

Componentes web do Lightning têm um ciclo de vida gerenciado pela estrutura. A estrutura cria componentes, adiciona e remove-os do DOM e renderiza atualizações do DOM sempre que o estado de um componente muda. Existem vários métodos para interagir com o ciclo de vida.

O gancho do ciclo de vida connectedCallback() é acionado quando um componente é inserido no DOM. O gancho do ciclo de vida disconnectedCallback() é acionado quando um componente é removido do DOM. Um dos usos desses ganchos é registrar e cancelar o registro de ouvintes de eventos.

Dê uma olhada no código no lmsSubscriberWebComponent a partir do repositório de amostras do lwc-recipes para obter um bom exemplo.

A seguir, veremos como escrever testes do Jest para serviços de conexão.

Recursos

Compartilhe seu feedback do Trailhead usando a Ajuda do Salesforce.

Queremos saber sobre sua experiência com o Trailhead. Agora você pode acessar o novo formulário de feedback, a qualquer momento, no site Ajuda do Salesforce.

Saiba mais Continue compartilhando feedback