Anlık Görüntü (Snapshot) Testleri
Vue School'dan Videolu Anlık Görüntüleri ÖğreninAnlık görüntü testleri, fonksiyonlarınızın çıktısının beklenmedik bir şekilde değişmediğinden emin olmak istediğinizde oldukça kullanışlı bir araçtır.
Anlık görüntüler kullanıldığında, Vitest verilen değerin bir anlık görüntüsünü alır ve bunu testle birlikte saklanan referans anlık görüntü dosyasıyla karşılaştırır. Eğer iki anlık görüntü eşleşmezse, test başarısız olur: bu ya değişikliğin beklenmedik olduğu anlamına gelir ya da referans anlık görüntüsünün sonucun yeni sürümüne güncellenmesi gerektiği anlamına gelir.
Anlık Görüntüleri Kullanma
Bir değerin anlık görüntüsünü almak için, expect()
API'sinden toMatchSnapshot()
metodunu kullanabilirsiniz:
import { expect, it } from 'vitest';
it('toUpperCase', () => {
const result = toUpperCase('foobar');
expect(result).toMatchSnapshot();
});
Bu test ilk kez çalıştırıldığında, Vitest aşağıdakine benzer bir anlık görüntü dosyası oluşturur:
// Vitest Snapshot v1, https://www.getbook.com/tr/book/vitest-0/guide/snapshot
exports['toUpperCase 1'] = '"FOOBAR"';
Anlık görüntü dosyası, kod değişiklikleriyle birlikte commit edilmeli ve kod inceleme sürecinizin bir parçası olarak gözden geçirilmelidir. Sonraki test çalıştırmalarında, Vitest oluşturulan çıktıyı önceki anlık görüntüyle karşılaştırır. Eşleşirlerse, test başarılı olur. Eşleşmezlerse, test çalıştırıcısı kodunuzda düzeltilmesi gereken bir hata bulmuş demektir ya da uygulama değişmiştir ve anlık görüntünün güncellenmesi gerekmektedir.
WARNING
Eşzamanlı asenkron testlerde Anlık Görüntüler kullanılırken, doğru testin algılandığından emin olmak için yerel Test Bağlamı'ndan expect
kullanılmalıdır.
Satır İçi Anlık Görüntüler
Benzer şekilde, anlık görüntüyü test dosyası içinde satır içinde saklamak için toMatchInlineSnapshot()
metodunu kullanabilirsiniz.
import { expect, it } from 'vitest';
it('toUpperCase', () => {
const result = toUpperCase('foobar');
expect(result).toMatchInlineSnapshot();
});
Vitest, bir anlık görüntü dosyası oluşturmak yerine, anlık görüntüyü bir dize olarak güncellemek için test dosyasını doğrudan değiştirir:
import { expect, it } from 'vitest';
it('toUpperCase', () => {
const result = toUpperCase('foobar');
expect(result).toMatchInlineSnapshot('"FOOBAR"');
});
Bu sayede beklenen çıktıyı farklı dosyalara gitmeden doğrudan görebilirsiniz.
WARNING
Eşzamanlı asenkron testlerde Anlık Görüntüler kullanılırken, doğru testin algılandığından emin olmak için yerel Test Bağlamı'ndan expect
kullanılmalıdır.
Anlık Görüntüleri Güncelleme
Alınan değer anlık görüntüyle eşleşmediğinde, test başarısız olur ve aralarındaki farkı gösterir. Anlık görüntüdeki değişiklik beklendiğinde, anlık görüntüyü mevcut duruma göre güncellemek isteyebilirsiniz.
İzleme modundayken, başarısız olan bir anlık görüntüyü doğrudan güncellemek için terminalde u
tuşuna basabilirsiniz.
Veya Vitest'in anlık görüntüleri güncellemesini sağlamak için CLI'da --update
veya -u
işaretini kullanabilirsiniz.
vitest -u
Dosya Anlık Görüntüleri
toMatchSnapshot()
çağrıldığında, tüm anlık görüntüleri biçimlendirilmiş bir .snap
dosyasında saklarız. Bu, anlık görüntü dizesinde bazı karakterlerden (örneğin çift tırnak "
ve ters tırnak ```) kaçmamız gerektiği anlamına gelir. Ayrıca, anlık görüntü içeriğinin sözdizimi vurgulamasını kaybedebilirsiniz.
Bu durumu iyileştirmek için, doğrudan bir dosyada anlık görüntü almak için toMatchFileSnapshot()
metodunu sunuyoruz. Bu, anlık görüntü dosyasına herhangi bir dosya uzantısı atamanıza ve bunların daha okunabilir olmasını sağlamanıza olanak tanır.
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/basic.output.html
içeriğiyle karşılaştırılacaktır ve --update
işaretiyle üzerine yazılabilir.
Resim Anlık Görüntüleri
jest-image-snapshot
kullanarak görüntülerin anlık görüntülerini almak da mümkündür.
npm i -D jest-image-snapshot
test('image snapshot', () => {
expect(readFileSync('./test/stubs/input-image.png')).toMatchImageSnapshot();
});
examples/image-snapshot
örneğinde daha fazla bilgi edinebilirsiniz.
Özel Serileştirici (Serializer)
Anlık görüntülerinizin nasıl serileştirileceğini değiştirmek için kendi mantığınızı ekleyebilirsiniz. Jest gibi, Vitest'in de yerleşik JavaScript türleri, HTML öğeleri, ImmutableJS ve React öğeleri için varsayılan serileştiricileri vardır.
Örnek serileştirici modülü:
expect.addSnapshotSerializer({
serialize(val, config, indentation, depth, refs, printer) {
// `printer`, mevcut eklentileri kullanarak bir değeri serileştiren bir fonksiyondur.
return `Pretty foo: ${printer(val.foo)}`;
},
test(val) {
return val && Object.prototype.hasOwnProperty.call(val, 'foo');
},
});
Şunun gibi bir test ekledikten sonra:
test('foo snapshot test', () => {
const bar = {
foo: {
x: 1,
y: 2,
},
};
expect(bar).toMatchSnapshot();
});
Aşağıdaki anlık görüntüyü elde edersiniz:
Pretty foo: Object {
"x": 1,
"y": 2,
}
Anlık görüntüleri serileştirmek için Jest'in pretty-format
özelliğini kullanıyoruz. Bu konuda daha fazla bilgiyi burada okuyabilirsiniz: pretty-format.
Jest'ten Farklılıklar
Vitest, birkaç istisna dışında Jest'in ile neredeyse uyumlu bir Anlık Görüntü özelliği sunar:
1. Anlık görüntü dosyasındaki yorum başlığı farklıdır {#_1-comment-header-in-the-snapshot-file-is-different}
- // Jest Snapshot v1, https://goo.gl/fbAQLP
+ // Vitest Snapshot v1, https://www.getbook.com/tr/book/vitest-0/guide/snapshot
Bu, işlevselliği gerçekten etkilemez, ancak Jest'ten geçiş yaparken commit farkınızı etkileyebilir.
2. printBasicPrototype
varsayılan olarak false
değerine ayarlanmıştır {#_2-printbasicprototype-is-default-to-false}
Hem Jest hem de Vitest'in anlık görüntüleri pretty-format
tarafından desteklenmektedir. Vitest'te, daha temiz bir anlık görüntü çıktısı sağlamak için printBasicPrototype
varsayılan olarak false
olarak ayarladık, Jest <29.0.0'da ise varsayılan olarak true
'dur.
import { expect, test } from 'vitest';
test('snapshot', () => {
const bar = [
{
foo: 'bar',
},
];
// Jest'te
expect(bar).toMatchInlineSnapshot(`
Array [
Object {
"foo": "bar",
},
]
`);
// Vitest'te
expect(bar).toMatchInlineSnapshot(`
[
{
"foo": "bar",
},
]
`);
});
Bunun okunabilirlik ve genel DX (Developer Experience - Geliştirici Deneyimi) için daha makul bir varsayılan olduğuna inanıyoruz. Hala Jest'in davranışını tercih ediyorsanız, yapılandırmanızı değiştirebilirsiniz:
// vitest.config.js
export default defineConfig({
test: {
snapshotFormat: {
printBasicPrototype: true,
},
},
});
3. Köşeli parantez >
özel mesajlar için iki nokta üst üste :
yerine ayırıcı olarak kullanılır {#_3-chevron-is-used-as-a-separator-instead-of-colon-for-custom-messages}
Vitest, anlık görüntü dosyası oluşturulurken özel bir mesaj iletildiğinde okunabilirlik için iki nokta üst üste (😃 yerine köşeli parantez (>) kullanır.
Aşağıdaki örnek test kodu için:
test('toThrowErrorMatchingSnapshot', () => {
expect(() => {
throw new Error('error');
}).toThrowErrorMatchingSnapshot('hint');
});
Jest'te, anlık görüntü şöyle olacaktır:
exports[`toThrowErrorMatchingSnapshot: hint 1`] = `"error"`;
Vitest'te, eşdeğer anlık görüntü şöyle olacaktır:
exports[`toThrowErrorMatchingSnapshot > hint 1`] = `"error"`;