Python Django中的单元测试紧耦合模型

Python Django中的单元测试紧耦合模型,python,django,unit-testing,model-view-controller,mocking,Python,Django,Unit Testing,Model View Controller,Mocking,我对django和单元测试都是新手,我正在尝试为我的模型构建单元测试,但遇到了一些困难 我有几个模型密切合作: 资源将维护文件资源 MetadataField表示可以添加到资源的元数据字段,对应于一个充满字段的表 MetadataValue将MetadataField ID与资源ID和相应的值匹配,这是资源-MetadataField多对多关系的中间表 MetadataSchema表示由许多MetadataFields组成的模式。每个资源都分配了一个元数据模式,该模式控制由哪个元数据字段表示 关

我对django和单元测试都是新手,我正在尝试为我的模型构建单元测试,但遇到了一些困难

我有几个模型密切合作:

资源
将维护文件资源

MetadataField
表示可以添加到资源的元数据字段,对应于一个充满字段的表

MetadataValue
将MetadataField ID与资源ID和相应的值匹配,这是资源-MetadataField多对多关系的中间表

MetadataSchema
表示由许多
MetadataFields
组成的模式。每个
资源
都分配了一个
元数据模式
,该模式控制由哪个
元数据字段
表示

关系:

Resource - MetadataField       : Many-to-Many through MetadataValue
MetadataValue - MetadataSchema : Many-to-Many
Resource - MetadataSchema      : One-to-Many
我不知道如何编写测试来处理这些模型。本教程中的模型测试似乎主要包括初始化对象和验证属性。如果我对这些对象进行任何设置,尽管它需要使用所有其他对象,那么测试都将依赖于它们不打算测试的代码。 e、 如果我想创建一个资源,我还应该为它分配一个元数据模式和该模式中字段的值

我在django中查找过单元测试模型的好例子,但没有找到任何东西(django网站似乎没有单元测试,所有的测试都很差/缺少测试,或者在一些情况下有很好的测试,但几乎没有使用任何模型)

以下是我看到的可能方法:

  • 进行大量模拟,以确保我只测试一个类,并保持对模型的单元测试非常简单,只测试它们的方法/属性,但不测试关系是否正常运行。然后依靠更高级别的集成测试来发现关系中的任何问题等
  • 设计确实依赖于其他功能的单元测试,并接受一个功能中的中断将中断多个测试,前提是可以很容易地看到故障发生的位置。因此,我可能会有一种方法来测试我是否可以成功地将
    MetadataValue
    添加到资源中,这需要设置至少一个
    MetadataSchema
    Resource
    。然后,我可以使用
    try-except
    块来确保如果在断言处理我实际要测试的内容之前测试失败,它会给出一条特定的错误消息,提示故障在其他地方。这样我可以快速扫描多条失败的测试消息以找到错误真正的罪魁祸首。但不可能在每次测试中都可靠地进行这种分离

我很难理解这一点,所以我不知道这一切是否有意义,但如果有针对这种情况的最佳实践,请告诉我!感谢使用,它们允许您加载模型数据而不编写代码。

对我来说,单元测试的目的是分离代码单元,只测试它们,而不是测试它们如果我正确理解你的想法,你想创建一个更具集成性的测试(两个或多个模型之间的关系),这也是一个非常有用的测试层,但仍然是一个不同的测试层:)

为了测试单独的模块,特别是当它们使用大量代码时,我更喜欢模拟依赖项。Google作为Python模拟的第一选择返回(我想有很多)

另一件事是,如果有太多依赖项,您必须对其进行模拟,这可能意味着您必须重新考虑您的体系结构,因为紧密耦合:)


祝你好运

您可以使用django Fixture加载数据进行测试,如果您的模型发生了很大变化,这可能会非常耗时,而且很难维护


我建议您使用类似的库,它允许您在需要时根据需要为测试创建对象。您可以设置任意数量的工厂,您可以看到一些示例,您还可以看到一些使用模拟的示例以及测试django应用程序的许多提示。

但在某些情况下,保存一个模型的数据需要将数据保存到另一个模型中(即更新资源,元数据存储在单独的表中)。因此,fixture不会回避这个问题(除非我以完全错误的方式思考问题-很有可能!)如果单元测试太难编写,那么可能会指出设计过于复杂。例如,我不确定是否看到MetaDataField的值?每个MetaDataValue表都不能有资源和值的列。然后,您将为每种类型的元数据创建一个表。更清楚一点,也不太奇怪。当然,这取决于您预计将拥有多少不同类型的元数据。此外,我发现您希望为已经编写的代码编写测试。这并不坏(通常更多的测试是好的)。不过,最好先编写测试(称为TestDrivenDevelopment),以便尽早发现问题。通常很难为过于复杂的代码编写测试;)