Terjemahan artikel disiapkan khusus untuk siswa kursus Python QA Engineer .
Kita hidup di era ketika perangkat lunak bergerak sangat cepat ke pasar. Karena itu, proses pengembangan menjadi sangat menegangkan. Tingkat implementasi perangkat lunak yang tinggi dan pengiriman yang cepat terlihat seperti bagian yang baik dari model bisnis, tetapi muncul pertanyaan di sini tentang bagaimana memberikan perangkat lunak dengan kualitas yang tepat.
Mengapa kita perlu tes otomatis
Ada banyak keuntungan untuk pengujian otomatis, berikut adalah tiga yang utama:
Penggunaan Kembali: Tidak perlu menulis skrip baru setiap kali, bahkan ketika versi baru dari sistem operasi dirilis, kecuali ada kebutuhan mendesak untuk itu.
Keandalan: Orang cenderung membuat kesalahan, dan mobil membuatnya lebih kecil kemungkinannya. Dan mereka bekerja lebih cepat ketika melakukan langkah / tes berulang yang perlu dilakukan terus menerus.
Bekerja 24/7: Anda dapat memulai pengujian kapan saja, bahkan dari jarak jauh. Jika Anda mulai menguji di malam hari, itu akan berjalan bahkan saat Anda tidur.
Mengembangkan alat uji pytest berfitur lengkap dengan Python
Saat ini, ada banyak kerangka kerja dan alat untuk pengujian. Ada berbagai jenis kerangka kerja, misalnya, data-driven, kata kunci-driven, hybrid, BDD, dll. Anda dapat memilih salah satu yang paling sesuai dengan kebutuhan Anda.
Saya harus mengatakan bahwa Python dan
pytest
menempati ceruk besar dalam masalah ini. Python dan alat-alat terkaitnya banyak digunakan, mungkin karena lebih mudah diakses oleh orang-orang dengan sedikit pengalaman pemrograman dibandingkan dengan bahasa lain.
Kerangka
pytest
mudah untuk menulis tes kecil, tetapi juga skala untuk mendukung pengujian fungsional aplikasi dan perpustakaan yang canggih.
Beberapa fitur utama
pytest
:
- Deteksi otomatis modul dan fungsi uji;
- CLI yang efektif untuk meningkatkan kontrol atas apa yang ingin Anda jalankan atau lewati;
- Ekosistem plugin pihak ketiga yang besar;
- Jadwal - berbagai jenis, aplikasi yang berbeda;
- Bekerja dengan kerangka pengujian unit tradisional.
Deteksi tes otomatis dan dapat dikonfigurasi
Secara default,
pytest
mengharapkan untuk menemukan tes dalam modul Python yang namanya dimulai dengan
test_
atau diakhiri dengan
_test.py
. Selain itu, secara default, ia mengharapkan nama-nama fungsi tes untuk memulai dengan awalan
test_
. Namun, protokol deteksi tes ini dapat diubah dengan menambahkan konfigurasi Anda sendiri ke salah satu
pytest
konfigurasi
pytest
.
Mari kita lihat fungsi tes yang sangat sederhana:
class CheckClass(object): def one_check(self): x = "this" assert 'h' in x def two_check(self): x = "hello" assert hasattr(x, 'check')
Pernahkah Anda memperhatikan sesuatu? Tidak ada
assertEqual
atau
assertDictEqual
, hanya pernyataan yang dapat diakses dan dimengerti. Tidak perlu mengimpor fungsi-fungsi ini untuk hanya membandingkan dua objek. Menegaskan adalah apa yang sudah dimiliki Python dan tidak perlu menemukan kembali roda.
Kode templat? Jangan khawatir, perlengkapan terburu-buru untuk menyelamatkan!
Lihatlah fungsi tes yang menguji operasi dasar dalam program Wallet:
// test_wallet.py from wallet import Wallet def test_default_initial_amount(): wallet = Wallet() assert wallet.balance == 0 wallet.close() def test_setting_initial_amount(): wallet = Wallet(initial_amount=100) assert wallet.balance == 100 wallet.close() def test_wallet_add_cash(): wallet = Wallet(initial_amount=10) wallet.add_cash(amount=90) assert wallet.balance == 100 wallet.close() def test_wallet_spend_cash(): wallet = Wallet(initial_amount=20) wallet.spend_cash(amount=10) assert wallet.balance == 10 wallet.close()
Ahem, menarik! Pernahkah Anda memperhatikan? Ada banyak kode boilerplate. Hal lain yang patut dicatat adalah bahwa tes ini melakukan hal lain selain menguji bagian fungsional, misalnya, membuat Dompet dan menutupnya dengan
wallet.close()
.
Sekarang mari kita lihat bagaimana Anda bisa menghilangkan kode boilerplate menggunakan
pytest
pytest.
import pytest from _pytest.fixtures import SubRequest from wallet import Wallet
Bagus bukan? Fungsi tes sekarang kompak dan melakukan apa yang seharusnya mereka lakukan. Dompet dikonfigurasikan, dipasang, dan ditutup menggunakan
wallet
. Fixture tidak hanya membantu menulis kode yang dapat digunakan kembali, tetapi juga menambahkan konsep berbagi data. Jika Anda perhatikan dengan cermat, jumlah dalam
wallet
adalah bagian dari data uji yang disediakan secara eksternal oleh logika uji, dan tidak secara kaku dipasang di dalam fungsi.
@pytest.mark.parametrize('wallet', [(10,)], indirect=True)
Dalam lingkungan yang lebih terkontrol, Anda mungkin memiliki file dengan data pengujian, misalnya
test-data.ini
di repositori atau shell yang dapat membacanya, sementara fungsi pengujian Anda dapat memanggil berbagai shell untuk membaca data pengujian.
Namun disarankan untuk meletakkan semua perlengkapan Anda di file
conftest.py
khusus. Ini adalah file khusus di pytest yang memungkinkan tes untuk mendeteksi perlengkapan global.
Tapi saya punya test case yang ingin saya jalankan di dataset berbeda!
Jangan khawatir,
pytest
memiliki fitur keren untuk
pytest
parameter perlengkapan Anda. Mari kita lihat sebuah contoh.
Misalkan produk Anda memiliki CLI yang dikelola secara lokal. Selain itu, produk Anda memiliki banyak parameter default yang ditetapkan saat startup, dan Anda ingin memeriksa semua nilai parameter ini.
Anda mungkin berpikir untuk menulis test case terpisah untuk masing-masing parameter ini, tetapi dengan
pytest
semuanya jauh lebih sederhana!
@pytest.mark.parametrize(βsetting_name, setting_valueβ, [('qdb_mem_usage', 'low'), ('report_crashes', 'yes'), ('stop_download_on_hang', 'no'), ('stop_download_on_disconnect', 'no'), ('reduce_connections_on_congestion', 'no'), ('global.max_web_users', '1024'), ('global.max_downloads', '5'), ('use_kernel_congestion_detection', 'no'), ('log_type', 'normal'), ('no_signature_check', 'no'), ('disable_xmlrpc', 'no'), ('disable_ntp', 'yes'), ('ssl_mode', 'tls_1_2'),])def test_settings_defaults(self, setting_name, setting_value): assert product_shell.run_command(setting_name) == \ self.βThe current value for \'{0}\' is \'{1}\'.β.format(setting_name, setting_value), \ 'The {} default should be {}'.format(preference_name, preference_value)
Keren bukan? Anda baru saja menulis 13 test case (masing-masing menetapkan nilai
setting_value
berbeda), dan di masa depan, jika Anda menambahkan parameter baru ke produk Anda, yang perlu Anda lakukan adalah menambahkan tuple lain.
Bagaimana pytest berintegrasi dengan pengujian antarmuka pengguna dengan uji Selenium dan API?
Nah, produk Anda mungkin memiliki beberapa antarmuka. CLI - seperti yang kami katakan di atas. Mirip dengan GUI dan API. Sebelum menggunakan produk perangkat lunak Anda, penting untuk menguji semuanya. Dalam perangkat lunak perusahaan, di mana beberapa komponen saling berhubungan dan bergantung satu sama lain, perubahan pada satu bagian dapat memengaruhi yang lain.
Ingat bahwa
pytest
hanyalah kerangka kerja untuk pengujian yang mudah, bukan jenis pengujian khusus. Artinya, Anda bisa membuat tes untuk GUI menggunakan Selenium atau, misalnya, tes untuk API dengan pustaka
requests
dari Python dan menjalankannya dengan
pytest
.
Misalnya, pada level tinggi, ini bisa berupa pemeriksaan struktur repositori.

Seperti yang Anda lihat pada gambar di atas, ini memberikan peluang bagus untuk memisahkan komponen:
apiobjects : Tempat yang bagus untuk membuat pembungkus untuk memanggil titik akhir API. Anda mungkin memiliki
BaseAPIObject
dan kelas turunan yang memenuhi persyaratan Anda.
pembantu : Anda dapat menambahkan metode pembantu Anda di sini.
lib : file perpustakaan yang dapat digunakan oleh berbagai komponen, misalnya,
conftest
Anda di
conftest
, objek
pageobjects
, dll.
pageobjects :
PageObjects
arsitektur
PageObjects dapat digunakan untuk membuat kelas untuk berbagai halaman GUI. Kami menggunakan
Webium , yang merupakan pustaka implementasi templat Objek Halaman untuk Python.
suites : Anda dapat menulis set cek pylint Anda sendiri untuk kode, mereka akan membantu Anda mendapatkan lebih banyak kepercayaan pada kualitas kode Anda.
tes : Anda dapat membuat katalog tes berdasarkan preferensi Anda. Ini akan membuatnya mudah untuk mengelola dan meninjau tes Anda.
Saya membawanya hanya untuk referensi, struktur repositori dan dependensi dapat diatur sesuai dengan kebutuhan pribadi Anda.
Saya punya banyak test case dan saya ingin mereka berjalan secara paralel
Anda dapat memiliki banyak test case di set Anda, dan kebetulan Anda perlu menjalankannya secara paralel dan mengurangi keseluruhan waktu pelaksanaan pengujian.
Pytest menawarkan plugin uji coba paralel mengagumkan yang disebut
pytest-xdist
, yang menambahkan beberapa mode eksekusi unik ke pytest dasar. Instal plugin ini menggunakan
pip
.
pip install pytest-xdist
Mari kita lihat cara kerjanya dengan sebuah contoh.
Saya memiliki repositori pengujian otomatis CloudApp untuk pengujian GUI Selenium saya. Selain itu, terus berkembang dan diperbarui dengan tes baru dan sekarang ini memiliki ratusan tes. Yang ingin saya lakukan adalah menjalankannya secara paralel dan mengurangi keseluruhan waktu pelaksanaan pengujian.
Di terminal, cukup ketik
pytest
di folder root proyek / folder tes. Ini akan memungkinkan Anda untuk menjalankan semua tes.
pytest -s -v -n=2

pytest-xdist
akan menjalankan semua tes secara paralel!
Dengan cara ini, Anda juga dapat menjalankan beberapa browser secara paralel.
Laporan
Pytest hadir dengan dukungan bawaan untuk membuat file hasil pengujian yang dapat dibuka menggunakan Jenkins, Bamboo, atau server integrasi berkelanjutan lainnya. Gunakan yang berikut ini:
pytest test/file/path β junitxml=path
Ini akan membantu menghasilkan file XML yang hebat yang dapat dibuka dengan banyak parser.
Kesimpulan
Popularitas Pytest meningkat setiap tahun. Selain itu, ia memiliki dukungan komunitas yang kuat, yang memungkinkan Anda untuk mengakses banyak ekstensi, seperti
pytest-django , yang akan membantu Anda menulis tes untuk aplikasi web di Django. Ingatlah bahwa pytest mendukung kasus uji yang paling bebas, jadi jika Anda menggunakan
unittest
, pytest harus dipertimbangkan secara lebih rinci.
Sumber
Itu saja. Sampai jumpa di
lapangan !