TL;DR: Hidupkan kompilasi Ahead-Of-Time (AOT) untuk ujian Angular anda untuk mendapatkan liputan kod templat yang tepat, pelaksanaan ujian yang lebih pantas, simetri pengeluaran dan kalis masa hadapan ujian.
Pilihan sudah tersedia untuk pengguna Vitest dan tidak lama lagi akan tersedia untuk pengguna Karma dan Jest (pembina eksperimen).
Sama ada anda menggunakan Karma, Jest atau Vitest, anda mungkin menggunakan kompilasi Just-In-Time (JIT) untuk ujian Sudut anda, kerana sehingga baru-baru ini, ia merupakan satu-satunya pilihan yang tersedia.
Masalahnya ialah JIT mempunyai beberapa kelemahan yang ketara:
Sejak Sudut 8 dan pengenalan IVy, penyusun Sudut telah mula mengubah templat menjadi arahan. Di antara banyak faedah lain, ini juga bermakna alat liputan kod boleh memetakan arahan ini kepada templat dan mengira liputan kod dengan sewajarnya.
Secara teorinya, adalah mungkin untuk menghasilkan liputan kod dengan menjalankan ujian dengan AOT sejak Angular 8, tetapi pilihan itu tidak tersedia dalam Karma atau Jest. Hanya mungkin untuk mendayakan AOT untuk ujian sejak sokongan Vitest untuk Angular telah ditambahkan oleh pasukan Analog.
Sehingga November 2024:
Sama ada anda menggunakan JIT atau AOT, komponen akhirnya akan disusun pada satu ketika. Perbezaan utama ialah dengan AOT, kompilasi dilakukan sekali dan boleh dicache, manakala dengan JIT, setiap modul ujian mungkin akhirnya menyusun semula komponen.
Ini bermakna walaupun fasa transformasi agak perlahan dengan AOT, masa pelaksanaan ujian keseluruhan akan lebih cepat. Nombor yang saya lihat menunjukkan sekitar 20% pelaksanaan lebih pantas, tetapi ini akan sangat bergantung pada struktur ujian anda dan Sistem Dalam Ujian.
Kami secara amnya mahu ujian kami sesimetri mungkin dengan persekitaran pengeluaran untuk meningkatkan keyakinan. Ini selalunya mencabar kerana ia seimbang dengan sifat lain seperti kelajuan ujian, saiz Sistem Dalam Ujian atau kebolehramalan.
Aspek menarik AOT ialah ia meningkatkan simetri pengeluaran tanpa merosakkan sifat lain. Menggunakan AOT, anda akan mendapat lebih keyakinan dan mencapai tingkah laku yang lebih dekat dengan pengeluaran.
Lebih penting lagi, JIT telah mencapai hadnya dan menjadi liabiliti untuk Angular. Sebagai contoh, beberapa ciri Sudut tidak disokong dalam JIT (cth. Deferrable Views). Ciri berpotensi lain daripada peta jalan Sudut, seperti komponen tanpa pemilih, akan mungkin mustahil untuk digunakan dengan JIT.
Sebenarnya, memandangkan Input Isyarat Angular (dan API berfungsi yang serupa), JIT sudah memerlukan beberapa perubahan minimum untuk berfungsi.
Dengan bertukar kepada AOT, anda menjadikan ujian anda kalis masa hadapan, bersedia untuk mendapat manfaat daripada sebarang inovasi dan bersedia untuk apa sahaja masa depan JIT.
Dengan menghidupkan AOT, beberapa teknik yang bergantung pada binaan dinamik akan rosak.
Sebagai contoh, penggunaan sedemikian tidak akan berfungsi lagi:
// ? This is broken with AOT. const fixture = render(`<app-button></app-button>`, { imports: [Button] }); function render(template, { imports }) { @Component({ template, imports, }) class TestContainer {} return TestBed.createComponent(TestContainer); }
Walau bagaimanapun, memintas kompilasi AOT masih boleh dilakukan (⚠️ buat masa ini ️⚠️):
function render(template, { imports }) { @Component({ jit: true, template, imports, }) class TestContainer {} return TestBed.createComponent(TestContainer); }
Nasihat saya ialah elakkan binaan sedemikian sebanyak mungkin dan lebih suka mencipta komponen khusus ujian apabila diperlukan, walaupun ia mungkin lebih bertele-tele. Pada masa hadapan, pasukan Angular boleh menyediakan alternatif yang serasi dengan AOT dan kurang boilerplat-y.
Walaupun Ujian Cetek tidak seharusnya menjadi strategi ujian utama anda kerana ia juga kurang simetri pengeluaran, ia masih merupakan teknik yang berguna untuk ada dalam kotak alat anda.
Dengan AOT, pada masa ini mustahil untuk mengatasi import komponen menggunakan TestBed#overrideComponent.
Penyelesaian adalah untuk mengatasi kebergantungan komponen pada peringkat modul menggunakan API rangka kerja ujian dan menggantikan komponen dengan gandaan ujiannya.
Contohnya, dengan Vitest:
// app.cmp.spec.ts vi.mock('./street-map.cmp', async () => { return { StreetMap: await import('./street-map-fake.cmp').then( (m) => m.StreetMapFake ), }; }); // street-map-fake.cmp.ts @Component({ selector: 'app-street-map', template: 'Fake Street Map', }) class StreetMapFake implements StreetMap { // ... }
Walaupun penyelesaian sementara ini serasi dengan AOT, ia disertakan dengan kos:
Buat masa ini, saya akan mengesyorkan menggunakan JIT untuk Ujian Cetek sehingga TestBed#overrideComponent menyokong AOT atau sehingga pasukan Angular menyediakan alternatif yang lebih baik. Anda boleh mencapai ini dengan menggunakan konfigurasi berasingan untuk Ujian Cetek yang menggunakan JIT untuk ujian yang sepadan dengan corak tertentu seperti *.jit.spec.ts.
Cari fail vite.config.js dan hidupkan AOT dengan menetapkan pilihan jit pemalam Angular kepada palsu:
// ? This is broken with AOT. const fixture = render(`<app-button></app-button>`, { imports: [Button] }); function render(template, { imports }) { @Component({ template, imports, }) class TestContainer {} return TestBed.createComponent(TestContainer); }
Kami mempunyai pilihan untuk menggunakan istanbul atau native v8 untuk liputan kod. Atas sebab tertentu, masih dalam siasatan, pemetaan semula liputan Vitest gagal apabila menggunakan v8. Penyelesaiannya adalah dengan kembali menggunakan istanbul.
Pastikan anda memasang versi Vitest Istanbul yang sepadan dengan Versi utama Vitest
function render(template, { imports }) { @Component({ jit: true, template, imports, }) class TestContainer {} return TestBed.createComponent(TestContainer); }
Kemas kini vite.config.mts untuk membolehkan liputan menggunakan Istanbul:
// app.cmp.spec.ts vi.mock('./street-map.cmp', async () => { return { StreetMap: await import('./street-map-fake.cmp').then( (m) => m.StreetMapFake ), }; }); // street-map-fake.cmp.ts @Component({ selector: 'app-street-map', template: 'Fake Street Map', }) class StreetMapFake implements StreetMap { // ... }
Anda kini boleh menjalankan ujian:
export default defineConfig({ ... plugins: [ angular({ jit: false }), ... ], ... });
kemudian klik pada ikon liputan dan kagumi liputan kod templat. ?
(anda juga akan menemui laporan liputan dalam folder liputan)
Perhatikan bahawa liputan dikira berdasarkan arahan yang dihasilkan oleh pengkompil, yang bermaksud bahawa:
Ia juga akan berfungsi untuk arahan struktur.
Sekarang, teka apa!?
Liputan juga berfungsi untuk templat sebaris! ?
Walaupun liputan kod adalah alat yang berguna, ia harus digunakan dengan bijak. Pastikan ia sebagai penunjuk, bukan matlamat tegar.
Sebarang ketetapan statistik yang diperhatikan akan cenderung runtuh sebaik sahaja tekanan dikenakan ke atasnya untuk tujuan kawalan.
-- Charles Goodhart
Dalam erti kata lain, apabila ukuran menjadi sasaran, ia tidak lagi menjadi ukuran yang baik.
Saya akan menambah bahawa metrik yang paling mudah selalunya yang paling mengelirukan.
Pengguna Karma tidak lama lagi akan dapat mendayakan AOT dengan bendera mudah.
Pengguna jenaka mempunyai tiga pilihan:
Pengguna Vitest boleh menikmati faedah AOT sekarang. ?
Jika anda bosan dengan pepijat, atau ujian penyelenggaraan tinggi yang pecah pada setiap refactor, kursus video saya, Ujian Sudut Pragmatik, sedia membantu!
Ketahui strategi ujian praktikal dan boleh dipercayai untuk memastikan apl Angular anda stabil dan boleh diselenggara. (Kini diskaun 50% untuk masa terhad!)
Atas ialah kandungan terperinci Bahan Hilang untuk Liputan Kod Templat Sudut dan Ujian Kalis Masa Depan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!