测试非托管模型的挑战
在 Django 项目中,我们偶尔会遇到非托管模型,即元选项中没有 Managed = True 的模型。这些模型可能会使测试变得棘手,特别是当您的测试设置涉及托管和非托管模型或多个数据库的混合时(例如,一个包含托管模型,另一个包含非托管模型)。
这篇博文探讨了使用 pytest-django 测试非托管模型的方法,重点介绍了优点、缺点和解决方法,以帮助您有效管理这些场景。
方法 1:将所有模型标记为托管
在测试期间处理非托管模型的一种直接方法是将它们暂时标记为托管。具体方法如下:
# 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
注意:要使此方法发挥作用,您需要在 pytest 设置(或 pytest.ini)中添加 --no-migrations 选项
参考:Stack Overflow
优点:
- 易于实施。
缺点:
- 跳过迁移测试,当多个开发人员处理同一个项目时,这可能会导致问题。
方法 2:手动创建非托管模型
或者,您可以在测试设置期间手动创建非托管模型。这种方法可确保迁移经过测试:
@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)
优点:
- 将迁移作为测试用例的一部分进行测试。
缺点:
- 稍微复杂一点。
- transaction=True 不适用于此方法(在下一节中讨论)。
了解事务测试
Pytest-django 提供了数据库固定装置:django_db 和 django_db(transaction=True)。它们的区别如下:
django_db: 在测试用例结束时回滚更改,这意味着不会对数据库进行实际提交。
django_db(transaction=True): 在每个测试用例后提交更改并截断数据库表。由于每次测试后只有托管模型会被截断,这就是非托管模型在事务测试期间需要特殊处理的原因。
示例测试用例
@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
使事务测试适用于非托管模型
由于事务测试仅截断托管模型,因此我们可以在测试运行期间将非托管模型修改为托管模型。这确保它们包含在截断中:
# 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
使用 on_commit Hooks 避免 transaction=True (如果可能的话)
在涉及 on_commit 挂钩的场景中,您可以通过直接捕获和执行 on_commit 回调来避免使用事务测试,使用 pytest-django(>= v.4.4) 中的固定装置 django_capture_on_commit_callbacks:
@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)
参考
- pytest-django 文档
- Stack Overflow:测试非托管模型
您还有其他处理非托管模型的方法或技巧吗?在下面的评论中分享它们!
以上是在 Pytest-Django 中处理非托管模型的详细内容。更多信息请关注PHP中文网其他相关文章!

Python更易学且易用,C 则更强大但复杂。1.Python语法简洁,适合初学者,动态类型和自动内存管理使其易用,但可能导致运行时错误。2.C 提供低级控制和高级特性,适合高性能应用,但学习门槛高,需手动管理内存和类型安全。

Python和C 在内存管理和控制方面的差异显着。 1.Python使用自动内存管理,基于引用计数和垃圾回收,简化了程序员的工作。 2.C 则要求手动管理内存,提供更多控制权但增加了复杂性和出错风险。选择哪种语言应基于项目需求和团队技术栈。

Python在科学计算中的应用包括数据分析、机器学习、数值模拟和可视化。1.Numpy提供高效的多维数组和数学函数。2.SciPy扩展Numpy功能,提供优化和线性代数工具。3.Pandas用于数据处理和分析。4.Matplotlib用于生成各种图表和可视化结果。

选择Python还是C 取决于项目需求:1)Python适合快速开发、数据科学和脚本编写,因其简洁语法和丰富库;2)C 适用于需要高性能和底层控制的场景,如系统编程和游戏开发,因其编译型和手动内存管理。

Python在数据科学和机器学习中的应用广泛,主要依赖于其简洁性和强大的库生态系统。1)Pandas用于数据处理和分析,2)Numpy提供高效的数值计算,3)Scikit-learn用于机器学习模型构建和优化,这些库让Python成为数据科学和机器学习的理想工具。

每天学习Python两个小时是否足够?这取决于你的目标和学习方法。1)制定清晰的学习计划,2)选择合适的学习资源和方法,3)动手实践和复习巩固,可以在这段时间内逐步掌握Python的基本知识和高级功能。

Python在Web开发中的关键应用包括使用Django和Flask框架、API开发、数据分析与可视化、机器学习与AI、以及性能优化。1.Django和Flask框架:Django适合快速开发复杂应用,Flask适用于小型或高度自定义项目。2.API开发:使用Flask或DjangoRESTFramework构建RESTfulAPI。3.数据分析与可视化:利用Python处理数据并通过Web界面展示。4.机器学习与AI:Python用于构建智能Web应用。5.性能优化:通过异步编程、缓存和代码优

Python在开发效率上优于C ,但C 在执行性能上更高。1.Python的简洁语法和丰富库提高开发效率。2.C 的编译型特性和硬件控制提升执行性能。选择时需根据项目需求权衡开发速度与执行效率。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

Dreamweaver Mac版
视觉化网页开发工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)