Dalam projek Django, kadangkala kami menemui model yang tidak terurus—model yang tidak terurus = Benar dalam pilihan meta mereka. Model ini boleh menyukarkan ujian, terutamanya apabila persediaan ujian anda melibatkan gabungan model terurus dan tidak terurus atau berbilang pangkalan data (mis., satu dengan model terurus dan satu lagi dengan model tidak terurus).
Siaran blog ini meneroka pendekatan untuk menguji model tidak terurus dengan pytest-django, menyerlahkan kebaikan, keburukan dan penyelesaian untuk membantu anda mengurus senario ini dengan berkesan.
Satu cara mudah untuk mengendalikan model yang tidak terurus semasa ujian adalah dengan menandai model tersebut sebagai terurus buat sementara waktu. Begini cara anda boleh melakukannya:
# Add this to conftest.py @pytest.hookimpl(tryfirst=True) def pytest_runtestloop(): from django.apps import apps unmanaged_models = [] for app in apps.get_app_configs(): unmanaged_models += [m for m in app.get_models() if not m._meta.managed] for m in unmanaged_models: m._meta.managed = True
Nota: Agar pendekatan ini berfungsi, anda perlu menambah pilihan --no-migrations pada tetapan pytest anda (atau pytest.ini)
Rujukan: Limpahan Tindanan
Kebaikan:
Keburukan:
Sebagai alternatif, anda boleh membuat model tidak terurus secara manual semasa persediaan ujian. Pendekatan ini memastikan bahawa migrasi diuji:
@pytest.fixture(scope="session", autouse=True) def django_db_setup(django_db_blocker, django_db_setup): with django_db_blocker.unblock(): for _connection in connections.all(): with _connection.schema_editor() as schema_editor: setup_unmanaged_models(_connection, schema_editor) yield def setup_unmanaged_models(connection, schema_editor): from django.apps import apps unmanaged_models = [ model for model in apps.get_models() if model._meta.managed is False ] for model in unmanaged_models: if model._meta.db_table in connection.introspection.table_names(): schema_editor.delete_model(model) schema_editor.create_model(model)
Kebaikan:
Keburukan:
Pytest-django menyediakan lekapan pangkalan data: django_db dan django_db(transaction=True). Begini perbezaannya:
django_db: Menggulung semula perubahan pada penghujung kes ujian, bermakna tiada komitmen sebenar dibuat pada pangkalan data.
django_db(transaction=True): Melakukan perubahan dan memotong jadual pangkalan data selepas setiap kes ujian. Memandangkan hanya model terurus dipotong selepas setiap ujian, inilah sebabnya model tidak terurus memerlukan pengendalian khas semasa ujian transaksi.
Contoh Kes Ujian
@pytest.mark.django_db def test_example(): # Test case logic here pass @pytest.mark.django_db(transaction=True) def test_transactional_example(): # Test case logic here pass
Memandangkan ujian transaksi hanya memotong model terurus, kami boleh mengubah suai model yang tidak terurus untuk diurus semasa ujian dijalankan. Ini memastikan ia termasuk dalam pemangkasan:
# Add this to conftest.py @pytest.hookimpl(tryfirst=True) def pytest_runtestloop(): from django.apps import apps unmanaged_models = [] for app in apps.get_app_configs(): unmanaged_models += [m for m in app.get_models() if not m._meta.managed] for m in unmanaged_models: m._meta.managed = True
Dalam senario yang melibatkan cangkuk on_commit, anda boleh mengelak daripada menggunakan ujian transaksi dengan menangkap dan melaksanakan panggilan balik on_commit secara langsung, menggunakan lekapan django_capture_on_commit_callbacks daripada pytest-django(>= v.4.4):
@pytest.fixture(scope="session", autouse=True) def django_db_setup(django_db_blocker, django_db_setup): with django_db_blocker.unblock(): for _connection in connections.all(): with _connection.schema_editor() as schema_editor: setup_unmanaged_models(_connection, schema_editor) yield def setup_unmanaged_models(connection, schema_editor): from django.apps import apps unmanaged_models = [ model for model in apps.get_models() if model._meta.managed is False ] for model in unmanaged_models: if model._meta.db_table in connection.introspection.table_names(): schema_editor.delete_model(model) schema_editor.create_model(model)
Adakah anda mempunyai pendekatan atau petua lain untuk mengendalikan model yang tidak terurus? Kongsi mereka dalam komen di bawah!
Atas ialah kandungan terperinci Mengendalikan Model Tidak Terurus dalam Pytest-Django. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!