Untuk Menguji Sistem, Mengasingkan Kesan Sampingan

Mengambil kesan sampingan adalah salah satu cara terbaik untuk membina kod yang boleh diuji

Gambar pertandingan tinju antara dua pejuang lelaki. Wajah mereka di luar bingkai. Pejuang di sebelah kiri telah menghantar cangkuk kiri ke pejuang di sebelah kanan. Pejuang di sebelah kanan memakai pendek merah dengan simbol kecil dari Kesatuan Soviet.

Nock adalah perpustakaan terkenal yang ditulis dalam JavaScript yang berguna untuk permintaan rangkaian rintisan. Ia mengembalikan tindak balas statik untuk ujian supaya ia dapat dijalankan walaupun pelayan HTTP tidak tersedia.

Walau bagaimanapun, ia juga bau.

Gandingan yang terhasil antara Sumber Data dan Sistem Bawah Ujian adalah kos yang boleh menjejaskan refactoring dan pemeliharaan kod.

Inilah sebabnya.

Katakan ada pelayan yang mengembalikan senarai jawatan dan fungsi yang menggunakan respons dari pelayan itu untuk membuat senarai tajuk pos. Ujian untuk fungsi itu menggunakan Nock untuk meregangkan respons dari pelayan:

Rajah yang menunjukkan blok di sebelah kiri dengan kapsyen

Kod ini mempunyai liputan yang baik. Walau bagaimanapun, terdapat beberapa isu dengannya.

Jika anda membuat perubahan pada jenis kandungan respons, anda perlu menukar ujian, walaupun tingkah laku kod tetap sama:

Perkara yang sama berlaku jika anda membuat perubahan pada URL, tajuk atau parameter yang Nock sedang menggerogoti. Anda perlu menukar ujian walaupun tingkah laku sistem tetap sama:

Fungsi "membuat senarai jawatan" adalah Sistem Under Test (SUT). Data dari panggilan HTTP ialah Sumber Data.

Anda boleh merancang kod supaya Sumber Data mempunyai pluggable antara muka umum kepada SUT. Dalam kes itu, anda boleh menjalankan logik tanpa memerlukan persediaan terlalu banyak.

Rajah yang menunjukkan blok di sebelah kiri dengan tajuk

Untuk persekitaran ujian, anda boleh menyuntik "Sumber Data Memori Dalam." Untuk pengeluaran, anda boleh menggunakan "Sumber Data Pelayan HTTP."

"Antara muka umum" dalam JSFiddle sebelumnya adalah kaedah "mencari tajuk jawatan." Tidak kira bagaimana anda membina antara muka, anda mempunyai kawalan ke atas semua pemanggil. Oleh itu, perubahan adalah mudah. Martin Fowler menyebut bahawa "antara muka yang tidak diterbitkan."

Sebaliknya, jika pelayan memecah kontrak Interface Diterbitkan mereka, mengatakan perubahan atribut kelas dari tajuk pasca ke tajuk artikel, anda hanya perlu menukar pelaksanaan Sumber Data. Anda tidak perlu membuat perubahan di mana-mana sahaja.

Perkara yang penting untuk diuji dan maklum balas awal adalah pada ujian terhadap tingkah laku, bukan data. Oleh itu, sangat penting untuk mereka bentuk kod untuk mengurangkan jumlah usaha yang diperlukan untuk perubahan kepada logik. Dalam kes ini, logik ialah transformasi input dari Sumber Data ke senarai tidak teratur HTML.

Dengan reka bentuk baru, anda telah memecahkan Sumber Data dari Sistem Bawah Ujian. Oleh itu, anda boleh mengeluarkan Nock.

Reka bentuk baru juga mengurangkan kerja yang diperlukan untuk menambah peraturan baru ke sistem tanpa salinan / tampal:

Namun, "Sumber Data Pelayan HTTP" mempunyai beberapa logik yang belum diterokai di dalam fungsi peribadi "tajuk siaran pertanyaan dari html."

Untuk mengujinya, anda boleh mengulang corak yang sama. Tolak kesan sampingan dan buat mekanisme "mendapatkan permintaan" pluggable ke dalam "Sumber Data Server HTTP." Dengan cara ini anda masih boleh menguji kod tanpa memerlukan Nock:

Memandangkan anda sudah mempunyai ujian untuk mengesahkan "senarai tajuk jawatan" berfungsi dengan "Sumber Data In-Memory," anda boleh membuat keputusan untuk menguji Sumber Data secara berasingan bagi memastikan ia mengembalikan hasil yang betul:

Anda telah menolak kesan sampingan dari logik sepenuhnya. Dalam kes ini, fungsi "mendapatkan permintaan" sebenarnya adalah kesan sampingan. Kini anda boleh menggunakan Nock untuk menutupnya.

Walau bagaimanapun, memandangkan logik di dalam "mendapatkan permintaan" adalah remeh dan Nock mempunyai kos yang besar, masuk akal untuk mempunyai sebilangan kecil Ujian Integrasi yang dapat melaksanakan keseluruhan aplikasi, termasuk kesan sampingan. Anda boleh menggunakan Nock untuk mengelakkan sambungan ke pelayan langsung, dan masih, menggunakan permintaan HTTP untuk mengesahkan sama ada permohonan itu memberikan sambutan yang munasabah apabila semua kepingan itu bersesuaian.

Nock berguna untuk merapatkan sambungan di lapisan HTTP dan untuk memberikan respons statik. Bagaimanapun, gunakannya dengan berhati-hati. Bagi setiap ujian yang anda rujuk, anda meningkatkan gandingan dan kos perubahan yang ketara.

Sekiranya tidak digunakan dengan jimat, Nock boleh membuat Hell Nock.

Masalah yang anda ingin selesaikan adalah mengurangkan jumlah bug dan kos perubahan. Sekiranya anda mengubah struktur kod tanpa sebarang perubahan terhadap tingkah laku, ujian tidak boleh dipecahkan. Sekiranya mereka melakukannya, maka anda gagal menulis ujian yang berguna.

Matlamat anda adalah untuk meningkatkan kualiti liputan ujian kepada logik yang anda ambil perhatian dan mencapai maklum balas awal. Semua itu tanpa menjejaskan keupayaan anda untuk refactor kod itu.

Mengasingkan kesan sampingan dan hadkan penggunaan alat seperti Nock ke sempadan aplikasi.

Ini sepatutnya memberikan anda keyakinan yang cukup untuk membuat perubahan dan tidak memecahkan barangan.

Sertai perjuangan, tolak kesan sampingan, dan kemudian ... Nock it out.

Terima kasih untuk membaca. Jika anda mempunyai maklum balas, hubungi saya di Twitter, Facebook atau Github.

Terima kasih kepada Eduardo Slompo dan Guilherme J. Tramontina atas maklum balas mereka terhadap jawatan ini.