Rumah > Artikel > pembangunan bahagian belakang > Melaksanakan Ujian Unit dalam ReadmeGenie
Dalam siaran ini, saya akan melalui perjalanan melaksanakan ujian unit, mengendalikan cabaran konfigurasi yang kompleks dan memperkenalkan liputan kod yang mantap dalam ReadmeGenie. Daripada reka bentuk ujian awal hingga menyediakan cangkuk prakomit, proses ini melibatkan pelbagai peningkatan dalam kualiti kod, kebolehpercayaan dan aliran kerja pembangun.
Untuk bermula, saya memilih unittest sebagai rangka kerja utama untuk menulis dan melaksanakan ujian. Ujian unit terbina dalam Python menyediakan pendekatan berstruktur untuk mentakrifkan kes ujian, dan penyepaduannya dengan olok-olok menjadikannya sesuai untuk menguji konfigurasi kompleks dan panggilan API.
Saya mencipta pelari ujian khusus (tests/test_runner.py) untuk penemuan automatik dan pelaksanaan semua fail ujian dalam direktori ujian/:
# tests/test_runner.py import unittest if __name__ == "__main__": loader = unittest.TestLoader() suite = loader.discover(start_dir="tests", pattern="test_*.py") runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)
Persediaan ini memastikan bahawa menjalankan python tests/test_runner.py akan memuatkan dan menjalankan semua fail ujian secara automatik, menjadikannya mudah untuk mengesahkan kefungsian keseluruhan projek.
Projek ReadmeGenie memerlukan ujian komprehensif untuk beberapa komponen:
Setiap fail ujian dinamakan mengikut modul yang diuji (cth., test_parse_arg.py untuk penghuraian hujah dan test_model.py untuk fungsi model), memastikan struktur yang jelas dan boleh diselenggara.
Menyediakan test_loadConfig.py ternyata menjadi bahagian yang paling mencabar dalam projek ini. Pada mulanya, saya menghadapi isu berterusan yang berkaitan dengan pembolehubah persekitaran dan semakan laluan fail. Memandangkan load_config() bertujuan untuk mengendalikan pelbagai sumber konfigurasi (cth., pembolehubah persekitaran, fail .env, JSON dan fail TOML), ujian memerlukan ejekan yang meluas untuk mensimulasikan persekitaran ini dengan tepat.
Isu utama yang terlibat:
Konflik Pembolehubah Persekitaran: Pembolehubah persekitaran sedia ada kadangkala mengganggu nilai yang dipermainkan. Menggunakan @patch.dict("os.environ", {}, clear=True), saya mengosongkan pembolehubah persekitaran dalam skop ujian untuk memastikan hasil yang konsisten.
Semakan Laluan Fail: Memandangkan load_config() menyemak kewujudan fail, saya menggunakan os.path.exists untuk mensimulasikan senario di mana fail konfigurasi ada atau tiada.
Mengejek terbuka dan toml.load: Ini memerlukan ejekan yang tepat untuk mengendalikan kes fail konfigurasi yang hilang, kosong atau diisi. Menggunakan mock_open dengan tampalan pada toml.load, saya mensimulasikan setiap situasi dengan berkesan.
Selepas menyelesaikan isu ini, test_loadConfig.py kini merangkumi tiga senario utama:
Berikut ialah versi terakhir test_loadConfig.py:
# tests/test_runner.py import unittest if __name__ == "__main__": loader = unittest.TestLoader() suite = loader.discover(start_dir="tests", pattern="test_*.py") runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)
Dengan ujian kami disediakan, kami menumpukan pada mengukur dan meningkatkan liputan menggunakan coverage.py. Dengan menetapkan ambang 80%, kami menyasarkan untuk memastikan semua bahagian kritikal kod diuji.
Saya mengkonfigurasi coverage.py dengan tetapan berikut dalam pyproject.toml:
import unittest from unittest.mock import mock_open, patch from loadConfig import load_config class TestLoadConfig(unittest.TestCase): @patch.dict("os.environ", {}, clear=True) @patch("loadConfig.os.getenv", side_effect=lambda key, default=None: default) @patch("loadConfig.os.path.exists", return_value=False) @patch("builtins.open", new_callable=mock_open, read_data="{}") @patch("loadConfig.toml.load", return_value={}) def test_load_config_empty_file(self, mock_toml_load, mock_open_file, mock_exists, mock_getenv): config = load_config() self.assertEqual(config, {}) @patch.dict("os.environ", {}, clear=True) @patch("loadConfig.os.getenv", side_effect=lambda key, default=None: default) @patch("loadConfig.os.path.exists", return_value=True) @patch("builtins.open", new_callable=mock_open, read_data='{"api_key": "test_key"}') @patch("loadConfig.toml.load", return_value={"api_key": "test_key"}) def test_load_config_with_valid_data(self, mock_toml_load, mock_open_file, mock_exists, mock_getenv): config = load_config() self.assertEqual(config.get("api_key"), "test_key") @patch.dict("os.environ", {}, clear=True) @patch("loadConfig.os.getenv", side_effect=lambda key, default=None: default) @patch("loadConfig.os.path.exists", return_value=False) @patch("builtins.open", side_effect=FileNotFoundError) @patch("loadConfig.toml.load", return_value={}) def test_load_config_file_not_found(self, mock_toml_load, mock_open_file, mock_exists, mock_getenv): config = load_config() self.assertEqual(config, {})
Konfigurasi ini termasuk liputan cawangan, menyerlahkan baris yang hilang dan menguatkuasakan ambang liputan minimum 75%.
Untuk menyepadukan ini ke dalam aliran kerja pembangunan, saya menambah cangkuk prakomit untuk memastikan liputan kod disemak pada setiap komit. Jika liputan jatuh di bawah 75%, komitmen disekat, mendorong pembangun untuk meningkatkan liputan sebelum meneruskan:
[tool.coverage.run] source = [""] branch = true omit = ["tests/*"] [tool.coverage.report] show_missing = true fail_under = 75
Laporan liputan terbaru kami menunjukkan:
- repo: local hooks: - id: check-coverage name: Check Coverage entry: bash -c "coverage run --source=. -m unittest discover -s tests && coverage report -m --fail-under=75" language: system
Walaupun liputan kukuh di sesetengah kawasan (cth., loadConfig.py pada 100%), masih terdapat peluang untuk penambahbaikan dalam models/model.py dan readme_genie.py. Memfokuskan pada cawangan yang belum diuji dan kes tepi akan menjadi penting untuk mencapai matlamat kami liputan keseluruhan 85% atau lebih tinggi.
Projek ini telah banyak mengajar saya tentang ujian unit, ejekan dan liputan kod. Menyediakan test_loadConfig.py merupakan pengalaman yang sangat berharga, mendorong saya untuk meneroka tahap mengejek konfigurasi yang lebih mendalam. Cangkuk pra-komit untuk perlindungan telah menambah lapisan jaminan kualiti, menguatkuasakan piawaian ujian yang konsisten.
Melangkah ke hadapan, saya menyasarkan untuk memperhalusi lagi ujian ini dengan menambah kes tepi dan menambah baik liputan cawangan. Ini bukan sahaja menjadikan ReadmeGenie lebih teguh tetapi juga meletakkan asas yang kukuh untuk pembangunan masa depan.
Atas ialah kandungan terperinci Melaksanakan Ujian Unit dalam ReadmeGenie. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!