Rumah > pembangunan bahagian belakang > Tutorial Python > Mengendalikan Model Tidak Terurus dalam Pytest-Django

Mengendalikan Model Tidak Terurus dalam Pytest-Django

Susan Sarandon
Lepaskan: 2024-12-31 08:34:14
asal
311 orang telah melayarinya

Handling Unmanaged Models in Pytest-Django

Cabaran Menguji Model Tidak Terurus

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.

Pendekatan 1: Tandakan Semua Model sebagai Terurus

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
Salin selepas log masuk
Salin selepas log masuk

Nota: Agar pendekatan ini berfungsi, anda perlu menambah pilihan --no-migrations pada tetapan pytest anda (atau pytest.ini)

Rujukan: Limpahan Tindanan

Kebaikan:

  • Mudah untuk dilaksanakan.

Keburukan:

  • Melangkau ujian migrasi, yang boleh menyebabkan masalah apabila berbilang pembangun sedang mengusahakan projek yang sama.

Pendekatan 2: Cipta Model Tidak Terurus Secara Manual

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)
Salin selepas log masuk
Salin selepas log masuk

Kebaikan:

  • Menguji migrasi sebagai sebahagian daripada kes ujian anda.

Keburukan:

  • Sedikit lebih kompleks.
  • transaksi=True tidak berfungsi dengan pendekatan ini (dibincangkan dalam bahagian seterusnya).

Memahami Ujian Transaksional

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
Salin selepas log masuk

Membuat Ujian Transaksi Berfungsi dengan Model Tidak Terurus

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
Salin selepas log masuk
Salin selepas log masuk

Mengelakkan transaksi=Benar dengan on_commit Hooks (jika boleh)

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)
Salin selepas log masuk
Salin selepas log masuk

Rujukan

  • Dokumentasi pytest-django
  • Limpahan Tindanan: Menguji Model Tidak Terurus

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!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan