Testes de Snapshot
Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →
Testes de snapshot são uma ferramenta extremamente útil quando você quer garantir que sua interface não mude inesperadamente.
Um caso de teste de snapshot típico renderiza um componente de UI, captura um snapshot e o compara com um arquivo de snapshot de referência armazenado junto ao teste. O teste falha se os snapshots não coincidirem: seja porque a mudança foi inesperada, ou porque o snapshot de referência precisa ser atualizado para a nova versão do componente.
Testes de Snapshot com Jest
Uma abordagem similar pode ser aplicada ao testar componentes React. Em vez de renderizar a interface gráfica - o que exigiria construir todo o aplicativo - você pode usar um renderizador de teste para gerar rapidamente um valor serializável para sua árvore React. Veja este exemplo de teste para um componente Link:
import renderer from 'react-test-renderer';
import Link from '../Link';
it('renders correctly', () => {
const tree = renderer
.create(<Link page="http://www.facebook.com">Facebook</Link>)
.toJSON();
expect(tree).toMatchSnapshot();
});
Na primeira execução desse teste, o Jest cria um arquivo de snapshot com este aspecto:
exports[`renders correctly 1`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Facebook
</a>
`;
O artefato de snapshot deve ser commitado junto das mudanças de código e revisado no seu processo de code review. O Jest usa o pretty-format para tornar os snapshots legíveis durante revisões. Nas execuções seguintes, o Jest compara a saída renderizada com o snapshot anterior. Se coincidirem, o teste passa. Se não, ou o test runner encontrou um bug no seu código (no componente <Link> neste caso) que precisa ser corrigido, ou a implementação mudou e o snapshot precisa ser atualizado.
O snapshot tem escopo restrito aos dados que você renderiza - no nosso exemplo, o componente <Link> com a prop page. Isso significa que mesmo se outro arquivo (como App.js) tiver props faltantes no componente <Link>, o teste ainda passará, pois o teste não conhece o uso do <Link>, estando limitado ao Link.js. Além disso, renderizar o mesmo componente com props diferentes em outros testes de snapshot não afeta o primeiro, pois os testes não têm conhecimento mútuo.
Mais informações sobre como o teste de snapshot funciona e por que o criamos estão no post de lançamento. Recomendamos ler este artigo para entender quando usar snapshot testing. Também sugerimos assistir a este vídeo da egghead sobre Snapshot Testing com Jest.
Atualizando Snapshots
É fácil identificar quando um teste de snapshot falha após a introdução de um bug. Nesse caso, basta corrigir o problema para que os testes passem novamente. Mas vamos discutir quando um teste de snapshot falha devido a uma mudança intencional na implementação.
Um exemplo seria se mudássemos intencionalmente o endereço apontado pelo componente Link.
// Updated test case with a Link to a different address
it('renders correctly', () => {
const tree = renderer
.create(<Link page="http://www.instagram.com">Instagram</Link>)
.toJSON();
expect(tree).toMatchSnapshot();
});
Nessa situação, o Jest exibirá esta saída:

Como atualizamos o componente para apontar para outro endereço, é natural esperar mudanças no snapshot. Nosso teste falha porque o snapshot do componente atualizado não coincide mais com o artefato armazenado.
Para resolver, precisamos atualizar nossos artefatos de snapshot. Execute o Jest com um flag que solicite a regeneração dos snapshots:
jest --updateSnapshot
Aceite as alterações executando o comando acima. Você também pode usar a flag equivalente de caractere único -u para regenerar os snapshots, se preferir. Isso regenerará os artefatos de snapshot para todos os testes de snapshot que falharam. Se tivéssemos outros testes de snapshot falhando devido a um bug não intencional, precisaríamos corrigir o bug antes de regenerar os snapshots para evitar registrar snapshots do comportamento problemático.
Se quiser limitar quais casos de teste de snapshot serão regenerados, você pode passar a flag adicional --testNamePattern para regravar snapshots apenas para os testes que correspondem ao padrão.
Você pode experimentar essa funcionalidade clonando o exemplo de snapshot, modificando o componente Link e executando o Jest.
Modo Interativo de Snapshots
Snapshots com falha também podem ser atualizados interativamente no modo watch:

Ao entrar no Modo Interativo de Snapshots, o Jest guiará você pelos snapshots com falha, um teste por vez, dando oportunidade para revisar a saída com erro.
A partir daqui, você pode escolher atualizar aquele snapshot ou pular para o próximo:

Ao terminar, o Jest mostrará um resumo antes de retornar ao modo watch:

Snapshots Inline
Snapshots inline se comportam de forma idêntica aos snapshots externos (arquivos .snap), exceto que os valores são gravados automaticamente de volta no código-fonte. Isso significa que você obtém os benefícios dos snapshots gerados automaticamente sem precisar alternar para um arquivo externo para verificar se o valor correto foi gravado.
Exemplo:
Primeiro, escreva um teste chamando .toMatchInlineSnapshot() sem argumentos:
it('renders correctly', () => {
const tree = renderer
.create(<Link page="https://example.com">Example Site</Link>)
.toJSON();
expect(tree).toMatchInlineSnapshot();
});
Na próxima execução do Jest, tree será avaliado e um snapshot será gravado como argumento de toMatchInlineSnapshot:
it('renders correctly', () => {
const tree = renderer
.create(<Link page="https://example.com">Example Site</Link>)
.toJSON();
expect(tree).toMatchInlineSnapshot(`
<a
className="normal"
href="https://example.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
Example Site
</a>
`);
});
É só isso! Você pode até atualizar os snapshots com --updateSnapshot ou usando a tecla u no modo --watch.
Por padrão, o Jest cuida da gravação dos snapshots no seu código-fonte. Porém, se você usa prettier no projeto, o Jest detectará e delegará o trabalho para o prettier (respeitando sua configuração).
Matchers de Propriedades
Frequentemente existem campos em objetos que você quer incluir no snapshot que são gerados (como IDs e Datas). Se tentar fazer snapshot desses objetos, eles forçarão a falha do snapshot em toda execução:
it('will fail every time', () => {
const user = {
createdAt: new Date(),
id: Math.floor(Math.random() * 20),
name: 'LeBron James',
};
expect(user).toMatchSnapshot();
});
// Snapshot
exports[`will fail every time 1`] = `
{
"createdAt": 2018-05-19T23:36:09.816Z,
"id": 3,
"name": "LeBron James",
}
`;
Para esses casos, o Jest permite fornecer um matcher assimétrico para qualquer propriedade. Esses matchers são verificados antes do snapshot ser gravado ou testado, e então salvos no arquivo de snapshot no lugar do valor recebido:
it('will check the matchers and pass', () => {
const user = {
createdAt: new Date(),
id: Math.floor(Math.random() * 20),
name: 'LeBron James',
};
expect(user).toMatchSnapshot({
createdAt: expect.any(Date),
id: expect.any(Number),
});
});
// Snapshot
exports[`will check the matchers and pass 1`] = `
{
"createdAt": Any<Date>,
"id": Any<Number>,
"name": "LeBron James",
}
`;
Qualquer valor fornecido que não seja um matcher será verificado exatamente e salvo no snapshot:
it('will check the values and pass', () => {
const user = {
createdAt: new Date(),
name: 'Bond... James Bond',
};
expect(user).toMatchSnapshot({
createdAt: expect.any(Date),
name: 'Bond... James Bond',
});
});
// Snapshot
exports[`will check the values and pass 1`] = `
{
"createdAt": Any<Date>,
"name": 'Bond... James Bond',
}
`;
Se o caso envolver uma string e não um objeto, você precisará substituir manualmente a parte aleatória antes de testar o snapshot.
Você pode usar por exemplo replace() e expressões regulares.
const randomNumber = Math.round(Math.random() * 100);
const stringWithRandomData = `<div id="${randomNumber}">Lorem ipsum</div>`;
const stringWithConstantData = stringWithRandomData.replace(/id="\d+"/, 123);
expect(stringWithConstantData).toMatchSnapshot();
Outras formas de fazer isso são usando o serializador de snapshots ou mockando a biblioteca responsável por gerar a parte aleatória do código que você está snapshotando.