使用Python,SQLAlchemy和Factory Boy进行敏捷数据库集成测试

所以您对测试感兴趣,不是吗?
还没做吗 那是开始的正确时间!

在这个小例子中,我将展示一个可能的过程来轻松测试与数据库交互的代码段。

在进行数据库集成测试时,通常每个测试用例都不需要做些事情:

  • 在一个或多个表中设置测试数据(设置)
  • 运行被测功能
  • 检查数据库的实际状态是否符合预期(断言)
  • 清除所有内容以进行下一个测试(拆卸)

如果不仔细地做,这些步骤中的大多数都可能带来多余的代码行。 而且,最终的测试运行通常很慢。

以我的经验,最困难的部分是设置拆除数据库状态以测试相关代码段。

很简单,我将只插入带有几个原始“插入”查询的数据和带有“删除”的清理表。

做完了!

这样做,您很可能会遇到难以重用,难以阅读甚至难以维护的SQL代码。 一种非常繁琐且容易出错的方法。
此外,您可能会遇到性能问题,尤其是在涉及更多表或级联删除的情况下。

您,在阅读了300行SQL语句之后

隔离测试用例的最佳方法是SQL的一个现有功能: Transactions 是的,他们可以为您提供帮助。

假设您正在使用出色的pytest框架进行测试,那么一些精心设计的固定装置将完成这项工作:

哇! 太简单?! 是的。
简而言之:

  • connection固定装置可确保只有一个数据库连接,并且在运行所有测试后将其关闭。
  • session固定装置可确保每个测试在单独的事务中运行,并且回滚保证了清除。 回滚将始终比任何自定义删除查询更快,并且不会忘记恢复任何内容anything

…好的,但是我们还没有输入任何数据!

您说得对,让我向您介绍…

工厂男孩

Factory Boy是用于创建按需预配置对象的工具。 它非常方便,我个人建议您广泛使用它。

假设您有一个User类,其中包含nameemail 。 使用Factory Boy,您可以创建与您的User模型绑定的类。

现在,仅调用UserFactory.build()将生成一个已填充的 User实例。
有很多功能,例如属性覆盖,序列等。 看看文档!

嗯,很好! 但是,这与数据库有什么关系?

好吧,如果我说您可以实际将工厂与SQLAlchemy模型绑定在一起呢?

就这样! 现在, 在数据库中创建并拥有一个用户就像编写UserFactory.create()一样简单。

心神。

需要更多物体? UserFactory.create_batch(6)

心神。 再来一次

如果您认为自己没有做到这一点,那么以下是其出色的全面集成测试:

在第5行,您可以看到SQLAlchemy会话如何绑定到工厂类。 工厂执行的每项操作都将使用我们的会话,其生命周期由灯具本身处理。

简单,几行长,干净,易于理解,并且……显然有效! 😃
如此顺利的集成测试!

当然,此示例是有意的,您可以在我故意创建的此存储库中找到更真实,更有组织的示例。

概括

为了进行干净的数据库集成测试,您应该致力于:

  1. 在隔离的事务中运行测试用例,然后回滚它们。
  2. 将您的实体描述为模型,并将其创建委托给工厂系统。

如果没有您所用语言的工厂库或系统,请自己动手并开源!