我真的很难为一个大型Django项目编写有效的单元测试。我具有相当好的测试覆盖范围,但是我已经意识到,我一直在编写的测试绝对是集成/验收测试,而不是单元测试,而且我的应用程序中有关键部分没有得到有效测试。我想尽快解决此问题。
这是我的问题。我的模式是深层的关系,并且非常注重时间,这给我的模型对象带来了很高的内部耦合和很多状态。我的许多模型方法都是基于时间间隔进行查询的,而在带有auto_now_add
时间戳的字段中,我有很多事情要做。因此,以如下所示的方法为例:
def summary(self, startTime=None, endTime=None):
# ... logic to assign a proper start and end time
# if none was provided, probably using datetime.now()
objects = self.related_model_set.manager_method.filter(...)
return sum(object.key_method(startTime, endTime) for object in objects)
一种方法如何测试这样的东西?
这是我到目前为止的位置。在我看来,应该对单元测试目标的参数进行一些模拟行为by key_method
,是否summary
正确地过滤/聚合以产生正确的结果?
模拟datetime.now()很简单,但是我如何模拟其余的行为呢?
- 我可以使用固定装置,但是我听说过使用固定装置构建数据的利弊(可维护性差是我的主意)。
- 我也可以通过ORM设置数据,但这可能是有局限性的,因为那时我还必须创建相关的对象。而且ORM不允许您
auto_now_add
手动处理字段。 - 模拟ORM是另一种选择,但是模拟深度嵌套的ORM方法不仅棘手,而且ORM代码中的逻辑也从测试中被模拟出来,而模拟似乎使测试真正依赖于内部和内部依赖。被测功能。
最难破解的螺母似乎是这样的功能,它们位于几层模型和较低级别的功能上,并且非常依赖于时间,即使这些功能可能并不十分复杂。我的总体问题是,无论我如何看待它,我的测试看起来都比它们要测试的功能复杂得多。
从现在开始,您应该首先编写单元测试,这可以帮助您在编写实际的生产代码之前发现设计中的可测试性问题。
—
2013年
这是有帮助的,但是并没有真正解决如何最好地测试内在有状态,ORM繁重的应用程序的问题。
—
2013年
您必须抽象掉持久层
—
Chedy2149
假设听起来很不错,但是在项目维护方面,我认为在业务逻辑和文档详尽的Django ORM之间插入定制的持久层不会有不小的代价。突然,这些类挤满了许多微小的中间方法,它们本身需要随着时间的推移而重构。但这也许在可测试性至关重要的地方是合理的。
—
2013年
检出此内容:vimeo.com/43612849,以及此内容:vimeo.com/15007792
—
Chedy2149