Snímky
Naučte se pracovat se snímky prostřednictvím videa z Vue SchoolSnímkové testy jsou velmi užitečný nástroj, který vám pomůže zajistit, že se výstup vašich funkcí nezmění neočekávaným způsobem.
Při použití snímků Vitest vytvoří snímek dané hodnoty a porovná jej s referenčním snímkem uloženým v souboru vedle testu. Pokud se snímky neshodují, test selže. To může znamenat buď neočekávanou změnu, nebo že je potřeba aktualizovat referenční snímek na novou verzi výsledku.
Použití snímků
Pro vytvoření snímku hodnoty použijte metodu toMatchSnapshot()
z API expect()
:
import { expect, it } from 'vitest';
it('toUpperCase', () => {
const result = toUpperCase('foobar');
expect(result).toMatchSnapshot();
});
Při prvním spuštění tohoto testu Vitest vytvoří soubor se snímkem, který bude vypadat takto:
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports['toUpperCase 1'] = '"FOOBAR"';
Soubor se snímkem by měl být uložen spolu se změnami kódu a zkontrolován v rámci revize kódu. Při následných spuštěních testů Vitest porovná aktuální výstup s uloženým snímkem. Pokud se hodnoty shodují, test projde. Pokud se hodnoty neshodují, testovací nástroj buď našel chybu ve vašem kódu, kterou je třeba opravit, nebo se implementace změnila a je třeba aktualizovat snímek.
WARNING
Při použití snímků v asynchronních testech, které běží souběžně, je nutné použít expect
z lokálního Testovacího kontextu, aby se zajistilo správné fungování testu.
Inline snímky
Podobně můžete použít metodu toMatchInlineSnapshot()
k uložení snímku přímo v testovacím souboru.
import { expect, it } from 'vitest';
it('toUpperCase', () => {
const result = toUpperCase('foobar');
expect(result).toMatchInlineSnapshot();
});
Místo vytvoření samostatného souboru se snímkem Vitest přímo upraví testovací soubor a aktualizuje snímek jako řetězec:
import { expect, it } from 'vitest';
it('toUpperCase', () => {
const result = toUpperCase('foobar');
expect(result).toMatchInlineSnapshot('"FOOBAR"');
});
Díky tomu uvidíte očekávaný výstup přímo v kódu, bez nutnosti přepínání mezi soubory.
WARNING
Při použití snímků v asynchronních testech, které běží souběžně, je nutné použít expect
z lokálního Testovacího kontextu, aby se zajistilo správné fungování testu.
Aktualizace snímků
Pokud se získaná hodnota neshoduje se snímkem, test selže a zobrazí se rozdíl mezi nimi. Pokud je změna snímku očekávaná, můžete snímek aktualizovat na aktuální stav.
V režimu watch můžete stisknout klávesu u
v terminálu a přímo aktualizovat neúspěšné snímky.
Nebo můžete použít přepínač --update
nebo -u
v CLI, aby Vitest aktualizoval snímky.
vitest -u
Souborové snímky
Při volání toMatchSnapshot()
se všechny snímky ukládají do formátovaného souboru se snímky. To vyžaduje escapování některých znaků v řetězci snímku, konkrétně dvojitých uvozovek "
a zpětných apostrofů ```. Navíc můžete ztratit zvýraznění syntaxe pro obsah snímku (pokud je v nějakém jazyce).
Pro tento účel zavádíme metodu toMatchFileSnapshot()
, která umožňuje ukládat snímky do samostatných souborů. To vám umožní přiřadit souboru se snímkem libovolnou příponu a učinit je čitelnějšími.
import { expect, it } from 'vitest';
it('render basic', async () => {
const result = renderHTML(h('div', { class: 'foo' }));
await expect(result).toMatchFileSnapshot('./test/basic.output.html');
});
Test bude porovnávat obsah se souborem ./test/basic.output.html
. Soubor lze aktualizovat pomocí příznaku --update
.
Obrázkové snímky
Snímky obrázků lze také vytvářet pomocí knihovny jest-image-snapshot
.
npm i -D jest-image-snapshot
test('image snapshot', () => {
expect(readFileSync('./test/stubs/input-image.png')).toMatchImageSnapshot();
});
Další informace naleznete v příkladu examples/image-snapshot
.
Vlastní způsob serializace
Můžete přidat vlastní logiku pro úpravu způsobu, jakým jsou vaše snímky serializovány. Podobně jako Jest má i Vitest výchozí serializátory pro základní typy JavaScriptu, prvky HTML, ImmutableJS a pro prvky React.
Příklad modulu serializátoru:
expect.addSnapshotSerializer({
serialize(val, config, indentation, depth, refs, printer) {
// `printer` je funkce, která serializuje hodnotu pomocí existujících pluginů.
return `Pretty foo: ${printer(val.foo)}`;
},
test(val) {
return val && Object.prototype.hasOwnProperty.call(val, 'foo');
},
});
Po přidání testu, jako je tento:
test('foo snapshot test', () => {
const bar = {
foo: {
x: 1,
y: 2,
},
};
expect(bar).toMatchSnapshot();
});
Výsledný snímek bude vypadat takto:
Pretty foo: Object {
"x": 1,
"y": 2,
}
Pro serializaci snímků Vitest používá knihovnu pretty-format
od Jestu. Více si o tom můžete přečíst zde: pretty-format.
Rozdíl od Jest
Vitest poskytuje téměř kompatibilní funkci snímků s Jest's s několika výjimkami:
1. Hlavička komentáře v souboru snímku je odlišná {#_1-comment-header-in-the-snapshot-file-is-different}
- // Jest Snapshot v1, https://goo.gl/fbAQLP
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
Tato změna neovlivňuje funkčnost, ale může ovlivnit rozdíly v commitech při migraci z Jest.
2. printBasicPrototype
je ve výchozím nastavení false
{#_2-printbasicprototype-is-default-to-false}
Snímky v Jestu i Vitestu využívají pretty-format
. Ve Vitest nastavujeme printBasicPrototype
ve výchozím nastavení na false
, abychom poskytli čistší výstup snímku, zatímco v Jest <29.0.0 je ve výchozím nastavení true
.
import { expect, test } from 'vitest';
test('snapshot', () => {
const bar = [
{
foo: 'bar',
},
];
// in Jest
expect(bar).toMatchInlineSnapshot(`
Array [
Object {
"foo": "bar",
},
]
`);
// in Vitest
expect(bar).toMatchInlineSnapshot(`
[
{
"foo": "bar",
},
]
`);
});
Toto výchozí nastavení považujeme za vhodnější pro čitelnost a celkový DX (Developer Experience). Pokud stále preferujete chování Jest, můžete změnit konfiguraci:
// vitest.config.js
export default defineConfig({
test: {
snapshotFormat: {
printBasicPrototype: true,
},
},
});
3. Chevron >
se používá jako oddělovač namísto dvojtečky :
pro vlastní zprávy {#_3-chevron-is-used-as-a-separator-instead-of-colon-for-custom-messages}
Vitest používá chevron >
jako oddělovač namísto dvojtečky :
pro lepší čitelnost, když se při vytváření snímku předává vlastní zpráva.
Pro následující příklad testovacího kódu:
test('toThrowErrorMatchingSnapshot', () => {
expect(() => {
throw new Error('error');
}).toThrowErrorMatchingSnapshot('hint');
});
V Jest bude snímek:
exports[`toThrowErrorMatchingSnapshot: hint 1`] = `"error"`;
Ve Vitest bude ekvivalentní snímek:
exports[`toThrowErrorMatchingSnapshot > hint 1`] = `"error"`;