Angular: Masalah Performa TestBed.configureTestingModule

Dibuat pada 20 Okt 2016  ·  110Komentar  ·  Sumber: angular/angular

Saya mengirimkan ... (centang satu dengan "x")

[ ] bug report 
[x] feature request
[ ] support request 

Perilaku saat ini

Mengimpor modul ke TestBed.configureTestingModule dapat memperlambat pengujian _secara substansial_. Kami memiliki 'modul bersama' dengan bagian-bagian, yang banyak digunakan oleh komponen kami, termasuk satu atau dua perpustakaan pihak ketiga. Sangat mudah untuk mengimpor modul ini sebagai pilihan daripada cherry dalam pengujian, namun menguji komponen kecil kemarin, saya melihat bootstrap uji mengambil _dua detik penuh_ dan harus memilih dependensi untuk membuat pengujian berjalan dengan andal.

Perilaku yang diharapkan

TestBed.configureTestingModule harus berprestasi.

Reproduksi minimal masalah dengan instruksi

Dalam plunker ini

  1. buka src/simple.spec.ts dan beri komentar dan batalkan komentar pada SharedModule impor ke configureTestingModule .
  2. Amati waktu yang diperlukan untuk menjalankan tes.

Saya melihat lompatan dari 0,079 detik ke 0,241 detik. (~= 3x lebih lambat). Kalikan dengan 5 kasus dan tes sederhana ini membutuhkan waktu satu detik. Buat modul bersama lebih besar dan Anda memiliki masalah nyata.

Apa motivasi / kasus penggunaan untuk mengubah perilaku?

  1. Tes yang lambat merusak alur kerja TDD
  2. Tes yang cukup lambat memutuskan karma dari browser dan gagal dalam suite.

Tolong beritahu kami tentang lingkungan Anda:

Win10, VsCode, Webpack,

  • Versi sudut: 2.0.X

Ya.

  • Browser: Lokal, PhantomJS. Plunk diuji di Chrome.
  • Bahasa: TypeScript (meskipun tes ditranspilasikan ke ES5 sebelum dijalankan, tentu saja)

_Catatan:_ Bahkan saat saya menulis ini, saya bertanya-tanya apakah itu harapan yang masuk akal untuk modul besar melalui TestBed dengan cepat? Mungkin saya hanya melakukan sesuatu yang salah secara arsitektur, (gunakan beberapa modul bersama yang lebih kecil, bukan yang besar, dll.) Namun, pengujian cukup memakan waktu tanpa harus melacak setiap ketergantungan individu dari komponen yang lebih kompleks hanya untuk mendapatkan dimulai.

testing days feature fixed by Ivy medium triage #1

Komentar yang paling membantu

Ini adalah pekerjaan saya saat ini di sekitar:

const oldResetTestingModule = TestBed.resetTestingModule;
beforeAll(done => (async () => {
  TestBed.resetTestingModule();
  TestBed.configureTestingModule({
    // ...
  });
  await TestBed.compileComponents();

  // prevent Angular from resetting testing module
  TestBed.resetTestingModule = () => TestBed;
})().then(done).catch(done.fail));

afterAll(() => {
  // reinstate resetTestingModule method
  TestBed.resetTestingModule = oldResetTestingModule;
  TestBed.resetTestingModule();
});

Dengan cara ini, hanya perlu menjalankan configureTestingModule dan compileComponents sekali per file spesifikasi. Setelah modul pengujian diinisialisasi, menjalankan TestBed.createComponent() cukup cepat.

Semua 110 komentar

Sepertinya tujuannya benar-benar untuk memiliki _component instance_ baru setiap kali, dan untuk sebagian besar pengujian _module_ akan menjadi statis untuk file .spec tertentu. Sepertinya juga mengonfigurasi _module_ di setiap iterasi adalah bagian yang benar-benar menambah waktu. Pola yang lebih baik dapat mengonfigurasi _module sekali_, lalu testModule.createComponent beberapa kali.

TestBed.configureTestingModule sekali dan memanggil TestBed.createComponent pada modul itu beberapa kali tidak berfungsi, meskipun ... mungkin saya kehilangan cara yang jelas untuk mempertahankan status modul di antara iterasi?

_Edit: FWIW Saya mencoba mencatat cap waktu dan sepertinya sebagian besar waktu berlalu selama TestBed.createComponent , bukan TestBed.configureTestingModule - namun saya masih curiga ini terkait dengan konfigurasi modul, karena menambahkan sesuatu ke modul yang diimpor menambahkan dengan waktu, apakah impor tersebut digunakan dalam komponen yang diuji atau tidak._

Saya memiliki masalah kinerja eksekusi pengujian unit yang tampaknya terkait langsung dengan masalah ini.

Saya memiliki aplikasi ionik 2/sudut 2. Saat mencoba menguji unit komponen saya menggunakan kelas TestBed dan ComponentFixture, ada waktu 1-2 detik yang dihabiskan dengan mudah dalam pengaturan setiap pengujian yang tampaknya terkait langsung dengan imports: [IonicModule.forRoot(MyComponent)] yang telah saya tambahkan ke modul pengujian saya melalui TestBed.configureTestingModule({...}) metode.

Ketika saya menghapus impor, pengujian saya berjalan lebih cepat, tetapi jelas gagal karena template komponen saya tidak lagi dikompilasi.

@vmandy Saya telah mengatasi ini dengan melakukan satu atau lebih dari:

  1. menghabiskan lebih banyak waktu untuk mengkurasi _hanya apa yang saya butuhkan_ dalam modul pengujian
  2. mengejek dependensi komponen yang memakan waktu untuk bootstrap
  3. mengganti templat komponen yang saya uji sehingga tidak terlalu bergantung.

Semuanya memakan waktu dan kurang optimal (kecuali dari sudut pandang bahwa saya benar-benar terpaksa mengisolasi unit yang saya uji?)

Sepertinya ada beberapa _theoretical_ optimasi untuk ini setidaknya, karena saya _tahu_ komponen ini tidak mengambil 1-2 detik untuk bootstrap saat run-time.

Saya mengalami masalah serupa. Kupikir itu disebabkan oleh walabi, tetapi tampaknya itu adalah TestBed.

https://github.com/wallabyjs/public/issues/885

Saya melihat masalah yang sama. Tes unit apa pun dengan kompilasi komponen mendekati 1 detik ...

Sayangnya saya ditarik dari proyek Angular 2 dan belum melihat ini dalam beberapa waktu. Sepertinya banyak komplikasi TestBed (pengaturan modul tes, umumnya, bukan hanya kinerja) dapat dihindari dengan pendekatan yang mirip dengan pendekatan render enzym.shallow di ekosistem React. - di mana hanya satu unit yang dirender dan tidak ada dependensinya - hal yang sama dapat dilakukan dengan mengganti template komponen Angular di .spec, tetapi itu juga sering kali membosankan/memakan waktu.

kami memiliki hampir 2000 kasus uji yang dieksekusi kurang dari 1 menit di Angular 1 di mana Angular 2 membutuhkan waktu 1 menit untuk mengeksekusi hanya 100 kasus uji. Alangkah baiknya jika kita bisa mendapatkan solusi untuk masalah ini karena menghambat kemampuan pengujian dalam aplikasi besar.

@mlakmal Saya pikir ada banyak orang yang sangat bergantung pada tes e2e, atau hanya menguji logika fungsional di kelas komponen

let component = new ComponentClass(mockDep1, mockDep2);
expect(component.doAddition(2,2)).toBe(4);

Yang tidak menguji rendering template apa pun (logika template) ... tetapi setidaknya memungkinkan pengujian _class logic_ yang mudah

@ollwenjones terima kasih, saya akan mencobanya. saya benar-benar tidak ingin menguji logika templat apa pun karena sebagian besar dari itu tercakup oleh pengujian otomatis kami, jadi hanya menguji kode kelas komponen sudah cukup.

@mlakmal manis! Membuat saya senang untuk menyumbangkan sesuatu yang benar-benar membantu seseorang. - FWIW Saya sering bingung tentang pengujian unit rendering template, karena sangat mudah untuk masuk ke pengujian _framework_.

Saya sedang dalam proses meningkatkan proyek yang cukup besar dari rc.4 ke 2.3, jadi ini pertama kalinya kami menggunakan pendekatan NgModule.

Kami memiliki ~ 1000 unit tes, dengan mungkin 1/2 dari komponen pengujian tersebut. Sebelum memutakhirkan, pengujian berjalan cukup cepat - sekitar 30-an.

Setelah memutakhirkan, mereka membutuhkan waktu setidaknya dua kali lebih lama, tetapi yang terburuk adalah mereka tampak agak "terkelupas" - Karma secara berkala akan kehilangan koneksi ke Chrome dan seringkali saya perlu menyegarkan Chrome beberapa kali. Saya menduga ada sesuatu yang waktunya habis tetapi belum mengisolasinya.

@ollwenjones tentang pengujian komponen "dangkal", apakah Anda tahu tentang NO_ERRORS_SCHEMA yang dapat Anda atur dalam modul pengujian?

import { NO_ERRORS_SCHEMA} from '@angular/core';
// ...
TestBed.configureTestingModule({
  declarations: [ /*... whatever */ ],
  schemas: [NO_ERRORS_SCHEMA]
});

Ini berarti bahwa kompilator mengabaikan elemen apa pun yang tidak dikenalinya, artinya Anda tidak perlu mendeklarasikan semua komponen yang digunakan dalam templat komponen yang diuji.

Menemukan masalah yang sama dalam pengujian Angular: #13500
Saya dapat memperbaiki situasi dengan membuat modul pengujian yang dipesan lebih dahulu untuk setiap pengujian.

@michaelbromley 😮 Aku tidak tahu tentang NO_ERRORS_SCHEMA akan / mungkin akan menyelamatkan saya _hours_ - juga merupakan kesempatan untuk mudah-mudahan mempercepat beberapa tes ini, sebagai lebih ramping tes-modul lebih cepat testbed tampaknya untuk pergi.

@michaelbromley yang juga banyak membantu saya. Menghapus MaterialModule.forRoot() dari impor saya benar-benar mempercepat pengujian saya. 👍

Idealnya, kita harus dapat memanggil TestBed.configureTestingModule() di dalam beforeAll() . Itu tidak berfungsi karena baris ini. Ini mengatur ulang modul sebelum setiap tes. Mungkin seharusnya tidak masalah, tetapi itu karena Angular menghabiskan cukup banyak waktu untuk mengkompilasi komponen dalam mode JiT. Menyetel ulang akan membuang informasi ini. Merekam sesi profil di jendela karma membawa saya pada kesimpulan ini.

IMO, ini harus dilakukan:

  1. Mampu mengonfigurasi modul di beforeAll();
  2. Cache komponen yang dikompilasi

Cara lain untuk memperbaikinya adalah membuat modul pengujian reset eksplisit, tetapi ini dapat merusak kode pengguna.

Apakah jelas bahwa ini tidak ada hubungannya dengan karma-phantom? Tes terbang di Chrome untuk saya, tetapi Phantom membutuhkan setidaknya satu detik per tes. Saya telah mengolok-olok dependensi sebanyak mungkin dan mereka masih berjalan lambat di Phantom.

phantom sangat lambat bagi saya (menggunakan karma-webpack , tetapi ini adalah masalah yang berbeda. Saya menggunakan Chrome sekarang, dan Anda dapat melihat secara visual saat pengujian berjalan ketika ada pengujian yang menggunakan banyak komponen yang harus dikompilasi macet sebentar dan berjalan lambat hingga mencapai tes layanan yang berjalan cepat.

Mengkonfigurasi modul di beforeAll tidak begitu nyaman, karena saya ingin membuat tiruan baru setelah setiap kali dijalankan dan membuatnya (dan penyedia lainnya) dalam keadaan baru.

Caching komponen yang dikompilasi adalah cara untuk melakukannya.

Anda juga dapat menggunakan electron dan karma-electron untuk menjalankan pengujian
tanpa kepala. Ini hampir secepat chrome. Phantomjs sekitar 8 kali lebih lambat
untuk saya.

Bersulang

Notifikasi [email protected] schrieb am Mi., 8. Mrz 2017, 23:49:

phantom sangat lambat bagi saya (menggunakan karma-webpack, tetapi ini berbeda
isu. Saya menggunakan Chrome sekarang, dan Anda dapat melihat secara visual saat pengujian berjalan
ada tes yang menggunakan banyak komponen yang harus dikompilasi itu
macet sesaat dan berjalan lambat hingga mencapai tes layanan yang
lari cepat.

Mengkonfigurasi modul di beforeAll tidak begitu nyaman, karena saya ingin
buat tiruan baru setelah masing-masing dijalankan dan minta mereka (dan penyedia lainnya) di a
keadaan segar.

Caching komponen yang dikompilasi adalah cara untuk melakukannya.


Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/12409#issuecomment-285195615 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/ABn5_18VjaBSPZQX1ZQ45mveN2PFMoNBks5rjzB-gaJpZM4KcS5I
.

Dukungan AOT juga akan membantu di sini.

@philipooo dengan sedikit modifikasi pada beberapa referensi Jasmine ( jasmine.createSpyObj() khusus), Anda juga dapat menjalankan tes Anda tanpa browser apa pun – dengan menggunakan Jest alih-alih Karma.

Untuk sedikitnya 35 file dengan total 100 tes Jest telah mampu mempercepat pengujian saya 2.5x (vs Karma di Chrome). Pengujian sekarang berjalan secara paralel, sepenuhnya terisolasi, belum lagi mode jam tangan superior dengan umpan balik instan.

Saya telah menulisnya di sini, jika ada yang penasaran: https://www.xfive.co/blog/testing-angular-faster-jest/.

Ada juga masalah untuk mengintegrasikannya langsung ke CLI (misalnya di bawah bendera: ng test --jest ): https://github.com/angular/angular-cli/issues/4543.

@thymikee Saya sangat senang mendengarnya. Saya telah _muuuch lebih baik_ pengalaman menguji kode Bereaksi dengan Jest daripada yang pernah saya miliki dengan Angular, dan saya telah diyakinkan bahwa pengguna akhir kerangka kerja yang dapat dipercaya tidak perlu melakukan banyak pengujian browser.

Terakhir kali saya memeriksa Jest menggunakan jsdom yang tidak bermain bagus dengan zone.js apakah ini tidak lagi terjadi? Saya harus membaca blog Anda.

Jadi jsdom bukan masalah. Hanya saja tes harus dijalankan dalam konteks Zone.js, yang dilakukan oleh lib kecil ini: jest-zone-patch

Pengujian dengan komponen HTML hanya menyusahkan... Saya memiliki sekitar 500 unit tes yang 90% melihat DOM, butuh 40 menit untuk menjalankan semuanya... pada tingkat ini, Chrome mogok saat mencapai tingkat RAM terlalu tinggi... hasilnya adalah saya harus mengelompokkan tes saya sebanyak 50. Menyakitkan sekali...

Pasti ada beberapa kebocoran memori di sana-sini ...

bueller?

Menemukan bahwa menggunakan FormsModule sangat memperlambat compileComponents terutama menggunakan ngModel .

Misalnya di sini adalah plunker yang memiliki komponen dengan 10 input dan dibutuhkan sekitar 3 kali lebih banyak saat menggunakan ngModel .

@juliemr Hei, saya ingin melakukan permintaan fitur untuk menambahkan skema yang melakukan rendering dangkal. Haruskah menyimpan barang-barang di sini (karena apa yang ditulis @ollwenjones cukup banyak adalah yang saya inginkan) atau membuat masalah baru?
Pada dasarnya itu:

  • Mampu membuat instance komponen anak, TAPI bukan templatnya. (ini sedikit lebih kompleks daripada kedengarannya)
  • Masih mengalami kesalahan saat terikat ke properti yang salah pada komponen (tidak seperti skema kesalahan)

Saat ini saya sedang membuat komponen rintisan dalam proyek saya untuk membuat komponen kosong dan meminta mereka mengimplementasikan antarmuka yang sama untuk membuatnya konsisten dengan input dan output dan memudahkan pengguna saya untuk menguji template komponen mereka. Ini menjadi sangat sulit setelah Anda memasukkan hal-hal seperti logika ContentChildren yang dikombinasikan dengan penggunaan atau transklusi direktif templateOutlet.

Solusi yang mungkin adalah menggunakan skema normal atau komponen pertama kemudian untuk komponen anak menggunakan NO_ERROR_SCHEMA.

Jadi kami baru-baru ini beralih ke Jest dari webpack > karma/phantom/chrome, menggunakan instruksi / alat hebat @thymikee yang mempercepat sedikit (langkah pembuatan webpack pra-tes dihapus setidaknya) dan penyiapan yang disederhanakan _sangat_ - tetapi secara keseluruhan Pengujian sudut masih terasa seperti _struggle_.

Alasan utamanya adalah mengonfigurasi modul pengujian masih _pain_ - hasil dengan NO_ERRORS_SCHEMA jerawatan, dan hal-hal tertentu yang ditakdirkan untuk memperlambat segalanya (seperti hal-hal dari @angular/material dan DynamicFormsModule ) harus disertakan (jadi tes sederhana yang saya kerjakan ini masih membutuhkan waktu 6 detik.) Terima kasih @oferh untuk

Mengarahkan saya untuk mengatakan bahwa @dblVs , saya pikir Anda _harus_ melakukan permintaan fitur. Saya pikir saran _positif_ dengan beberapa ide desain yang bagus mungkin akan lebih diterima oleh orang-orang inti daripada negatif saya, "ini lambat... "

Pendapat saya adalah bahwa tanpa alat seperti itu, kami tidak diberdayakan oleh alat saat ini untuk menulis _unit test_ sama sekali. Semua pengujian ini dengan rendering komponen yang dalam dan semua dependensi di bawah pohon yang disediakan dalam modul uji untuk injeksi, dll. adalah _pengujian integrasi_, dan uji integrasi _lebih sulit untuk ditulis._

jika itu membantu siapa pun, saya mencoba browser tanpa kepala Electron dengan tes unit 2 sudut dan kinerjanya jauh lebih baik daripada PhantomJS.

Ya, PhantomJS benar-benar sangat tua. Tetapi Chrome versi terbaru juga dapat berjalan sebagai browser tanpa kepala dan ini akan menjadi yang tercepat.

@ollwenjones saya sangat setuju, ini adalah permintaan fitur yang sangat penting/kritis. jika kami ingin mengembangkan melalui TDD (juga fase pengujian normal) itu sangat sulit dan kami berjuang dengan kinerja waktu uji runner

Ini adalah pekerjaan saya saat ini di sekitar:

const oldResetTestingModule = TestBed.resetTestingModule;
beforeAll(done => (async () => {
  TestBed.resetTestingModule();
  TestBed.configureTestingModule({
    // ...
  });
  await TestBed.compileComponents();

  // prevent Angular from resetting testing module
  TestBed.resetTestingModule = () => TestBed;
})().then(done).catch(done.fail));

afterAll(() => {
  // reinstate resetTestingModule method
  TestBed.resetTestingModule = oldResetTestingModule;
  TestBed.resetTestingModule();
});

Dengan cara ini, hanya perlu menjalankan configureTestingModule dan compileComponents sekali per file spesifikasi. Setelah modul pengujian diinisialisasi, menjalankan TestBed.createComponent() cukup cepat.

@vvasabi solusi yang menarik, satu file pengujian spesifikasi sangat lambat, karena di dalam beforeEach kami mendefinisikan modul yang menyertakan modul dengan banyak komponen dan beberapa layanan tiruan (dengan array penyedia dan useClass) Sayangnya beberapa tes gagal setelah menggunakan perbaikan Anda. Kami juga menggunakan AOT yang mungkin memperlambat kompilasi.

Kami juga menggunakan overrideComponent di dalam beforeEach karena layanan ini hanya digunakan dalam komponen ini.

fixture = TestBed.overrideComponent(ListingFormComponent, { set: { providers: [ { provide: DisplayFieldService, useClass: MockDisplayFieldService } ] } }).createComponent(ListingFormComponent);

Tetapi masalah utamanya jelas adalah penyertaan modul "besar" dengan banyak komponen di dalam configureTestingModule.

Waktu setelah perbaikan : Menjalankan 53 dari 148 (3 GAGAL) KESALAHAN (1,261 dtk / 0,327 dtk) berjalan lancar tetapi 3 tes gagal sekarang mungkin lebih karena rangkaian tes berhenti.
Waktu sebelum Perbaikan : Chrome 59.0.3071 (Mac OS X 10.12.5): Dieksekusi 63 dari 148 (dilewati 85) SUKSES (44.235 dtk / 44.164 dtk) dengan beberapa eksekusi beku selama pengujian.

Masih menyelidiki.

@rbinsztock Saya akan mencoba mengisolasi tes yang gagal ke dalam file spesifikasi mereka sendiri tanpa menerapkan peretasan saya. Karena peretasan saya mencegah Angular mengatur ulang test bed setelah setiap tes dijalankan, beberapa tes yang mengubah status di layanan bersama (yaitu mencemari test bed) dapat menyebabkan tes lain rusak. Misalnya, jika pengujian 1 membuat beberapa perubahan pada MockDisplayFieldService , maka pengujian 2 akan mendapatkan kembali instance MockDisplayFieldService dengan perubahan yang masih diterapkan.

Setelah Anda mengetahui pengujian mana yang mengubah status layanan bersama dan menyebabkan yang lain rusak, Anda dapat mencoba membatalkan perubahan setelah pernyataan. Kemudian, pindahkan kembali tes-tes yang diisolasi itu, dan lihat apakah mereka sekarang dapat lulus. Semoga ini membantu.

Sunting : Saya baru saja memperhatikan bahwa MockDisplayFieldService disediakan oleh ListingFormComponent , jadi meskipun kemungkinan memiliki instance baru yang dibuat untuk setiap pengujian, layanan bersama lainnya mungkin tidak.

wow solusi yang bagus. Mengujinya dalam satu file spesifikasi.

Sebelum

Finished in 6.282 secs / 7.383 secs @ 16:56:55 GMT+0200 (CEST)

Setelah

Finished in 0.17 secs / 0.202 secs @ 16:59:56 GMT+0200 (CEST)

Tetapi karena ini masih merupakan solusi, saya tidak bisa membiarkan grup dev saya mengeksploitasinya secara liar. Kami memiliki 1000+ unit test. Seluruh suite membutuhkan waktu sekitar 10 menit untuk berjalan. Akan senang melihat solusi resmi segera.

Saya mulai bertanya-tanya apakah ini tidak terlalu banyak untuk ditanyakan, karena berapa banyak kompilasi yang harus terjadi hanya untuk memiliki satu hal Angular (typescript, anotasi dekorator, penguraian template, semua modul-ng untuk DI, aot dalam beberapa kasus, dll.) - mungkin tidak masuk akal untuk mengharapkan mereka berjalan seperti JS murni atau bahkan tes TS murni? 🙁

Saya pikir tidak apa-apa jika testmodule lambat pada waktu konstruksi. Tetapi kita harus memiliki pilihan apakah akan membuat TestBed sebelum semua atau sebelum setiap kasus uji. Saat ini kami dipaksa untuk yang terakhir dan dengan demikian satu-satunya pilihan untuk mempercepat pengujian adalah mengacaukan banyak harapan menjadi satu unit pengujian tunggal. 👎

Sepenuhnya setuju dengan @giniedp di sini.

Dalam kasus kami, kami memiliki dua repositori terpisah, satu dengan 2500+ tes dan yang lainnya akan mencapai 1000 sebelum akhir bulan.

Yang pertama masih mengimpor banyak modul dalam konfigurasi TestBed, yang membutuhkan waktu 6-7 menit untuk menyelesaikan proses penuh. Saya sudah mulai menghapusnya satu per satu saat saya mengerjakan setiap fitur untuk meningkatkan kecepatan. Yang kedua, dibuat dengan cara setelah itu, saya telah mengatakan kepada tim saya untuk menggunakan tiruan sebanyak mungkin dan untuk menghindari mengimpor apa pun di testbed, dan secara umum, mengelompokkan banyak harapan dalam satu tes (yang IMO adalah salah). Ini jauh lebih cepat untuk uji coba penuh (tanpa kompilasi, sekitar 20 detik), tetapi waktu kompilasi masih memakan waktu setidaknya satu menit jika tidak hingga 2 atau 3, yang jelas mengganggu.

Saya ingin melihat peningkatan kinerja yang besar pada pengujian, karena di situlah saya kehilangan 50% waktu saya saat mengembangkan fitur.

@Shireilia coba Jest (dengan jest-preset-angular ) sehingga Anda dapat melewati langkah kompilasi, memparalelkan tes, dan memiliki mode tontonan yang lebih cerdas

@thymikee Terima kasih, saya akan mencobanya di minggu mendatang :)

@thymikee Terima kasih atas pekerjaan Anda di preset. Jest bekerja sangat baik untuk proyek saya. Beberapa pengamatan:

  • Jest berjalan lebih cepat daripada Karma karena melewati Webpack dan memiliki kemampuan untuk menjalankan beberapa file spesifikasi secara bersamaan. Namun, pengujian yang memerlukan komponen Angular untuk dipakai, sebenarnya membutuhkan waktu lebih lama untuk dijalankan daripada Karma di Chrome. Saya menduga masalahnya mungkin jsdom tidak seefisien Blink. Meskipun, beberapa penyelidikan lebih lanjut akan diperlukan.
  • Karena Jest tidak mengharuskan semua modul dimuat agar pengujian dapat berjalan, semakin sedikit modul yang harus diimpor oleh pengujian, semakin cepat penyelesaiannya. Saya menghabiskan beberapa waktu mengisolasi modul yang tidak harus diimpor (langsung atau tidak langsung), dan itu memberi saya sedikit peningkatan pada waktu putaran. (Misalnya, beberapa modul, yang tidak digunakan, diekspor oleh file index.ts dan berakhir di grafik impor.)
  • Solusi saya di atas juga berlaku saat menggunakan Jest.
  • Saya perhatikan bahwa file spesifikasi yang tidak memiliki nama unik akan merusak kemampuan IntelliJ untuk mengatur breakpoint di dalamnya. Saya akan mencoba membuat repo pengujian dan membuka masalah di repo Anda. (Sunting: masalah dibuka )

Terima kasih lagi. Jest itu luar biasa.

@vvasabi terima kasih atas solusinya yang secara drastis mempercepat pengujian saya. Satu pertanyaan, apakah ada cara untuk memiliki modul pusat yang baru saja digunakan oleh file spesifikasi. Misalnya, lanjutkan dan sertakan semuanya dalam satu modul lalu minta semua file spesifikasi menggunakannya?

Mungkin anti pola tetapi pelambatan bagi saya sekarang adalah perlu waktu untuk mengatur modul untuk setiap file spesifikasi. Saya memiliki 20 sejauh ini dan mereka tumbuh (satu untuk setiap komponen, layanan, arahan, dll) Jadi perlambatan datang ketika setiap file spesifikasi terkena. Setelah modul dibangun, pernyataan berikutnya berjalan dalam waktu singkat.

Sekali lagi terima kasih atas solusinya

@Rhonun Senang mendengar bahwa peretasan saya berhasil untuk Anda. Anda pasti dapat membangun modul pengujian umum. Cukup ekspor metadata modul dari satu file, dan file spesifikasi Anda dapat mengimpor dan menggunakan kembali.

Jika Anda ingin melangkah lebih jauh dan memastikan peretasan saya tidak terulang di setiap file spesifikasi, pertimbangkan untuk menyiapkan fungsi util seperti ini:

const resetTestingModule = TestBed.resetTestingModule,
  preventAngularFromResetting = () => TestBed.resetTestingModule = () => TestBed;
  allowAngularToReset = () => TestBed.resetTestingModule = resetTestingModule;
export const setUpTestBed = (moduleDef: TestModuleMetadata) => {
  beforeAll(async(async () => {
    resetTestingModule();
    preventAngularFromResetting();
    TestBed.configureTestingModule(moduleDef);
    await TestBed.compileComponents();
  }));

  afterAll(() => resetTestBed());
};

Kemudian, panggil saja di dalam blok describe terluar dari file spesifikasi Anda. Semoga ini membantu.

@vvasabi pekerjaan Anda memang bekerja dengan baik. saya mengurangi sekitar 250 tes dari 45 detik menjadi sekitar 15 detik. saya benar-benar berpikir tim ng harus menyediakan opsi untuk menyiapkan modul pengujian di beforeAll karena ini menghemat banyak waktu, terutama dalam spesifikasi dengan banyak waktu.

satu-satunya kelemahan sejauh ini adalah bahwa dalam beberapa spesifikasi interaksi dom tampaknya rusak dengan pendekatan baru (misalnya mengatur nilai input, mengklik btns )

kelemahan lainnya adalah sepertinya tidak mungkin untuk menggunakan beforeAll dengan pendekatan @vvasabi dalam beberapa spesifikasi dan beforeEach dalam spesifikasi lain dalam suite yang sama.

@dasAnderl Senang mendengar bahwa trik saya berhasil untuk Anda.

beberapa spesifikasi interaksi dom tampaknya rusak (misalnya mengatur nilai input, mengklik btns)

Karena modul pengujian sekarang digunakan kembali di beberapa pengujian, pengujian apa pun yang mengubah layanan bersama berpotensi memengaruhi hasil pengujian lainnya. Salah satu cara cepat untuk mengonfirmasi ini adalah dengan menjalankan tes yang rusak satu per satu. Jika mereka lulus saat dijalankan sendiri, maka mereka gagal karena TestBed yang tercemar.

kelemahannya adalah sepertinya tidak mungkin untuk menggunakan sebelumnyaSemua dalam beberapa spesifikasi dan sebelumnyaSetiap dalam spesifikasi lain di suite yang sama

Ya, solusinya akan memaksa Anda untuk mengelompokkan pengujian yang dapat menggunakan kembali konfigurasi TestBed yang sama dalam satu blok describe . Yang tidak bisa harus tinggal di kompartemen mereka sendiri. Saya ingin berargumen bahwa ini mungkin organisasi kode yang lebih bersih, terlepas dari apakah peretasan diterapkan atau tidak.

@vvasabi TERIMA KASIH!!! Ini sangat membantu dalam menurunkan waktu pengujian saya. Saya mungkin menambahkan terlalu banyak metadata untuk setiap pengujian yang berarti saya perlu memperbaiki komponen saya menjadi lebih modular (yang saya tidak yakin bagaimana melakukannya), tetapi sementara itu saran Anda telah menghasilkan keuntungan besar dalam kinerja eksekusi tes.

Sebelumnya: Executed 502 of 502 (4 FAILED) (16 mins 24.944 secs / 15 mins 51.429 secs)

Setelah: Executed 502 of 502 SUCCESS (2 mins 53.59 secs / 2 mins 5.877 secs)

Masih lebih lambat dari yang saya inginkan, tetapi peningkatan biiiiig!

(Ya, pengujian ini berjalan pada lingkungan yang sangat lambat, di mana kita sering mendapatkan waktu tunggu asinkron yang tidak terjadi secara lokal. Menjalankan pengujian lebih cepat tampaknya menyelesaikannya).

Jika orang lain membutuhkan detail yang lebih spesifik tentang cara menerapkan kode Anda, ini dia.

Buat file baru bernama src/test.common.spec.ts (FYI: Saya harus membuat beberapa perubahan kecil di sini dibandingkan dengan yang Anda miliki di atas). Ekstensi .spec.ts adalah agar file tidak disertakan dalam build - jika tidak, ng build akan mengeluh dengan kesalahan Cannot find name 'beforeAll' .

Tambahkan yang berikut ini ke dalam file:

import { TestBed, async, TestModuleMetadata } from '@angular/core/testing';

const resetTestingModule = TestBed.resetTestingModule,
  preventAngularFromResetting = () => TestBed.resetTestingModule = () => TestBed;
let allowAngularToReset = () => TestBed.resetTestingModule = resetTestingModule;

export const setUpTestBed = (moduleDef: TestModuleMetadata) => {
  beforeAll(done => (async () => {
    resetTestingModule();
    preventAngularFromResetting();
    TestBed.configureTestingModule(moduleDef);
    await TestBed.compileComponents();

    // prevent Angular from resetting testing module
    TestBed.resetTestingModule = () => TestBed;
  })().then(done).catch(done.fail));

  afterAll(() => allowAngularToReset());
};

Dalam file .component.spec.ts mungkin ada sesuatu seperti berikut:

describe('SomeComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ OneComponent, TwoComponent ],
      imports: [ SharedModule ],
      providers: [ HttpService ]
    }).compileComponents();
  }));

Ini kemudian menjadi:

describe('SomeComponent', () => {
  let moduleDef: TestModuleMetadata = {
    declarations: [ OneComponent, TwoComponent ],
    imports: [ SharedModule ],
    providers: [ HttpService ]
  };
  setUpTestBed(moduleDef);

Jalankan tes dengan ng test

Agak jelas, tetapi jangan gunakan pola ini setiap kali Anda membutuhkan komponen/layanan/apa pun yang Anda uji untuk disetel ulang di antara pengujian.

Saya menguji kerja @vvasabi, dan itu benar-benar berhasil! Test suit saya sekarang hampir 10x lebih cepat!

Apakah ada tanggapan resmi dari tim inti mengenai hal ini? Apakah ada rencana untuk membuatnya lebih cepat tanpa pekerjaan seperti ini?

EDIT: Saya baru saja menemukan PR #17710 yang akan menyelesaikan masalah ini, tetapi sudah lebih dari 2 bulan tanpa jawaban.

Saya juga memiliki masalah serupa di pelacak (https://github.com/angular/angular/issues/13963) mengenai fakta bahwa semua dependensi pengujian dikompilasi ulang untuk setiap metode pengujian. Saya pikir jika TestBed hanya akan dikompilasi sekali dan kemudian menggunakan kembali output yang dikompilasi untuk metode pengujian berikutnya, itu akan mempercepat semuanya _a lot_.

Saya baru saja menggunakan mekanisme ini... Saya memiliki 100 tes yang memakan waktu sekitar 2 menit48 detik. Mengonversinya, dan mengeksekusi dalam 8 detik

@robwormald dan @alxhub , bolehkah kami memiliki pembaruan tentang tapak ini? Ada juga PR terbuka untuk memperbaikinya tanpa umpan balik untuk waktu yang lama.

Salah satu fitur utama Angular adalah kemampuan untuk diuji, dan masalah kinerja ini benar-benar menjadi masalah. Saya memiliki aplikasi produksi dengan ~ 1500, dan tidak mungkin menggunakan TDD tanpa solusi buruk ini.

setuju. saya juga menggunakan solusinya, saya merangkumnya sehingga dapat digunakan dengan baik. namun ini harus merupakan penawaran bawaan (disiapkan di beforeAll). juga secara umum setup tes fells kikuk di ng. ini termasuk pengaturan .... dan injeksi layanan juga .... tidak ada perbandingan bagaimana reaksinya misalnya ... saya merasa itu bisa lebih mudah entah bagaimana ... saya merangkum untuk kegunaan yang lebih baik seperti ini:

biarkan comp: Comp;
setUpTestBed(CfModule, () => comp = new Comp(CfComponent));

untuk injeksi saya masih menggunakan hal-hal kikuk:

biarkan _restService: RestService;
biarkan _dataService: DataService;

beforeEach(inject([RestService, DataService], (restService: RestService, dataService: DataService) => {
_restService = restService;
_dataLayanan = dataLayanan;
}));

@dasAnderl Untuk menyuntikkan layanan, Anda juga dapat melakukan:

_restService = <RestService>TestBed.get(RestService);

Jika Anda ingin membuatnya generik (jadi tidak diperlukan casting), Anda dapat membuat metode util seperti ini:

const get = <T>(type: Type<T>): T => <T>TestBed.get(type);

Kemudian, contoh di atas menjadi:

_restService = get(RestService);

Seperti yang saya sebutkan di https://github.com/angular/angular/issues/13963 , masalah sebenarnya dengan solusi ini adalah bahwa dependensi tidak dibuat ulang di antara pengujian. Artinya, status apa pun yang dipegang oleh dependensi dapat menyebabkan masalah aneh. Yang saya pikir kita benar-benar perlukan adalah opsi untuk menggunakan kembali modul pengujian yang dikompilasi, karena sebagian besar waktu biasanya digunakan hanya dengan mengompilasi template untuk modul pengujian.

@vvasabi Terima kasih atas solusinya, lebih dari 200 tes yang membutuhkan waktu 50 detik sebelum sekarang menjadi 1,5 detik.

memiliki masalah yang sama dan menemukan ini:
https://github.com/Quramy/ngx-zombie-compiler

bekerja seperti pesona

Sayangnya itu tidak berfungsi dengan Angular 5 karena API yang mendasarinya berubah.

Namun, TestBed sekarang tampaknya men-cache set aotSummaries yang digunakan oleh pengujian. Jadi sepertinya semua yang diperlukan untuk mempercepat segalanya secara substansial akan menjadi opsi untuk memberi tahu TestBed untuk menggunakan kembali aotSummaries untuk metode spesifikasi berikutnya alih-alih menghapus dan membuatnya kembali untuk setiap metode spesifikasi.

Bagi siapa saja yang mungkin tertarik : dengan rilis angular 5, saya akhirnya bisa berpindah dari Karma ke Jest. Hasil untuk 3250 tes pada monorepo kami adalah:
Karma : 12 menit (2 menit waktu efektif, 10 kompilasi) full run
Lelucon: 126 detik full run

Selain itu, saya telah menginstal plugin vscode untuk menjalankan tes dengan cepat di editor satu per satu.
Ini adalah keuntungan besar yang saya bahkan tidak bisa mulai mengatakan betapa bahagianya saya tentang hal itu :)

Dan saya pikir dengan menggunakan solusi @vvasabi saya mungkin mendapatkan hasil yang lebih baik. Akan mencobanya.

Terima kasih banyak @thymikee karena telah mengarahkan saya ke Jest.
Jika ada yang ingin info lebih lanjut tentang ini, jangan ragu untuk menghubungi saya :)

Kita harus membuat contoh repo dengan praktik terbaik untuk pengaturan pengujian - Memiliki cache template atau menyiapkan ringkasan AOT.

@vikerman Itu akan luar biasa . Ini mungkin tidak terlalu rumit, tetapi karena tidak terdokumentasi, saya tidak tahu bagaimana melakukan sesuatu dengan ringkasan AOT.

@vikerman @Shireilia dapatkah Anda memberikan beberapa contoh di suatu tempat tentang cara mendapatkan JEST dan mungkin dikombinasikan dengan peretasan @vvasabi yang dapat menjadi titik awal untuk praktik pengujian cepat yang baik? Kami berjuang untuk mendapatkan solusi yang tepat untuk bekerja dan mungkin tertarik untuk melihat bagaimana Anda bisa menyelesaikannya.

@blackholegalaxy yakin, saya masih harus mengimplementasikan @vvasabi hack (persyaratan bisnis membutuhkan terlalu banyak waktu akhir-akhir ini), tetapi setidaknya membuat lelucon. Saya tidak tahu apakah saya akan punya waktu untuk menyiapkan repo dalam beberapa hari mendatang, tetapi saya dapat membagikan konfigurasi kami di sini sebagai permulaan cepat.

Kami menggunakan https://github.com/gdi2290/angular-starter sebagai starter. Tidak banyak yang berubah kecuali cara kami menangani terjemahan (seharusnya tidak berdampak apa pun).

Juga, pastikan untuk membaca dan mengikuti artikel @thymikee dengan topik: https://www.xfive.co/blog/testing-angular-faster-jest/ yang saya gunakan untuk membuat semuanya berfungsi. File yang dijelaskan dalam postingnya adalah yang akan saya taruh di bawah.

Pertama, kami tidak menyentuh tes selain memperbaiki beberapa pernyataan impor yang salah, jadi jika Anda sudah menggunakan karma + melati, Anda tidak perlu mengubah apa pun di dalamnya. Itu penting, karena @thymikee merekomendasikan untuk mengubah beberapa hal terkait matcher dan spy, tapi kami tidak harus melakukannya. Jadi, pada awalnya, saya sangat menyarankan untuk membiarkan file pengujian Anda tidak tersentuh.

Dalam paket json kami, saya menambahkan aturan ini:

<br i="18"/>
"jest": {<br i="19"/>
    "globals": {<br i="20"/>
      "ts-jest": {<br i="21"/>
        "tsConfigFile": "src/tsconfig.spec.json"<br i="22"/>
      },<br i="23"/>
      "__TRANSFORM_HTML__": true<br i="24"/>
    },<br i="25"/>
    "preset": "jest-preset-angular",<br i="26"/>
    "setupTestFrameworkScriptFile": "<rootdir i="27">/src/setupJest.ts",<br i="28"/>
    "transformIgnorePatterns": [<br i="29"/>
      "<rooddir i="30">/node_modules/(?!@ngrx|@VENDOR/FRAMEWORK-NAME)"<br i="31"/>
    ],<br i="32"/>
    "testRegex": "(/__tests__/.*|\.(spec))\.(ts|js)$"<br i="33"/>
  }<br i="34"/>
</rooddir></rootdir>

Sebagian besar masalah yang saya miliki untuk membuatnya berfungsi adalah karena kami memiliki kerangka kerja khusus (layanan yang sebagian besar menerapkan pola hypermedia untuk aplikasi kami, tetapi juga beberapa validator formulir, berbagai utilitas untuk log, manajemen toko, dll ...) dan harus menambahkan itu di transformIgnorePatterns:

<br i="39"/>
 "<rooddir i="40">/node_modules/(?!@ngrx|@VENDOR/FRAMEWORK-NAME)"<br i="41"/>
</rooddir>

Hapus apa yang tidak perlu di regex :)

Untuk sedikit lebih banyak masukan, kami harus mengikuti praktik terbaik tentang cara kami mengelolanya, dan itu menyediakan versi yang dikompilasi, bukan file .ts dari kerangka kerja. Setelah itu, semuanya berjalan baik :)

File jestGlobalMocks.ts kami:

<br i="9"/>
import 'rxjs/add/observable/of';<br i="10"/>
import 'rxjs/add/observable/throw';<br i="11"/>
import 'rxjs/add/observable/empty';<br i="12"/>
import 'rxjs/add/observable/forkJoin';<br i="13"/>
import 'rxjs/add/observable/timer';<br i="14"/>
import 'rxjs/add/observable/fromEvent';<br i="15"/>
import 'rxjs/add/observable/merge';<br i="16"/>
import 'rxjs/add/observable/interval';<br i="17"/>
import 'rxjs/add/observable/combineLatest';<br i="18"/>
import 'rxjs/add/operator/map';<br i="19"/>
import 'rxjs/add/operator/switchMap';<br i="20"/>
import 'rxjs/add/operator/share';<br i="21"/>
import 'rxjs/add/operator/do';<br i="22"/>
import 'rxjs/add/operator/catch';<br i="23"/>
import 'rxjs/add/operator/filter';<br i="24"/>
import 'rxjs/add/operator/take';<br i="25"/>
import 'rxjs/add/operator/combineLatest';<br i="26"/>
import 'rxjs/add/operator/debounceTime';<br i="27"/>
import 'rxjs/add/operator/delay';<br i="28"/>
import 'rxjs/add/operator/distinctUntilChanged';<br i="29"/>
import 'rxjs/add/operator/skip';<br i="30"/>
import 'rxjs/add/operator/last';<br i="31"/>
import 'rxjs/add/operator/finally';<br i="32"/>
import 'rxjs/add/operator/takeWhile';<br i="33"/>
import 'rxjs/Observable';<br i="34"/>
import 'rxjs/Subject';

const tiruan = () => {
biarkan penyimpanan = {};
kembali {
getItem: (key: any) => kunci di penyimpanan ? penyimpanan[kunci] : nol,
setItem: (kunci: apa saja, nilai: apa saja) => penyimpanan[kunci] = nilai || '',
removeItem: (kunci: apa saja) => hapus penyimpanan[kunci],
hapus: () => penyimpanan = {},
};
};

Object.defineProperty(jendela, 'localStorage', { nilai: mock() });
Object.defineProperty(jendela, 'sessionStorage', { nilai: mock() });
Object.defineProperty(jendela, 'getComputedStyle', {
nilai: () => ['-webkit-appearance']
});
Object.defineProperty(document.body.style, 'transform', {
nilai: () => {
kembali {
dapat dihitung: benar,
dapat dikonfigurasi: benar
};
},
});

Kami memusatkan impor untuk RXJS dalam file ini, akan lebih baik di masa mendatang ;)

setupJest.ts:

<br i="8"/>
import 'jest-preset-angular';<br i="9"/>
import './jestGlobalMocks';<br i="10"/>

tsconfigs.spec.json:

<br i="16"/>
{<br i="17"/>
  "compilerOptions": {<br i="18"/>
    "target": "es5",<br i="19"/>
    "module": "commonjs",<br i="20"/>
    "moduleResolution": "node",<br i="21"/>
    "emitDecoratorMetadata": true,<br i="22"/>
    "experimentalDecorators": true,<br i="23"/>
    "allowSyntheticDefaultImports": true,<br i="24"/>
    "sourceMap": true,<br i="25"/>
    "skipLibCheck": true,<br i="26"/>
    "noEmit": true,<br i="27"/>
    "noEmitHelpers": true,<br i="28"/>
    "importHelpers": true,<br i="29"/>
    "strictNullChecks": false,<br i="30"/>
    "allowUnreachableCode": false,<br i="31"/>
    "allowUnusedLabels": false,<br i="32"/>
    "noUnusedLocals": true,<br i="33"/>
    "noUnusedParameters": true,<br i="34"/>
    "removeComments": true,<br i="35"/>
    "noImplicitAny": true,<br i="36"/>
    "suppressImplicitAnyIndexErrors": true,<br i="37"/>
    "lib": [<br i="38"/>
      "dom",<br i="39"/>
      "es6"<br i="40"/>
    ],<br i="41"/>
    "baseUrl": "./src",<br i="42"/>
    "paths": {<br i="43"/>
      "@angular/<em i="44">": [<br i="45"/>
        "node_modules/@angular/</em>"<br i="46"/>
      ]<br i="47"/>
    },<br i="48"/>
    "typeRoots": [<br i="49"/>
      "node_modules/@types"<br i="50"/>
    ],<br i="51"/>
    "types": [<br i="52"/>
      "hammerjs",<br i="53"/>
      "jest",<br i="54"/>
      "node",<br i="55"/>
      "source-map",<br i="56"/>
      "uglify-js",<br i="57"/>
      "webpack",<br i="58"/>
      "fuse"<br i="59"/>
    ]<br i="60"/>
  },<br i="61"/>
  "exclude": [<br i="62"/>
    "node_modules",<br i="63"/>
    "dist"<br i="64"/>
  ],<br i="65"/>
  "awesomeTypescriptLoaderOptions": {<br i="66"/>
    "forkChecker": true,<br i="67"/>
    "useWebpackText": true<br i="68"/>
  },<br i="69"/>
  "compileOnSave": false,<br i="70"/>
  "buildOnSave": false,<br i="71"/>
  "atom": {<br i="72"/>
    "rewriteTsconfig": false<br i="73"/>
  }<br i="74"/>
}<br i="75"/>

Nomor versi lelucon kami yang sebenarnya:

<br i="80"/>
"@types/jest": "22.1.1",<br i="81"/>
"jest": "22.2.1",<br i="82"/>
"jest-preset-angular": "5.0.0",<br i="83"/>

Dan itu seharusnya.

PS : kami menggunakan Angular 5+.

Saya pikir masalahnya adalah initTestEnvironment dipanggil pada setiap tes yang dijalankan jadi jika Anda berada dalam mode tontonan, satu-satunya cara yang baik adalah dengan men-cache templat yang dikompilasi. Angular saat ini tidak mengekspos cache https://github.com/angular/angular/blob/master/packages/compiler/src/jit/compiler.ts#L41

Jika memungkinkan untuk memberikan implementasi penyimpanan cache khusus untuk pengujian maka kita dapat menyimpan cache pada objek __karma__ global seperti ini.

__karma__.compiledTemplateCache = __karma__.compiledTemplateCache || new Map<Type, CompiledTemplate>();

@Injectable()
class TemplateCacheStore {
  getTemplateCache(meta) {
    // ... get from global __karma__.compiledTemplateCache
  }

  setTemplateCache(meta) {
    // set to global __karma__.compiledTemplateCache
  }
}

getTestBed().initTestEnvironment(
  BrowserDynamicTestingModule.configure({ templatesCacheStore: TemplateCacheStore }),
  platformBrowserDynamicTesting()
);

Peretasan oleh @vvasabi sepertinya akan berhasil, setidaknya dalam beberapa situasi. Tetapi memeriksa dan mengubah ratusan file spesifikasi akan sangat memakan waktu. Dan tidak ada yang tahu bagaimana perubahan pada versi Angular yang akan datang akan memecahkan solusinya.

Intinya adalah bahwa perlu menerapkan peretasan seperti itu benar-benar tidak masuk akal. Seharusnya tidak perlu 10 menit untuk menjalankan pengujian unit UI. Ini pada dasarnya membatalkan inti dari TDD.

Yang lebih membuat frustrasi adalah bahwa semua masalah ini akan dibatalkan jika kita dapat memberi tahu Angular untuk menggunakan kembali ringkasan AoT dan/atau menggunakan kembali modul pengujian yang dikompilasi. Masalah ini telah berlangsung selama lebih dari 18 bulan, dan saya bingung karena orang-orang Angular sepertinya mengabaikannya.

Saya tidak mengerti semua cara kerja bagian dalam TestBed dan kompiler uji, tetapi dari apa yang saya tahu, ini seharusnya cukup mudah dilakukan untuk seseorang yang benar-benar memahami internal. Angular tampaknya sudah membuat ringkasan AoT di memori, jadi mengekspos flag ke cache dan menggunakannya kembali dalam file spesifikasi alih-alih membuatnya kembali setiap kali tampak seperti perubahan langsung.

@vikerman apakah ada pemikiran lebih lanjut yang dimasukkan ke dalam dokumentasi atau contoh untuk menggunakan cache templat atau menggunakan kembali ringkasan AoT?

Saya setuju... Saya merasa divalidasi oleh fakta bahwa masalah ini tidak hanya memengaruhi kami karena beberapa kesalahan saya, dan sangat menggembirakan melihat komunitas mengajukan solusi, tetapi juga mengecewakan karena kami harus menerapkannya peretasan tanpa peta jalan dari anggota tim inti... Pada dasarnya saya menyerah mencoba membuat tim saya menulis tes unit untuk komponen... semoga tes integrasi akan membantu kami dengan baik.

Saya telah membuat permintaan fitur di #22797 yang membahas masalah ini juga.

Itu akan:

  • memberikan pengalaman "render dangkal" yang lebih aman daripada NO_ERRORS_SCHEMA .
  • mencegah masalah karena harus mendeklarasikan (atau mengejek) seluruh grafik ketergantungan dari komponen yang diuji.
  • menjaga jaminan kebenaran sehubungan dengan pemilih dan input/output komponen anak, membuat pengujian unit tahan terhadap kerusakan melalui refactoring.

Silakan lihat dan berikan umpan balik, karena saya pikir ini akan sangat meningkatkan pengalaman pengujian aplikasi Angular.

@michaelbromley Ini adalah ide bagus dan saya menyukainya, tetapi sepertinya ini adalah opsi paralel daripada perbaikan nyata untuk masalah mendasar (bahwa komponen dikompilasi ulang berulang kali ketika tidak perlu). Terlepas dari itu, saya setuju dengan ide mengejek 100%.

Juga hanya untuk menunjukkan bagaimana masalah ini tampaknya dapat dipecahkan, saya menyiapkan fungsi global yang dipanggil di blok beforeAll() dari semua pengujian saya. Itu melakukan peretasan yang bodoh dan konyol untuk menggantikan logika di resetTestingModule() .

Saya tidak akan merekomendasikan siapa pun yang benar-benar menggunakan ini, tetapi tampaknya berfungsi dengan baik dan mempercepat hampir 40%. Maksud saya bukan untuk menawarkan solusi bagi siapa saja untuk digunakan, tetapi hanya untuk menunjukkan betapa mudahnya mempercepat banyak hal hanya dengan menggunakan kembali komponen yang dikompilasi:

let tb: any = getTestBed();

// Switch back to original resetTestingModule() function if it exists
if( ( window as any )[ "__testCache" ] ) tb.resetTestingModule = ( window as any )[ "__testCache" ].realResetTestingModule;

// Do a reset on the testing module.
TestBed.resetTestingModule();

// Store reference to original resetTestingModule() function.
let realResetTestingModule = tb.resetTestingModule;
( window as any )[ "__testCache" ] = { realResetTestingModule: tb.resetTestingModule };

// Replace original resetTestingModule() with a custom version that re-uses the moduleFactory and compiler.
// This cuts the test execution time by roughly 40%.
tb.resetTestingModule = () => {
  let mf = tb._moduleFactory;
  let compiler = tb._compiler;
  realResetTestingModule.apply( tb );
  tb._moduleFactory = mf;
  tb._compiler = compiler;
};

@vmandy (saya tahu saya terlambat) .. tetapi menghadapi masalah unit lambat ini, kesalahan kehabisan memori juga

Dua hal yang saya lakukan untuk menyiasatinya adalah:

1) Semua variabel yang digunakan di beforeEach, dideklarasikan di bagian atas file di dalam deskripsi pertama. misalnya

describe("FooComponent", () => {
 let var0: TypeFoo;
 let var1: TypeFoo;
 let var2: TypeFoo;

 beforeEach(() => {
   var0 = // something big
   var1 = // something big
   var2 = // something big
 })
 afterEach(() => {
   var0 = undefined
   var1 = undefined
   var2 = undefined
 })

 // my other 'describe', 'beforeEach' and 'it' blocks afterwards
});

Ini akan memperbaiki masalah kehabisan memori saya.

2) Untuk mempercepat. Ganti semua bit IonicModule Anda dengan NO_SCHEMA_ERRORS misalnya:

Mengganti:

imports: [
 IonicModule.forRoot(component),
]

dengan:

schemas: [
 NO_ERRORS_SCHEMA
]

Dan kalian semua baik!

@vvasabi @BurningDog @brian428 : apakah peretasan ini masih berfungsi dengan angular 5.1.3?
karena saya telah mengonfigurasi setelan uji dengan cara yang sama dan dapat menjalankan file spesifikasi tunggal. tetapi ketika saya mencoba menjalankan semua file spesifikasi, yang pertama lolos dan semua kasus uji lainnya gagal dengan kesalahan berikut.

Failed: Uncaught (in promise): Error: Illegal state: Could not load the summary for directive AccountDetailsComponent.

jika bukan solusi apa yang mungkin tersedia untuk saya, karena setelan pengujian kami saat ini membutuhkan waktu sekitar 10 hingga 12 menit untuk menjalankan kasus uji dan jika kami mengalikan angka ini dengan jumlah sumber daya, kami menghabiskan banyak waktu hanya untuk menjalankan kasus uji.

@kedar9444 Proyek saya ada di Angular 5.2.0, dan saya tidak perlu mengubah cara saya mengimplementasikan peretasan saya sejak saya menerbitkannya tahun lalu. Jika Anda dapat membagikan beberapa kode Anda yang mereproduksi masalah, mungkin orang dapat melihatnya.

@vvasabi : terima kasih sudah menjawab saya bisa bernafas sekarang!!! mari kita lihat apa yang telah saya lakukan dalam kode saya.

Saya telah membuat satu file konfigurasi untuk semua file spesifikasi:

export const configureTestSuite = () => {
    const testBedApi: any = getTestBed();
    const originReset = TestBed.resetTestingModule;

    TestBed.resetTestingModule();
    TestBed.resetTestingModule = () => TestBed;

    afterEach(() => {
        testBedApi._activeFixtures.forEach((fixture: ComponentFixture<any>) => fixture.destroy());
        testBedApi._instantiated = false;
    });

    afterAll(() => {
        TestBed.resetTestingModule = originReset;
        TestBed.resetTestingModule();
    });
}

kemudian digunakan yang sama dalam kasus uji aktual:

describe('Component: xxxComponent', () => {
    configureTestSuite();

    beforeAll(done => (async () => {

        TestBed.configureTestingModule({
            imports: [SharedModule, BrowserModule...],
            declarations: [xxxComponent, yyyComponent],
            schemas: [CUSTOM_ELEMENTS_SCHEMA],
            providers: [
                { provide: xxxService, useClass: xxxServiceStub }
                ...
            ],

        })

        await TestBed.compileComponents();

    })().then(done).catch(done.fail));

    describe('Component: templateFormComponent', () => {

        let xxxfixture: ComponentFixture<xxxComponent>;
        let xComponent: xxxComponent;

        let yyyfixture: ComponentFixture<yyyComponent>;
        let yComponent: yyyComponent;

        let xService: xxxService
        let el: HTMLElement;

        beforeEach(() => {

            xxxfixture = TestBed.createComponent(xxxComponent);
            xComponent = xxxfixture.componentInstance;

            xService = TestBed.get(xxxService);
        });
    });
});


dengan implementasi ini jika saya mencoba menjalankan file spesifikasi tunggal [dengan fdescribe] itu memberikan hasil yang tepat, tetapi jika saya mencoba menjalankan semua file spesifikasi sekaligus, konfigurasi menjalankan file spesifikasi pertama dengan benar tetapi melalui kesalahan untuk semua file spesifikasi lainnya .

dan kesalahannya adalah:

Failed: Uncaught (in promise): Error: Illegal state: Could not load the summary for directive xxxComponent.

jika Anda membutuhkan lebih banyak data, silakan sebutkan di komentar. Terima kasih sebelumnya. :)

berikut beberapa detailnya:

Angular CLI: 1.7.4
Node: 9.11.1
OS: win32 x64
Angular: 5.2.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.7.4
@angular-devkit/core: 0.0.29
@schematics/package-update: 0.3.2
typescript: 2.4.2
webpack: error

di sini adalah kode untuk mereproduksi masalah.

https://github.com/kedar9444/unit-test-performance

@kedar9444 Repo Github sangat membantu. Yang saya lakukan untuk memperbaiki masalah Anda adalah memiliki ini di configure-test-suit.ts :

beforeAll(() => {
  TestBed.resetTestingModule();
  TestBed.resetTestingModule = () => TestBed;
});

Anda membutuhkan 2 baris itu dalam blok beforeAll . Semoga ini membantu.

Setelah menambahkan bagian beforeAll saya mendapatkan kesalahan ini: Cannot configure the test module when the test module has already been instantiated.
Saya memanggil configureTestingModule di kait beforeEach .

@blacksonic Ide di balik peretasan ini adalah menghemat waktu dengan tidak perlu memanggil configureTestingModule sekali per blok it untuk mengkompilasi ulang komponen. Dengan demikian, keluhan bahwa the test module has already been instantiated akan hilang jika Anda hanya menelepon configureTestingModule sekali per blok describe terluar.

Saya membuat permintaan tarik untuk masalah ini tahun lalu tetapi tidak pernah mendapat umpan balik dari tim Angular. (#17710). Kami menggunakan kode yang sangat mirip dengan permintaan tarik di perusahaan saya dalam aplikasi Angular dengan lebih dari 1.000 unit test.

Pengujian di Angular benar-benar bermasalah saat ini karena masalah kinerja ini. Kami juga menggunakan 1000+ aplikasi pengujian, dan karena peretasan ini kami dapat beralih dari sekitar 30 menit menjadi sekitar 3 menit untuk uji coba penuh. Ini benar-benar buruk, uji coba 30m tidak dapat diterima. Dan bahkan 3m buruk untuk pengujian unit hanya untuk 1000+ pengujian.

Masalahnya terletak pada semua rendering dan ketergantungan pada browser. Saya berharap sudut beralih ke sesuatu seperti JSDom ASAP (dan jauh dari Karma dan Jasmine), jika tidak, tes tidak akan pernah secepat yang seharusnya.

@giggio Anda sudah dapat menggunakan JSDom dengan tes unit Angular melalui Jest. Cari komentar thymikee di utas ini.

Masalahnya bukan pada pendekatan DOM asli vs palsu. tes berbasis jsdom dengan Jest dapat memotong waktu berjalan menjadi setengah . Masih terlalu lambat bahkan untuk selusin tes. Saya khawatir Jest masih harus menempuh jalan panjang untuk memanfaatkan paralelisme & DOM palsu yang secara teori terlihat jauh lebih baik daripada implementasi saat ini. Tentu saja masyarakat akan diuntungkan dengan hal ini.

Untuk mencapai penurunan sepuluh kali lipat dalam waktu berjalan, Angular perlu mengizinkan modul pengujian untuk dikonfigurasi dalam blok beforeAll() . Saat ini hanya membuangnya secara naif setelah setiap tes. Ini harus diprioritaskan sampai kompilasi caching berlangsung. Kami tidak membutuhkan solusi _best_ sekarang, tetapi kami layak mendapatkan solusi non-naif setidaknya sampai sesuatu yang lebih baik dibuat.

Jadi apakah kita ingin memiliki speedup 2x atau 10x? Dan sampai kapan kita mau menunggu?

Sesuatu yang telah bekerja dengan baik untuk kami saat menguji pustaka komponen kami adalah membaginya menjadi pustaka yang lebih kecil jika memungkinkan, kemudian menjalankan pengujian pustaka ini secara paralel pada node CI, sementara juga menggunakan plugin Karma seperti karma-paralel untuk memparalelkan lebih jauh.

Itu, ditambah dengan mengesampingkan resetTestingModule dan mengelola reset secara manual seperti yang disebutkan sebelumnya di utas ini, telah membantu mengurangi waktu di 6000+ spesifikasi cukup sementara kami menunggu solusi berbasis Bazel / caching build.

kita tidak harus bergantung pada trik CI untuk mempercepat tes. Saya pikir @awerlang benar: Angular harus bertindak dengan cara pengujian dijalankan dengan benar tanpa membuat ulang seluruh komponen jika pengaturan dapat konsisten di antara pengujian.

Hal yang membuat frustrasi tentang ini adalah, seperti yang saya tunjukkan sebelumnya di utas ini , logika untuk hanya memegang modul pengujian yang dikompilasi adalah sepele. Saya hanya tidak tahu bagaimana "dengan benar" mengubah kode Angular yang sebenarnya di dalam TestBed atau Compiler untuk mengizinkan ini, atau saya sudah lama mengirim permintaan tarik.

Saya menyadari bahwa mungkin ada kasus Edge di mana solusi saya tidak akan berfungsi (misalnya di mana spesifikasi individu mengubah/mengganti bagian yang berbeda dari modul pengujian), tetapi memiliki tanda untuk mengaktifkan atau menonaktifkan cache hasil kompilasi juga akan menjadi sederhana tambahan.

Saya benar-benar bingung bahwa masalahnya sudah seburuk ini selama ini, namun tidak ada seorang pun di tim yang tampaknya memprioritaskan ini.

Ada pembaruan tentang ini? Apakah ada upaya yang dilakukan untuk mempercepat pelaksanaan tes saat menggunakan TestBed ? Bagaimana proyek yang lebih besar di Google yang menggunakan Angular menangani tes lambat?

Saya baru saja LGTM @oocx https://github.com/angular/angular/pull/17710.
Di Google, pengujian dilakukan dengan AOT dengan memberikan NgSummaries ke TestModuleMetadata
Ini adalah cara yang disarankan untuk mendapatkan kinerja terbaik, tetapi kami memahami bahwa mungkin tidak mudah untuk mendapatkan file NgSummary.
Dengan Ivy segera keluar, AOT akan menjadi default. Sementara itu, silakan coba saran di PR.

@kyliau Apakah Anda punya contoh melewati ringkasan AOT di sini?

@kyliau Terima kasih atas tanggapannya. Saya sudah menggunakan salah satu solusi yang disebutkan sebelumnya di utas ini. Pertanyaan saya lebih tentang kapan dukungan resmi untuk ini akan mendarat di inti. Saya akan mengikuti PR untuk melihat kapan itu berhasil.

Pertanyaan tentang apa yang Anda sebutkan tentang Ivy. Dengan Ivy menjadikan AOT sebagai default, apakah alur kerja untuk pengujian menggunakan TestBed berubah?

Halo semuanya! Saya mencoba menerapkan pendekatan ini dengan fungsi configureTestSuite .
Apakah seseorang menghadapi masalah ketika dengan pendekatan ini Karma mengatakan bahwa saya menjalankan 'Empty test suite'?

Di sini kode tes - https://Gist.github.com/alex-kel/e549a845e37b00678a17da7340432683

@awerlang @vvasabi mungkin kalian bisa membantu saya?

Halo,
Di tim saya, kami hanya menggunakan ng-bullet untuk mempercepat pengujian berbagai proyek kami.
Ini memungkinkan perolehan yang mengesankan (mis: 2m30s hingga 30s), tanpa masalah untuk saat ini.

Saya mencoba menggunakan ng-bullet tetapi masih mendapatkan "Empty test suite" yang sama
pesan...
, 29 е. 2018 . 13:47, Michael [email protected] :

Halo,
Di tim saya, kami hanya menggunakan ng-bullet
https://www.npmjs.com/package/ng-bullet untuk mempercepat tes kami
proyek yang berbeda.
Ini memungkinkan perolehan yang mengesankan (mis: 2m30s hingga 30s), tanpa masalah untuk
saat ini.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/12409#issuecomment-425635583 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AGshdnkc_522rtrlJCtn2TmcvZSlN4wAks5uf0_EgaJpZM4KcS5I
.

@kekel87 itu brilian bahwa seseorang mengatasi masalah itu dengan API perpustakaan yang rapi! Ketika saya membuka masalah, saya tidak pernah bermimpi itu akan datang 2 tahun kemudian dari pihak ke-3.

Jadi @kyliau , dengan Ivy sekarang tampaknya tertunda, dapatkah Anda memberikan panduan tentang cara menyediakan NgSummaries? Apakah ada beberapa contoh kode untuk ini? Apakah masih bekerja dengan v7?

Terima kasih,
Kris

Saya telah mengumpulkan sedikit pembantu untuk menggunakan kembali hasil kompilasi untuk modul yang diberikan untuk semua pengujian Anda. Saya akan senang mendengar jika itu membantu orang lain. Ini adalah fungsi precompileForTests() di s-ng-dev-utils .

Sepertinya API yang tersedia untuk hal-hal seperti ini terus berubah, jadi kita akan lihat berapa lama ini bisa bertahan. Saya membuat ini dengan Angular 8. Sepertinya dukungan yang lebih baik untuk AoT dalam pengujian mungkin datang dengan Ivy? Jadi mungkin solusi ini tidak perlu bertahan lama! 🤞

Ini terlihat sebagai masalah penting, dan menjadi lebih kritis saat modul Anda berkembang.

Idealnya itu hanya mungkin untuk menjalankan TestBed.configureTestingModule di dalam beforeAll .

Itu akan menjadi solusi yang paling elegan.

Posting blog di bawah ini menjelaskan cara melewati langkah kompilasi ulang sehingga Anda dapat menggunakan injeksi ketergantungan nyata, mengkompilasi komponen sekali, dan kemudian menjalankan semua tes. Terima kasih kepada Nikita Yakovenko karena telah membagikan solusi ini!

https://blog.angularindepth.com/angular-unit-testing-performance-34363b7345ba.

Yap, @davidjpfeiffer , seperti yang saya sebutkan di atas , pembaruan posting blog ini berbicara tentang ng-bullet .

Apalagi hampir semua proyek tim saya telah ada selama hampir satu tahun, dan masih bekerja dengan sangat baik! Dikombinasikan dengan ng-mock , Itu benar-benar bekerja dengan baik!

Yang lebih mengganggu adalah bahwa masalah dengan TestBed ini sudah ada selama bertahun-tahun.

Kami memiliki lebih dari 600 tes dalam proyek kami dan dibutuhkan lebih dari 5 menit untuk menjalankan semuanya. Atau 3 menit untuk memulai tes sederhana. Saya setuju dengan @ brian428 "Ini pada dasarnya membatalkan inti dari TDD.".

Bekerja dengan cara ini sangat sangat buruk.

@MatMercer sesuatu yang sangat membantu saya adalah pembaruan Angular "baru-baru ini" yang memungkinkan Anda menentukan flag --include , jadi selama pengembangan saya menyiapkan sesuatu seperti:

git diff HEAD^ --name-only | xargs -L 1 dirname | sort | uniq dll dan akhirnya mendapatkan output seperti {dir1/a/b/*.ts,dir2/a/c/*ts} yang saya berikan ke ng test --include ${test_glob?} .

Ini jelek, tetapi Anda selalu dapat menelepon ng test --include dir/i/am/working/on/ juga

Saya dapat bergerak lebih cepat (terutama jika digabungkan dengan garpu ng-bullet ). Dan seperti yang telah disebutkan orang lain, karma-parallel juga membantu menurunkan pengujian 4k dari 20 menit menjadi 5 menit pada rangkaian pengujian lengkap

@Goodwine Saat ini saya menggunakan angular 5.2.0. ng-bullet untuk beberapa alasan menyebabkan masalah dengan npm (masalah ketergantungan rekan). Tentang karma-paralel, itu hanya menurunkannya dari 5:20 menjadi 4:40, bukan perbedaan besar. Saya mencoba menggunakan saran Anda, tetapi karena Anda sudah mengatakan

apa yang benar-benar membantu saya adalah pembaruan Angular "baru-baru ini"

Karena saya menggunakan 5.2.0, saya tidak memiliki fitur "terbaru".

Tentang solusi lain yang disajikan di sini, saya tidak dapat menggunakannya, karena pengujian banyak mengubah komponen/menggunakan spy . Aku benar-benar tidak tahu harus berbuat apa lagi dari sini. Mungkin memutakhirkan versi Angular dan berdoa agar itu berfungsi?

anda tidak memerlukan ketergantungan ng-bullet . Implementasinya cukup sederhana.

inilah yang kami gunakan dalam proyek kami

import { getTestBed, TestBed } from "@angular/core/testing"

export function configureTestSuite(configureAction: () => Promise<any>) {
  const testBedApi = getTestBed()
  const originReset = TestBed.resetTestingModule
  beforeAll(() => {
    TestBed.resetTestingModule()
    TestBed.resetTestingModule = () => TestBed
  })
  if (configureAction) {
    beforeAll((done) => {
      configureAction().then(done).catch(done.fail)
    })
  }
  afterEach(() => {
    testBedApi["_activeFixtures"].forEach((fixture) => fixture.destroy())
    testBedApi["_instantiated"] = false
  })
  afterAll(() => {
    TestBed.resetTestingModule = originReset
    TestBed.resetTestingModule()
  })
}

dengan itu Anda tidak memiliki masalah ketergantungan rekan. Selanjutnya Anda mengendalikan perilaku sehingga Anda dapat mengembalikannya kapan saja, tanpa mengubah tes Anda.

@MatMercer

Karena saya menggunakan 5.2.0, saya tidak memiliki fitur "terbaru".

Ketahuilah bahwa versi sudut hanya didukung untuk waktu yang terbatas [ docs ]
Dan juga, jika tim Angular meningkatkan kinerja pengaturan pengujian seperti yang Anda inginkan, itu akan menjadi
versi yang lebih baru, jadi Anda harus memutakhirkan, sebenarnya tidak ada solusi*.

Pada Masalah lain tentang sesuatu yang serupa, seseorang menyebutkan bahwa rilis Angular berikutnya dengan Ivy dan R3SomethingTestBed membuat pengaturan pengujian berjalan lebih cepat bahkan tanpa AOT.
https://github.com/angular/angular-cli/issues/6650

  • Saya menemukan solusi, itu tidak cantik, pada dasarnya Anda menggunakan sesuatu seperti git diff HEAD^ --name-only dan memproses data untuk menghasilkan sesuatu yang dapat Anda teruskan ke const context = require.context(... dalam file test.ts , tetapi itu berarti Anda harus membuat ulang file HTML setiap kali (yang saya lakukan menggunakan tugas teguk menonton perubahan untuk file TS/HTML)

(Penafian: Saya bukan anggota tim Angular)

Saat ini saya sedang memfaktorkan ulang pengujian komponen saya (49 file) untuk menggunakan ng-bullet yang telah saya tambahkan secara manual dari sini ke dalam proyek saya seperti yang dikatakan @giniedp . Cuplikan yang diberikan @giniedp agak ketinggalan jaman jadi saya memberi peringatan kepada pendatang baru: gunakan ng-bullet dari sini, ini diperbarui dan berfungsi dengan angular 5.2.0 saya .

@Goodwine Memang, apa yang Anda katakan benar, jika mereka akan memberikan peningkatan kinerja di rilis berikutnya tidak ada "solusi", kami tetap harus memutakhirkannya.

Setelah saya menyelesaikan refactor saya akan membagikan hasilnya di sini, saya mungkin akan menggunakan karma-parallel juga.

itu sebenarnya implementasi yang sama dengan versi terbaru dari ng-bullet, kecuali bahwa saya memilih untuk melewati await TestBed.compileComponents() .

@giniedp

Tanda tangan cuplikan Anda yang memberi saya kesalahan kompilasi:

export function configureTestSuite(configureAction: () => Promise<any>) {

Tanda tangan dari proyek ng-bullet :

export const configureTestSuite = (configureAction?: () => void) => {

Mungkin cara kami menggunakannya dalam pengujian kami berbeda (saya menggunakan berbasis di halaman ng-bullet npm), itu sebabnya cuplikan Anda tidak berfungsi untuk saya.

kamu benar. Itu adalah perbedaan kecil lainnya dalam cara kami mengadopsi dari ng-bullet. Perubahan di pihak Anda adalah

-   configureTestSuite(() => {
+   configureTestSuite(async () => {
        TestBed.configureTestingModule({
            // ...
        })
    });

bagi kami itu penting untuk tidak mengambil kontrol aliran dari pengembang, jadi dia masih bisa melakukan hal-hal async di dalam configureTestSuite

    configureTestSuite(async () => {
        await TestBed.configureTestingModule({
            // ...
        }).compileComponents()
        await moreAsyncStuff()
    });

@giniedp @Goodwine

Itu menarik @giniedp. Dalam kasus penggunaan saya, kami tidak peduli dengan kontrol aliran.

Saya harus mengucapkan terima kasih! Saya berhasil menambahkan ng-bullet dalam proyek dan eksekusi tes berubah dari 5m:30s menjadi 30s . Masalah yang saya miliki dengan dependensi rekan sebelumnya adalah karena versi node saya terlalu usang .

Menambahkan karma-paralel tidak banyak membantu (28-an bukannya 30-an) dan mematahkan tes jadi saya tidak menggunakannya.

@Goodwine

Pada Masalah lain tentang sesuatu yang serupa, seseorang menyebutkan bahwa rilis Angular berikutnya dengan Ivy dan R3SomethingTestBed membuat pengaturan pengujian berjalan lebih cepat bahkan tanpa AOT.

Ya. enabledIvy: true (ini adalah opsi tsconfig.json, lihat https://angular.io/guide/ivy#opting-into-angular-ivy) mengkonfigurasi untuk menggunakan TestBedRender3 sebagai implementasi TestBed. Ini TestBed untuk Render 3, alias Ivy. Dan kompiler Ivy JiT memiliki mekanisme caching untuk modul dan komponen yang dikompilasi. ( Lihat https://github.com/angular/angular/blob/8.2.14/packages/core/src/render3/jit/module.ts#L49-L66 ).

Jadi jika Anda mengaktifkan Ivy, TestBed.configureTestingModule(...).compileComponents() menjadi lebih cepat karena kompilasi kedua atau yang lebih baru untuk komponen yang sama dilewati.

Dengan Ivy, infrastruktur TestBed telah dirombak dan tidak lagi memerlukan kompilasi ulang modul pengujian. Saya telah melihat peningkatan yang signifikan (8x) dalam pengujian karena perubahan ini.

@JoostK Senang mendengar!


Akan menyenangkan untuk memiliki gambaran umum tentang perbedaan kinerja antara:

  1. Sudut 8 dengan Karma
  2. Sudut 8 dengan Jest
  3. Sudut 9 dengan Karma (+Ivy)
  4. Sudut 9 dengan Jest (+Ivy)

Halo semuanya,

Seperti yang disebutkan @JoostK , Ivy TestBed dirombak untuk menghindari kompilasi ulang yang tidak perlu di antara pengujian, yang membantu meningkatkan kinerja secara keseluruhan. Kami melakukan beberapa pengukuran untuk membandingkan versi ViewEngine dan Ivy TestBed menggunakan rangkaian pengujian Komponen Material, aplikasi Angular.io, dan pengujian unit Kerangka Kerja Sudut - peningkatan kinerja sekitar 30-40%. Kami juga menerima umpan balik dari pengembang bahwa mereka melihat hasil yang lebih baik pada proyek mereka.

Saya menutup tiket ini dan merasa bebas untuk membuat yang baru jika Anda melihat masalah kinerja TestBed setelah beralih ke Ivy.

Terima kasih.

Masalah ini telah dikunci secara otomatis karena tidak ada aktivitas.
Silakan ajukan masalah baru jika Anda mengalami masalah serupa atau terkait.

Baca lebih lanjut tentang kebijakan penguncian percakapan otomatis kami.

_Tindakan ini telah dilakukan secara otomatis oleh bot._

Apakah halaman ini membantu?
0 / 5 - 0 peringkat