Selamat datang pythonista
Selama sesi terakhir, kami berbicara tentang pengujian dengan python. Kami membahas topik mengejek relatif cepat jadi saya ingin mengungkapkan di sini beberapa metode dan ide yang kami tinggalkan. Ide-ide ini akan menjadi
- Menambal monyet
- Mengejek dan menambal di pytest
Contoh-contoh di sini kurang lebih cukup jelas tetapi Anda dapat menemukan semua contoh di cabang `blog1` dari repositori yang didedikasikan untuk pengujian dengan Python. Saya mendorong Anda untuk menguji contoh dan membuka diskusi tentang topik, keraguan, atau aspek yang mungkin relevan bagi Anda
Perlengkapan tambalan monyet
Seperti yang mungkin Anda ketahui, patch monyet adalah tindakan memodifikasi kelas atau modul selama runtime. Salah satu contoh penggunaan umum patching monyet adalah
Anda mungkin memperhatikan bahwa kami menambal semua fungsi bawaan (tidak disarankan untuk melakukan ini, hanya untuk alasan ilustratif). Perilaku ini bisa berguna berkali-kali tetapi orang harus sangat berhati-hati dengannya karena akan meninggalkan definisi di lingkungan yang sedang berjalan yang tidak jelas oleh kode tertulis itu sendiri
Bayangkan loop tak terbatas di server tempat kami memiliki monyet yang menambal fungsionalitas kunci dan kami selalu mengembalikan yang sama. Tetapi justru perilaku itulah yang mungkin kita inginkan saat menguji menggunakan paket yang tidak kita kendalikan atau kita tidak memiliki infrastruktur untuk mengaksesnya.
Pytest menyadari situasi ini dan menyediakan perlengkapan bawaan untuk bekerja dengan patching monyet selama pengujian Anda. Fungsionalitas ini menangani penambalan dan ketika pengujian selesai, ia mengembalikan modul tambalan ke keadaan semula, untuk digunakan kembali (jika diperlukan) tanpa perubahan atau tambalan apa pun. Mari lihat salah satu contoh perlengkapan ini
Bayangkan kita memiliki kelas yang membuat model faktur di perusahaan kita. Entitas ini harus memiliki ID dan jenis data lainnya. Tetapi untuk jenis pengujian kami, kami perlu memastikan dan bekerja dengan ID yang sama demi kesederhanaan. Sedangkan untuk batch tes lainnya kami tidak memiliki kebutuhan tersebut. Dalam hal ini lihat kode di bawah ini
Seseorang dapat mengamati di sini bahwa dalam ruang lingkup pengujian yang menggunakan `monkeypatch` kami mengganti fungsi `uuid4` dengan definisi kami sendiri yang selalu mengembalikan uuid yang sama. Hal baiknya adalah kita tidak perlu merobohkan (membatalkan) tambalan ini di bagian akhir karena perlengkapan yang mengurusnya
Penggunaan lain dari `monkeypatch` bisa untuk mengganti variabel lingkungan. Seperti yang ditunjukkan pada contoh di bawah ini, relatif umum menggunakan variabel lingkungan untuk mengetahui lingkungan mana yang menjalankan kode kita. Berdasarkan variabel tersebut beberapa fitur dapat aktif, jadi jika di awal pengujian kita atur ke lingkungan `test`. (Ingatlah untuk mengatur lingkungan `ENV` Anda ke `pro` di lingkungan lokal Anda atau di `. env` file. )
Mengejek dan menambal
Seperti yang disebutkan di sesi terakhir ketika kita membutuhkan dobel yang memberikan perilaku tambahan (seperti saat dipanggil, atau apakah berhasil dipanggil) kita harus melihat ke perpustakaan `Mocking`
MagicMock
Keajaiban di balik `mocking` adalah `MagicMock` (bazinga. ). Memang basis perpustakaan adalah kelas `Mock` tetapi subkelas magic sudah mengimplementasikan dukungan (kapasitas tiruan) untuk semua metode te *magic* atau *dunder* (ya, yang memiliki garis bawah ganda sebagai awalan dan akhiran). Sebenarnya seseorang dapat menggunakan kelas-kelas ini tanpa berada di lingkungan pengujian (kerangka kerja). Mari kita periksa di lingkungan non-pengujian seperti itu kemampuan mengejek
Anda mungkin memperhatikan itu
- Instance dari `MagicMock` dapat digunakan sedemikian rupa sehingga ia akan menerima metode apa pun tanpa menghasilkan kesalahan apa pun dan tanpa melakukan apa pun, tetapi menghitung waktu dan cara memanggilnya. Jadi berbicara dengan benar, itu adalah tiruan
- Seseorang dapat mendefinisikan pernyataan berbeda pada tiruan ini
Kita dapat meningkatkan perilaku pustaka tiruan dari tiruan sederhana menjadi rintisan dengan memodifikasi contoh di atas
Jadi kita bisa melihat kegunaan alat ini untuk pengujian, tapi ada dua masalah dengan `MagicMock`
- Biasanya kami ingin mengejek (mengganti perilaku) kelas yang ada di sub modul bahkan mungkin di kedalaman arsitektur kami
- Setelah metode diganti, atau ada efek samping, bagaimana jika kita ingin kembali dalam konteks yang berbeda ke perilaku aslinya?
Menambal
Jadi fitur utama terakhir dari library ini adalah fungsi `patch` yang memberikan solusi untuk masalah sebelumnya. Ini digunakan sebagai dekorator atau sebagai pengelola konteks dan untuk melihatnya beraksi kita memerlukan contoh yang lebih kompleks
Bayangkan kita memiliki perancah seperti
Bayangkan itu di patch_example. py kami ingin mengejek kelas Faktur seperti yang kami lakukan sebelumnya. Sekarang situasinya lebih kompleks karena kita tidak mendefinisikan kelas secara langsung di file yang sama dengan kode yang direkayasa
Dalam situasi ini tambalan akan menjadi sangat berguna. Kode untuk memiliki sesuatu yang mirip menggunakan tambalan akan menjadi seperti
Hal pertama yang harus diperhatikan adalah cara menggunakan parameter tambalan pertama (dan wajib) (target). Ini harus menjadi jalur ke tempat di kode di mana kita ingin mengganti tiruan, atau seperti yang disebutkan Lisa Roach di Patch pembicaraan yang bagus di mana objek digunakan. Bukan di mana objek yang akan diejek didefinisikan dalam kode kita. ini kuncinya, jadi luangkan waktu Anda untuk mencerna cara kerja ini. Dalam contoh kami, Faktur ditentukan di domain tetapi kami ingin mengganti `Faktur` dengan tiruan dalam konteks/cakupan aplikasi. py di dalam aplikasi
Jadi itu adalah jalan menuju aplikasi. aplikasi apa yang harus kita gunakan untuk mengejek di sana
Seperti yang mungkin Anda perhatikan, tambalan hanya diterapkan dalam konteks dan kami tidak harus menangani proses pelepasan tambalan. Ini adalah fitur perpustakaan yang sangat nyaman. Begitu berada di luar manajer konteks kami memanggil fungsi yang sama akan berjalan tanpa menggunakan objek tiruan
Situasi di mana kami memiliki organisasi yang kompleks di dalam namespace diharapkan saat kami harus menguji. Setidaknya kami akan selalu membagi kode yang sedang diuji dan kode pengujian dalam dua file berbeda, tetapi misalnya saya memiliki preferensi untuk meletakkannya di folder terpisah dan perancah serta spasi nama di dalam src biasanya akan rumit. Selain itu, ada kemungkinan bahwa setiap test case membutuhkan tambalan khusus. Jadi akan lebih mudah jika perpustakaan menangani unpatching setelah keluar dari ruang lingkup
Jadi, alih-alih menggunakan perpustakaan mocking seperti yang telah kita lakukan (di luar kerangka uji apa pun), mari kita gunakan di lingkungan yang lebih alami. dalam pytests
Dalam hal ini kami menggunakan tambalan sebagai penghias alih-alih pengelola konteks. Alasannya adalah bahwa kami hanya mengejek sekali dan kami tidak perlu menghapus tambalan dalam konteks fungsi pengujian. Biasanya ini adalah situasi umum dan itulah mengapa versi dekorator lebih tersebar luas
Bayangkan situasi yang lebih kompleks di mana kita memiliki repositori yang karena kecepatan proyek belum diimplementasikan tetapi kita tahu bahwa akan ada metode `write_invoice` yang akan digunakan setiap kali kita memperbarui backlog faktur. Jadi repositori. py file mungkin terlihat seperti
Jadi kami ingin menyimpan entitas kami dan tetap ingin menjalankan tes yang kami pelajari sebelumnya. Untuk melakukan ini kita perlu menambahkan tambalan (mock) baru dan lebih bermakna yang akan mensimulasikan keberadaan repositori ini
Ketika kami mengatakan lebih bermakna, yang kami maksud adalah bahwa biasanya repositori dan gerbang lain ke dalam domain kami adalah jenis objek yang akan menggunakan infrastruktur atau perhitungan mahal yang tidak akan dapat diterima dalam pengujian kesatuan. Untuk beradaptasi dengan situasi ini kita perlu sedikit memodifikasi tes sebelumnya dengan melakukan
Kami menggunakan dua tambalan tetapi perhatikan bahwa urutan parameter yang diambil dalam fungsi pengujian adalah kebalikan dari urutan dekorator. Kami berharap hanya memiliki satu panggilan ke repositori dan jumlah panggilan yang sama ke metode tulis. Penting untuk digarisbawahi bahwa dengan melakukan ini kami dapat menguji fungsionalitas domain/aplikasi kami secara independen dari implementasi khusus dari repositori (persistensi dapat terjadi di database, di drive, di memori, dll. ). Dengan mengabstraksikan cara ini kita lebih bebas untuk fokus pada dependensi kita sendiri
Kesimpulan
Kami telah melihat bahwa saat menguji ada situasi di mana kami tidak mampu bekerja dengan penerapan kode saat ini. Hal ini terutama karena biaya mengadaptasi kode ke lingkungan pengujian akan membuat kode tersebut sangat sulit untuk dipelihara dan dibaca. Jadi, menambal dan mengejek monyet memberikan kemungkinan untuk mengganti elemen dalam kode kita dengan elemen yang tidak akan memiliki ketergantungan apa pun dan karenanya tidak akan mengeluh
Kami telah melihat bahwa dengan menggunakan alat ini kami juga dapat memperluas beberapa perilaku atau menggantinya, untuk mencakup semua kemungkinan kasus sudut yang dapat kami pikirkan
Meskipun paket-paket ini digunakan terutama selama pengujian, merupakan latihan yang sehat untuk mengujinya hanya dengan menjalankan skrip biasa untuk menghindari gangguan dari kerangka pengujian. Inilah yang telah kami lakukan;
Pada artikel selanjutnya kita akan membahas lebih banyak topik yang terkait dengan pengujian. Sampai saat itu, ingatlah untuk berani dan berani. dan ingatlah