Komponen ujian dalam React: apa dan bagaimana untuk menguji dengan Jest dan Enzim.

Artikel ini mengenai ujian komponen yang bertindak balas ditulis oleh Alona Pysarenko - Jurutera Frontend di Django Stars.
Baca artikel asal pada blog Django Stars.

Ujian Komponen reaksi mungkin mencabar untuk pemula serta pemaju berpengalaman yang telah bekerja dengan ujian. Mungkin menarik untuk membandingkan pendekatan anda sendiri dengan yang kami gunakan dalam projek kami. Untuk menampung pangkalan data, anda perlu tahu komponen mana yang mesti diuji dan kod yang betul dalam komponen harus dilindungi.

Semasa artikel ini, saya akan merangkumi topik berikut:

  • Tentukan susunan ujian komponen yang betul berdasarkan struktur projek
  • Cari apa yang harus dilepaskan dalam liputan ujian (apa yang tidak diuji)
  • Kenal pasti keperluan Pengujian Snapshot
  • Tentukan apa yang harus diuji dalam komponen dan di mana pesanan
  • Berikan contoh kod tersuai terperinci

Artikel ini memerlukan anda mengetahui tentang persediaan Jest dan Enzim. Maklumat tentang pemasangan dan konfigurasi boleh didapati dengan mudah di laman web rasmi mereka.

Anggapkan perkara berikut: Anda perlu menampung asas projek dengan ujian. Apa yang perlu anda mulakan, dan apa yang perlu anda dapatkan pada akhir ujian? Liputan ujian 100%? Ia adalah penanda aras yang mana anda harus bercita-cita, tetapi dalam kebanyakan situasi anda tidak akan mendapatkannya.

Mengapa? Kerana anda tidak perlu menguji semua kod. Kami akan mengetahui mengapa dan apa yang perlu ditinggalkan daripada ujian. Lebih-lebih lagi, liputan ujian 100% tidak selalu memastikan bahawa komponen itu diuji sepenuhnya. Tidak ada jaminan bahawa ia akan memberitahu anda jika sesuatu telah berubah. Jangan berusaha untuk peratusan, elakkan menulis ujian palsu, dan cobalah untuk tidak kehilangan butiran komponen utama.

Menentukan susunan komponen yang betul berdasarkan struktur projek

Mari kita bincangkan soalan ini di bahagian seterusnya struktur projek:

Saya mengambil direktori kongsi kerana ia adalah yang paling penting. Ia terdiri daripada komponen yang digunakan dalam beberapa halaman yang berlainan projek. Mereka boleh diguna semula, dan biasanya mereka kecil dan tidak kompleks. Jika satu atau komponen lain gagal, ia akan menyebabkan kegagalan di tempat lain. Itulah sebabnya kita harus yakin sama ada mereka telah ditulis dengan betul. Struktur direktori ini dibahagikan kepada beberapa folder, masing-masing mengandungi komponen.

Bagaimana untuk menentukan susunan ujian komponen yang betul dalam direktori kongsi:

  • Sentiasa ikuti aturan pergi dari mudah ke kompleks. Menganalisis setiap direktori dan menentukan komponen mana yang bebas - iaitu, rendering mereka tidak bergantung kepada komponen lain. Mereka siap sepenuhnya dan boleh digunakan secara berasingan sebagai unit tunggal. Dari struktur di atas, ia adalah direktori input dalam folder bentuk. Ia mengandungi komponen input untuk bentuk redux, seperti TextInput, SelectInput, CheckboxInput, DateInput, dll.
  • Seterusnya, kita perlu menentukan komponen bantu yang sering digunakan dalam komponen input, tetapi harus diuji selainnya. Ini adalah direktori utils. Komponen dalam folder ini tidak rumit, tetapi sangat penting. Mereka sering boleh digunakan semula dan membantu dengan tindakan berulang.
  • Langkah seterusnya adalah untuk menentukan komponen mana yang boleh digunakan secara berasingan juga. Jika ada, bawa mereka untuk ujian. Dari struktur kami, ia adalah widget, komponen kecil dengan fungsi mudah. Mereka akan menjadi item ketiga dalam barisan untuk liputan ujian.
  • Selanjutnya, analisa seluruh direktori dan tentukan komponen yang lebih kompleks, yang boleh digunakan secara berasingan atau bersama dengan komponen lain. Ia adalah direktori modal dalam kes kami. Komponen-komponen ini akan diterangkan secara terperinci di bawah.
  • Komponen yang paling kompleks dibiarkan hingga akhir. Mereka adalah direktori dan medan hoc dari folder bentuk. Bagaimanakah anda menentukan mana yang patut diuji dahulu? Saya mengambil direktori dari mana komponen telah digunakan dalam komponen yang diuji. Oleh itu, komponen dari direktori hoc hadir dalam komponen widget. Itulah sebabnya saya sudah tahu di mana dan untuk tujuan ini direktori dan komponennya digunakan.
  • Yang terakhir ialah folder medan. Ia mengandungi komponen yang berkaitan dengan bentuk redux.

Pesanan komponen akhir (berdasarkan contoh kami) akan kelihatan seperti ini:

Mengikuti pesanan ini, anda meningkatkan kerumitan komponen yang diuji langkah demi langkah. Oleh itu, apabila ia beroperasi dengan komponen yang lebih kompleks, anda sudah tahu bagaimana yang terkecil yang berlaku.

Jangan ambil untuk ujian, sebagai contoh, medan 'array', jika anda tidak pasti bagaimana untuk menguji medan 'teks'. Jangan ambil komponen yang dihiasi dengan bentuk redux jika anda belum menguji bidang 'bentuk' itu sendiri.

Selaras dengan pilihan anda, jangan ambil komponen pertama yang masuk ke dalam fikiran anda, dan beralih logiknya. Sudah tentu, struktur projek anda boleh berbeza. Ia boleh mempunyai nama direktori lain atau boleh mempunyai komponen tambahan, tindakan, dan reducer, tetapi logik menentukan perintah untuk menguji komponen adalah sama.

Mari kita tentukan apa yang harus ditinggalkan dalam liputan ujian:

  • Perpustakaan pihak ketiga. Jangan menguji fungsi yang diambil dari perpustakaan lain. Anda tidak bertanggungjawab untuk kod itu. Lompat atau tiru pelaksanaan jika anda memerlukannya untuk menguji kod anda.
  • Pemalar. Nama itu bercakap untuk dirinya sendiri. Mereka tidak berubah. Mereka adalah set kod statik yang tidak bertujuan untuk berubah.
  • Gaya dalam talian (jika anda menggunakannya dalam komponen anda). Untuk menguji gaya inline, anda perlu menduplikasi objek dengan gaya dalam ujian anda. Jika gaya objek berubah, anda mesti mengubahnya dalam ujian juga. Jangan menduplikat kod komponen dalam ujian. Anda tidak akan ingat untuk mengubahnya dalam ujian. Selain itu, rakan sekerja anda tidak akan menyedari bahawa terdapat pertindihan. Dalam kebanyakan kes, gaya inline tidak mengubah tingkah laku komponen, jadi mereka tidak boleh diuji. Terdapat pengecualian jika gaya anda berubah secara dinamik.
  • Perkara yang tidak berkaitan dengan komponen yang diuji. Melangkau meliputi komponen ujian yang diimport dalam komponen yang diuji. Berhati-hati jika ia dibalut dengan yang lain. Jangan menguji pembalut, hanya analisa dan uji mereka secara berasingan.

Jadi bagaimana anda sebenarnya menulis ujian? Saya menggabungkan dua pendekatan ujian:

  • Pengujian Snapshot
  • Ujian logik komponen

Saya akan membincangkannya sekarang.

Bagaimana untuk menguji dengan syot kilat

Pengujian Snapshot adalah alat ujian berguna sekiranya anda ingin memastikan bahawa antara muka pengguna tidak berubah. Apabila menghadapi alat ujian ini untuk kali pertama, anda mungkin mempunyai soalan mengenai organisasi dan menguruskan syot kilat. Prinsipnya sangat mudah, tetapi malangnya ia tidak digambarkan sepenuhnya di mana-mana sahaja.

Langkah 1. Tulis ujian untuk komponen, dan dalam blok harapan gunakan kaedah .toMatchSnapshot () yang membuat Snapshot itu sendiri:

ia ('menyebabkan komponen teks yang betul', () => {
    const TextInputComponent = renderer.create (). toJSON ();
    menjangkakan (TextInputComponent). toMatchSnapshot ();
});

Langkah 2. Apabila anda menjalankan ujian untuk kali pertama di satu tahap, bersama-sama dengan ujian, direktori akan dibuat bernama __snapshots__ dengan fail autogenerated di dalam dengan extension.snap.

Gambaran tangkapan kelihatan seperti ini:

/ // Jest Snapshot v1, https://goo.gl/fbAQLP
eksport [`Render TextInput betul komponen 1`] =`

`;

Langkah 3. Tekan snapshot ke dalam repositori dan simpannya bersama dengan ujian.

Jika komponen telah diubah, anda hanya perlu mengemas kini syot kilat dengan bendera-terkiniSnapshot atau gunakan bendera bentuk pendek anda.

Jadi Snapshot dicipta - bagaimana ia berfungsi?

Mari kita pertimbangkan dua kes:

1. Komponen telah berubah

  • Menjalankan ujian
  • Petunjuk baru dibuat, ia dibandingkan dengan petikan yang dihasilkan secara automatik yang tersimpan dalam direktori __snapshots__
  • Ujian gagal kerana snapshot berbeza

2. Komponen ini tidak berubah

  • Menjalankan ujian
  • Petunjuk baru dibuat, ia dibandingkan dengan petikan yang dihasilkan secara automatik yang tersimpan dalam direktori __snapshots__
  • Ujian diluluskan kerana snapshot adalah sama

Segala-galanya baik apabila kita menguji komponen kecil tanpa logik (hanya rendering UI). Tetapi sebagai menunjukkan amalan, tidak ada komponen sedemikian pada projek-projek sebenar. Jika mereka wujud, mereka sedikit.

Adakah terdapat snapshot yang cukup untuk ujian komponen penuh?

Arahan utama untuk ujian komponen

1. Satu komponen harus mempunyai satu petikan sahaja.

Sekiranya satu snapshot gagal, kemungkinan yang lain akan gagal juga. Jangan buat dan simpan sekumpulan gambar yang tidak perlu menyumbat ruang dan pemaju yang membingungkan yang akan membaca ujian anda selepas anda.

Sudah tentu, terdapat pengecualian apabila anda perlu menguji tingkah laku komponen dalam dua negeri: contohnya, dalam keadaan komponen sebelum membuka pop timbul dan selepas pembukaan.

Walau bagaimanapun, walaupun varian seperti itu boleh digantikan dengan yang berikut: ujian pertama menyimpan keadaan lalai komponen tanpa pop timbul dalam snapshot, dan ujian kedua mensimulasikan peristiwa dan memeriksa kehadiran kelas tertentu. Dengan cara ini, anda boleh dengan mudah memintas penciptaan beberapa syot kilat.

2. Menguji prop

Sebagai peraturan, saya membahagikan ujian props kepada dua ujian:

  • Pertama, periksa penyebab nilai prop lalai. Apabila komponen diberikan, saya mengharapkan nilai menjadi sama dengan defaultProps sekiranya prop ini mempunyai defaultProps.
  • Kedua, periksa nilai tersuai prop. Saya menetapkan nilai saya sendiri dan mengharapkannya diterima selepas penyampaian komponen.

3. Menguji jenis data

Untuk menguji apa jenis data yang terdapat dalam alat peraga atau jenis data yang diperolehi selepas tindakan tertentu, kita boleh menggunakan pustaka khas (tambahan Jest matchers), yang mempunyai set perlawanan yang dilanjutkan yang tidak ada dalam Jest. Dengan perpustakaan ini, ujian jenis data lebih mudah dan lebih menyeronokkan.

Ujian proptip, sebaliknya, adalah soalan bercanggah. Sesetengah pemaju boleh berhujah terhadap pengujian proptip kerana ia merupakan pakej pihak ketiga dan tidak boleh diuji. Namun, saya bersikeras untuk menguji proptip komponen kerana saya tidak menguji fungsi pakej itu sendiri. Sebaliknya, saya hanya memastikan bahawa proptip adalah betul. Jenis data adalah bahagian pengaturcaraan yang sangat penting dan tidak boleh dilangkau.

4. Pengujian acara

Setelah membuat tangkapan dan tangkai penutup dengan ujian, anda dapat memastikan komponen itu akan menghasilkan dengan betul. Tetapi ini tidak mencukupi untuk liputan penuh sekiranya anda mempunyai acara dalam komponen.

Anda boleh menyemak acara dengan beberapa cara. Yang paling banyak digunakan adalah:

  • acara mengejek => mensimulasikannya => mengharapkan acara dipanggil
  • acara mengejek => mensimulasikan acara dengan params => mengharapkan acara dipanggil dengan param yang diluluskan
  • lulus peraga yang perlu => membuat komponen => mensimulasikan peristiwa => mengharapkan tingkah laku tertentu pada acara dipanggil

5. Syarat ujian

Selalunya anda boleh mempunyai syarat untuk output kelas tertentu, memberikan bahagian tertentu kod, memindahkan alat yang diperlukan, dan sebagainya. Jangan lupa tentang perkara ini, kerana dengan nilai lalai, hanya satu cawangan akan lulus ujian, manakala yang kedua akan tetap belum dicabar.

Komponen kompleks dengan pengiraan dan banyak keadaan, anda boleh terlepas beberapa cawangan. Untuk memastikan semua bahagian kod dilindungi oleh ujian, gunakan alat liputan ujian dan lihat secara visual cawangan mana yang dilindungi dan yang tidak.

6. Ujian keadaan

Untuk memeriksa keadaan, dalam kebanyakan kes, perlu menulis dua ujian:

  • Yang pertama memeriksa status semasa.
  • Yang kedua memeriksa keadaan selepas memanggil acara. Render component => call function secara langsung di test => periksa bagaimana keadaan telah berubah. Untuk memanggil fungsi komponen, anda perlu mendapatkan contoh komponen dan kemudian hanya memanggil kaedahnya (contoh ditunjukkan dalam ujian seterusnya).

Setelah anda melawati senarai arahan ini, komponen anda akan dilindungi dari 90 hingga 100%. Saya meninggalkan 10% untuk kes-kes khas yang tidak diterangkan dalam artikel, tetapi boleh berlaku dalam kod.

Contoh Ujian

Mari kita beralih kepada contoh dan tutup komponen dengan ujian seperti yang telah kami huraikan di atas langkah demi langkah.

1. Menguji komponen dari borang / input.

Ambil satu komponen dari direktori / borang input. Biarkan ia DateInput.js, komponen untuk bidang datepicker.

Penyenaraian kod untuk komponen yang diuji: DateInput.js
Kelihatan seperti:

Komponen DateInput menggunakan pustaka bereaksi perpustakaan, dengan dua utiliti:

  • valueToDate (menukarkan nilai setakat ini)
  • dateToValue (menukar tarikh ke nilai)

Pakej ini untuk memanipulasi dengan tarikh dan PropTypes adalah untuk menyemak React props.

Menurut kod komponen, kita dapat melihat senarai alat lalai yang membantu komponen dapat diberikan:

const defaultProps = {
    inputClassName: 'input-custom',
    bulan dibahagi: 1,
    dateFormat: 'DD.MM.YYYY',
    showMonthYearsDropdowns: false,
    minDate: moment ()
};

Semua peraga sesuai untuk membuat snapshot, kecuali satu: minDate: moment (). momen () akan memberi kita tarikh semasa setiap kali kami menjalankan ujian dan tangkapan gambar akan gagal kerana ia menyimpan tarikh ketinggalan zaman. Penyelesaiannya ialah mengejek nilai ini:

const defaultProps = {
    minDate: moment (0)
}

Kami memerlukan sokongan minDate dalam setiap komponen yang diberikan. Untuk mengelakkan duplikasi prop, saya membuat HOC yang menerima defaultProps dan mengembalikan komponen yang cukup:

import TestDateInput dari '../DateInput';
const DateInput = (props) =>
    ;

Jangan lupa tentang zon masa, terutamanya jika ujian anda akan dijalankan oleh pemaju dari negara lain dalam zon waktu yang berbeza. Mereka akan menerima nilai mengejek, tetapi dengan peralihan zon waktu. Penyelesaiannya adalah untuk menetapkan zon masa lalai:

moment momen = require.requireActual ('moment-timezone'). tz.setDefault ('America / Los_Angeles')

Sekarang komponen input tarikh bersedia untuk diuji:

1. Buat gambar pertama:

ia ('menyebabkan komponen tarikh betul', () => {
    const DateInputComponent = renderer.create (). toJSON ();
    menjangkakan (DateInputComponent). toMatchSnapshot ();
});

2. props pengujian:

Lihatlah alat dan cari yang penting. Sokongan pertama untuk menguji adalah showMonthYearsDropdowns. Sekiranya ia ditetapkan benar, penurunan harga bagi bulan dan tahun ditunjukkan:

('semak undur bulan dan tahun dipaparkan', () => {
    const props = {
            showMonthYearsDropdowns: benar
        },
        DateInputComponent = mount (

Uji nilai prop null. Cek ini diperlukan untuk memastikan komponen itu diberikan tanpa nilai yang ditetapkan:

ia ('membuat input tarikh dengan betul dengan nilai nol', () => {
    const props = {
            nilai: null
        },
        DateInputComponent = mount ();
    jangkaan ((DateInputComponent) .prop ('nilai')). toEqual (null);
});

3.Teks utama untuk nilai, tarikh yang dijangka menjadi rentetan:

ia ('semak jenis nilai', () => {
    const props = {
            nilai: '10 .03.2018 '
        },
        DateInputComponent = mount ();
    menjangka (DateInputComponent.prop ('nilai')). toBeString ();
});

4. peristiwa terbaik:

Pertama, semak acara onange.

  • mengejek panggilan balik Chang
  • membuat komponen input tarikh
  • simulasi peristiwa perubahan dengan nilai sasaran baru
  • dan akhirnya periksa bahawa acara onange telah dipanggil dengan nilai baru.
ia ('semak panggil balik onange', () => {
    const onChange = jest.fn (),
        props = {
            nilai: '20 .01.2018 ',
            onChange
        },
        DateInputComponent = mount (

Seterusnya, pastikan popup datepicker dibuka selepas klik pada input tarikh. Untuk itu, cari input tarikh => simulate click event => dan mengharapkan popup apabila kelas .react-datepicker ada.

ia ('semak popup TarikhPicker terbuka', () => {
    const DateComponent = mount (),
        dateInput = DateComponent.find ("input [type = 'text']");
    dateInput.simulate ('klik');
    jangkaan (DateComponent.find ('react-datepicker')). toHaveLength (1);
});

Penyenaraian ujian penuh: DateInput.test.js

2. Ujian utiliti:

Penyenaraian kod untuk utiliti yang diuji: valueToDate.js

Tujuan utiliti ini adalah menukar nilai kepada tarikh dengan format tersuai.

Pertama sekali, mari kita analisis utiliti yang diberikan dan tentukan kes-kes utama untuk ujian:

  1. Menurut maksud utiliti ini, ia mengubah nilai, jadi kita perlu memeriksa nilai ini:
  • Dalam nilai kes tidak ditakrifkan: kita perlu memastikan bahawa utiliti tidak akan mengembalikan pengecualian (ralat).
  • Dalam nilai kes ditakrifkan: kita perlu menyemak bahawa utiliti mengembalikan tarikh masanya.

2. Nilai yang dikembalikan mestilah tergolong dalam kelas saat ini. Itulah sebabnya ia harus menjadi contoh momen.

3. Hujah kedua adalah dateFormat. Tetapkan ia sebagai tetap sebelum ujian. Itulah sebabnya ia akan diluluskan dalam setiap ujian dan nilai pulangan mengikut format tarikh. Sekiranya kita menguji tarikhFormat secara berasingan? Saya rasa tidak. Hujah ini adalah pilihan - jika kita tidak menetapkan dateFormat, utiliti tidak akan pecah, dan ia hanya akan memulangkan tarikh dalam format lalai. Ia adalah tugas semasanya, kita tidak boleh menguji perpustakaan pihak ketiga. Seperti yang saya nyatakan sebelum ini, kita tidak sepatutnya lupa tentang moment-timezone; ia adalah satu perkara yang sangat penting, terutamanya bagi pemaju dari zon waktu yang berbeza.

Let's code:

  1. Tulis ujian untuk kes pertama. Apabila kita tidak mempunyai nilai, ia kosong.
const format = 'DD.MM.YYYY';
ia ('menyebabkan utiliti valueToDate dengan nilai kosong', () => {
    const value = valueToDate ('', format);
    mengharapkan (nilai) .toEqual (null);
});

2. Periksa sama ada nilai ditakrifkan.

const date = '21 .11.2015 ',
      format = 'DD.MM.YYYY';
ia ('menyebabkan utiliti ValueToDate dengan nilai yang ditetapkan', () => {
    const value = valueToDate (tarikh, format);
    mengharapkan (nilai) .toEqual (momen (tarikh, format));
});

3. Periksa sama ada nilai itu adalah kelas momen.

const date = '21 .11.2015 ',
    format = 'DD.MM.YYYY';
ia ('nilai cek adalah instanceof moment', () => {
    const value = valueToDate (tarikh, format);
    menjangkakan (nilai instanceof moment) .toBeTruthy ();
});

Penyenaraian ujian penuh: valueToDate.test.js

3. Ujian Widget

Untuk ujian widget, saya mengambil komponen pemutar.

Penyenaraian kod untuk widget yang diuji: Spinner.js

Sepertinya ini:

Spinner tidak diperlukan dalam penjelasan, kerana hampir semua sumber web mempunyai komponen ini.

Jadi jika kita pergi untuk menulis ujian:

  1. Langkah pertama - buat snapshot:
ia ('menyebabkan komponen Spinner betul', () => {
   const SpinnerComponent = mount ();
   menjangka (SpinnerComponent). toMatchSnapshot ();
});

2. Ujian prop:

Mula-mula, kita melihat tajuk prop lalai, dan periksa sama ada ia berfungsi dengan betul.

ia ('semak tajuk prop secara lalai', () => {
 const SpinnerComponent = mount ();
    jangkaan (SpinnerComponent.find ('p'). text ()). toEqual ('Please wait');
});

Kemudian kami menyemak tajuk prop khusus. Kita perlu menyemak bahawa ia mengembalikan prop yang ditakrifkan dengan betul. Lihatlah kod, tajuk dibungkus menggunakan rawMarkup, dan output dengan bantuan bahayaSetInnerHTML.

Penyenaraian kod untuk rawMarkup menggunakan:

fungsi lalai eksport rawMarkup (template) {
    kembali {__html: template};
}

Adakah kita perlu memasukkan ujian untuk rawMarkup dalam komponen spinner? Tidak, itu adalah utiliti yang berasingan dan ia harus diuji selain daripada pemutar. Kami tidak peduli bagaimana ia berfungsi - kita hanya perlu tahu bahawa tajuk prop mengembalikan hasil yang betul.

Penjelasan: Sebab untuk menggunakan sifat berbahayaSetInnerHTML adalah berikut. Laman kami adalah berbilang bahasa, yang mana pasukan pemasaran penterjemahan bertanggungjawab. Mereka boleh menerjemahkannya dengan kombinasi perkataan atau bahkan menghiasi dengan tag HTML, seperti , , atau teks slice dengan senarai

    ,
      . Kami tidak tahu pasti bagaimana mereka menerjemahkan dan menghiasi teks. Kami hanya perlu memberikan semua perkara ini dengan betul.

      Saya menggabungkan dua ujian utama dalam satu ujian:

      • kembali hak tajuk prop yang betul
      • memberi tajuk prop dengan betul dengan tag HTML
      ia ('semak tajuk prop dengan tag html', () => {
          const props = {
                  tajuk: ' Silakan tunggu '
              },
              SpinnerComponent = mount ();
          jangkaan (SpinnerComponent.find ('p'). text ()). toEqual ('Please wait');
      });

      Ambil subTitle prop seterusnya. Ia adalah pilihan dan itulah sebabnya ia tidak mempunyai prop lalai, jadi langkau langkah dengan prop default dan uji adat props:

      • Periksa bahawa teks dalam subTitle prop menjadikan betul:
      const props = {
              subTitle: 'meninggalkan 1 minit'
          },
          SpinnerComponent = mount ();
      ia ('tunjukkan teks yang betul', () => {
          menjangkakan (SpinnerComponent.find ('p') pada (1) .text ()). toEqual (props.subTitle);
      });

      Kami tahu bahawa subTitle adalah pilihan. Itulah sebabnya kita perlu menyemak sama ada ia tidak diberikan dengan alat lalai, menurut markup penghirisan itu. Cuma semak bilangan tanda

      :

      ia ('semak subTitle tidak diberikan', () => {
        const SpinnerComponent = mount ();
          jangkaan (SpinnerComponent.find ('p'). panjang) .toEqual (1);
      });

      3. jenis jenis tangkapan:

      • Untuk tajuk prop dijangka menjadi rentetan:
      ('semak jenis penanda untuk tajuk adalah rentetan', () => {
          const props = {
                  tajuk: 'Tunggu'
              },
              SpinnerComponent = mount ();
          mengharapkan (SpinnerComponent.find ('p'). text ()). toBeString ();
      });
      • Untuk subTitle prop juga dijangka menjadi rentetan:
      const props = {
              subTitle: 'meninggalkan 1 minit'
          },
          SpinnerComponent = mount ();
      ia ('jenis untuk subTitle adalah rentetan', () => {
          menjangkakan (SpinnerComponent.find ('p') di (1) .text ()). toBeString ();
      });

      Senarai ujian penuh: Spinner.test.js

      4. Ujian Modal (ModalWrapper.js dan ModalTrigger.js)

      Kelihatan seperti:

      Bagaimana untuk menguji modal

      Pertama sekali, saya ingin menerangkan bagaimana modal dianjurkan pada projek kami. Kami mempunyai dua komponen: ModalWrapper.js dan ModalTrigger.js.

      ModalWrapper bertanggungjawab untuk susun atur pop timbul. Ia mengandungi bekas modal, butang 'dekat', tajuk modal dan badan.

      ModalTrigger bertanggungjawab untuk pengendalian modal. Ia termasuk susun atur ModalWrapper dan mengandungi peristiwa untuk mengawal susun atur modal (tindakan terbuka dan tutup).

      Saya akan pergi ke setiap komponen secara berasingan:

      1. Penyenaraian kod untuk komponen yang diuji: ModalWrapper.js

      Let's code:

      Pertama, ModalWrapper menerima komponen dan menjadikannya di dalam. Pertama sekali, semak bahawa ModalWrapper tidak akan gagal tanpa komponen. Buat tangkapan dengan alat lalai:

      ia ('tanpa komponen', () => {
          const ModalWrapperComponent = cetek ();
          menjangkakan (ModalWrapperComponent). toMatchSnapshot ();
      });

      Langkah seterusnya adalah untuk mensimulasikan keadaan sebenar dengan penyampaian komponen yang dilalui melalui prop:

      ia ('dengan komponen', () => {
         const props = {
                 komponen: () => {}
              },
              ModalWrapperComponent = cetek ();
          menjangkakan (ModalWrapperComponent). toMatchSnapshot ();
      });

      Ujian prop

      Menerima nama kelas tersuai prop:

      ia ('memberi nama kelas yang betul', () => {
          const props = {
                  modalClassName: 'custom-class-name'
              },
              ModalWrapperComponent = cetek (

      Menerima prop jawatan tersuai:

      ia ('menyebabkan tajuk yang betul', () => {
          const props = {
                 tajuk: 'Tajuk Modal'
             },
             ModalWrapperComponent = cetek (

      Menerima prop persembahan yang betul:

      ia ('semak nilai prop', () => {
              const props = {
                     tunjukkan: benar
                 },
                 ModalWrapperComponent = cetek (

      Menguji proptip

      • Untuk tunjuk ajar
      ia ('semak jenis taip', () => {
          const props = {
                 tunjukkan: benar
              },
              ModalWrapperComponent = cetek (
      • Untuk onHide prop
      ia ('menyebabkan jenis prop onHide yang betul', () => {
          const props = {
                  onHide: () => {}
              },
              ModalWrapperComponent = cetek (
      • Untuk komponen prop
      ia ('menyebabkan jenis prop komponen yang betul', () => {
         const props = {
                 komponen: () => {}
             },
             ModalWrapperComponent = mount ();
         jangkaan (ComponalWrapperComponent.props (). komponen) .toBeFunction ();
      });

      Senarai ujian penuh: ModalWrapper.test.js

      2. Penyenaraian kod untuk komponen yang diuji: ModalTrigger.js

      Pembalut modal telah diliputi dengan ujian. Bahagian kedua adalah untuk menampung komponen pemicu modal.

      Gambaran keseluruhan komponen: ia berdasarkan keadaan bertukar yang menunjukkan kebolehlihatan ModalWrapper. Jika bertukar: palsu, pop timbul tersembunyi, jika tidak, ia kelihatan. Fungsi terbuka () membuka popup pada elemen kanak-kanak. Acara klik dan fungsi tutup () menyembunyikan popup pada butang yang diberikan dalam ModalWrapper.

      Penciptaan tangkapan gambar:

      ia ('menyebabkan komponen ModalTrigger dengan betul', () => {
          const ModalTriggerComponent = cetek ( 
      );     menjangkakan (ModalTriggerComponent). toMatchSnapshot (); });

      Sekiranya kita menguji ModalTrigger dengan penyediaan prop komponen? Tidak - kerana komponen akan diberikan di dalam komponen ModalWrapper. Ia tidak bergantung kepada komponen yang diuji. Ia sudah ditutup dengan ujian dalam ujian ModalWrapper.

      Alat penguji:

      Kami mempunyai satu kanak-kanak dan kami ingin memastikan bahawa kami hanya mempunyai satu anak.

      ia ('pastikan untuk mempunyai hanya satu anak (elemen kawalan)', () => {
          jangkaan (ModalTriggerComponent.findWhere (node ​​=> node.key () === 'modal-control'). panjang) .toEqual (1);
      });

      Ujian proptip:

      Tumpuan anak harus menjadi objek, jadi periksa ini dalam ujian seterusnya:

      const ModalTriggerComponent = mount ( 
      );
      ia ('semak jenis taip kanak-kanak', () => {
            menjangkakan (ModalTriggerComponent.props (). kanak-kanak) .toBeObject ();
      });

      Bahagian penting komponen ModalTrigger adalah untuk memeriksa keadaan.

      Kami mempunyai dua negeri:

      • Popup dibuka. Untuk mengetahui bahawa modal dibuka, kita perlu menyemak keadaannya. Untuk ini, panggil fungsi terbuka dari contoh komponen dan mengharapkan yang ditoggarkan dalam keadaan sepatutnya benar.
      ia ('semak modal dibuka', () => {
          const event = {
              preventDefault: () => {},
              stopPropagation: () => {}
          };
          ModalTriggerComponent.instance (). Buka (acara);
          menjangkakan (ModalTriggerComponent.state (). toggled) .toBeTruthy ();
      });
      • Popup ditutup. Ia diuji sebaliknya, bertukar dalam keadaan harus palsu.
      ia ('semak modal tertutup', () => {
         ModalTriggerComponent.instance (). Close ();
         mengharapkan (ModalTriggerComponent.state () .gggled) .toBeFalsy ();
      });

      Senarai ujian penuh: ModalTrigger.test.js

      Sekarang modal diuji sepenuhnya. Salah satu nasihat untuk menguji komponen yang bergantung kepada satu sama lain: melihat komponen-komponen terlebih dahulu dan tulis rancangan ujian, tentukan apa yang anda perlukan untuk menguji dalam setiap komponen, periksa kes ujian untuk setiap komponen, dan pastikan anda tidak ulangi kes ujian yang sama dalam kedua-dua komponen. Berhati-hati menganalisis varian yang mungkin dan optimum untuk liputan ujian.

      5. Ujian HOC (Komponen Perintah Tinggi)

      Dua bahagian terakhir (HOC dan ujian medan borang) saling berkaitan. Saya ingin berkongsi dengan anda bagaimana untuk menguji susun atur bidang dengan HOCnya.

      Inilah penjelasan tentang BaseFieldLayout, mengapa kita memerlukan komponen ini, dan di mana kita menggunakannya:

      • BaseFieldLayout.js adalah pembungkus untuk komponen input bentuk seperti TextInput, CheckboxInput, DateInput, SelectInput, dan sebagainya. Nama-nama mereka berakhir dengan -Input kerana kita menggunakan pakej redux-bentuk dan komponen-komponen ini adalah komponen input untuk logik bentuk reduks.
      • Kami memerlukan BaseFieldLayout untuk membuat susun atur untuk komponen bidang bentuk, iaitu membuat label, petua, awalan (mata wang, singkatan meter persegi, dll), ikon, ralat dan sebagainya.
      • Kami menggunakannya dalam BaseFieldHOC.js untuk membungkus susun aturKomponen dalam susun atur bidang dan menyambungkannya dengan bentuk redux dengan bantuan komponen .

      Penyenaraian kod untuk komponen yang diuji: BaseFieldHOC.js

      Ia adalah HOC yang menerima komponen input borang dan mengembalikan komponen, yang berkaitan dengan bentuk redux.

      Menganalisa HOC:

      • Komponen ini hanya menerima satu prop, komponen. Pertama sekali, saya perlu membuat komponen ini dan membungkusnya di BaseFieldHOC.
      • Seterusnya, saya perlu menghiasi HOC dibungkus dengan bentuk redux untuk mendapatkan medan yang berkaitan dengan bentuk redux.
      • Sediakan medan ini di dalam komponen Rezek Redux untuk membuat kedai tersedia untuk komponen yang diuji. Untuk mengejek kedai, lakukan saja:
      const store = createStore (() => ({}));

      Sekarang, sebelum setiap ujian, saya perlu melakukan perkara berikut:

      biarkan BaseFieldHOCComponent;
      sebelumEach (() => {
          const TextInput = () => {kembali 'input teks'; },
              BaseFieldHOCWrapper = BaseFieldHOC (TextInput),
              TextField = reduxForm ({form: 'testForm'}) (BaseFieldHOCWrapper);
          BaseFieldHOCComponent = renderer.create (
              
                  
              
          ) .toJSON ();
      });

      Selepas itu, komponen ini bersedia untuk ujian:

      1. Buat tangkapan gambar:
      ia ('menyebabkan komponen yang betul', () => {
          jangkaan (BaseFieldHOCComponent). toMatchSnapshot ();
      });

      2. Pastikan komponen input dibungkus dalam BaseFieldLayout selepas membuat rendering:

      ('semak komponen input dibungkus dalam BaseFieldLayout', () => {
          jangkaan (BaseFieldHOCComponent.props.className) .toEqual ('form-group');
      });

      Itu sahaja, HOC dilindungi. Bahagian paling rumit dalam komponen ujian yang berkaitan dengan bentuk redux adalah untuk menyediakan medan (menghiasi dengan bentuk redux dan kedai persediaan). Selebihnya mudah, hanya ikuti arahan dan apa-apa lagi.

      Senarai ujian penuh: BaseFieldHOC.test.js

      6. Borang / ujian lapangan

      Bidang HOC dilindungi dengan ujian supaya kami dapat berpindah ke komponen BaseFieldLayout.

      Penyenaraian kod untuk komponen yang diuji: BaseFieldLayout.js

      Mari kod BaseFieldLayout.js dan tulis ujian mengikut arahan di atas:

      1. Pertama sekali, buat snapshot.

      Komponen ini tidak akan diberikan tanpa defaultProps:

      • inputComponent
      • Alat yang disediakan oleh bentuk redux: input dan objek meta. Input dengan nama dan meta hartanah dengan ralat sifat dan disentuh:
      const defaultProps = {
         meta: {
              menyentuh: null,
              ralat: null
          },
          input: {
              nama: 'nama medan'
          },
          inputComponent: () => {return 'test case'; }
      }

      Untuk menggunakan defaultProps di setiap pembungkus yang diuji, lakukan yang berikut:

      import TestBaseFieldLayout dari '../BaseFieldLayout';
      const BaseFieldLayout = (props) => ;

      Sekarang kita sudah bersedia untuk membuat snapshot:

      ia ('memberi komponen BaseFieldLayout dengan betul', () => {
          const BaseFieldLayoutComponent = renderer.create () toJSON ();
          jangkaan (BaseFieldLayoutComponent). toMatchSnapshot ();
      });

      2. Ujian prop:

      Komponen ini mempunyai banyak alat. Saya akan menunjukkan beberapa contoh, dan selebihnya akan diuji dengan analogi.

      • Pastikan tangki ikon diberikan dengan betul
      ia ('menyebabkan ikon dengan betul', () => {
          const props = {
                  ikon: 
              },
              BaseFieldLayoutComponent = mount ();
              jangkaan (BaseFieldLayoutComponent.find ('span'). hasClass ('icon-exclamation')) toBeTruthy ();
      });
      • Pastikan kandungan tooltip menjadikan di sebelah label
      const props = {
              labelTooltipContent: 'tooltip untuk label'
          },
          BaseFieldLayoutComponent = mount ();
      ia ('semak tuduhan diberikan', () => {
         jangkaan (BaseFieldLayoutComponent.find ('span'). hasClass ('tooltip-icon')). ​​toBeTruthy ();
      });
      • Ujian lapanganLink prop
      • Pastikan fieldLink adalah null secara lalai
      ia ('cek prop adalah batal secara lalai', () => {
          const BaseFieldLayoutComponent = cetek ();
          jangkaan (BaseFieldLayoutComponent.props (). fieldLink) .toBe (null);
      });
      • Pastikan bidangLink membuat dengan betul dengan nilai tersuai

      3. Kesilapan ujian:

      ia ('periksa jika bidang mempunyai ralat', () => {
          const props = {
                  meta: {
                      disentuh: benar,
                      ralat: 'Bidang ini diperlukan'
                  }
              },
              BaseFieldLayoutComponent = mount ();
          jangkaan (BaseFieldLayoutComponent.find ('. ralat')). toHaveLength (1);
      });

      Penyenaraian ujian penuh: BaseFieldLayout.test.js

      Pokoknya

      Sekarang anda tahu bagaimana untuk melaksanakan ujian liputan lengkap komponen berdasarkan struktur projek. Dari pengalaman saya sendiri, saya cuba menerangkan apa yang diperlukan untuk menguji, di mana pesanan, dan apa yang anda boleh hilang dalam liputan ujian. Juga, saya menunjukkan contoh beberapa komponen ujian dan melihat urutan liputan kod.

      Saya harap anda akan mendapati artikel ini berguna dan akan berkongsi tanggapan anda. Terima kasih kerana membaca.

      Sekiranya anda mendapati siaran ini berguna, sila ketik butang di bawah :)