Flask中SQLAlchemy的实际单元测试

时间:2017-06-14 08:46:04

标签: python unit-testing sqlalchemy

我正在搜索网络和搜索关键字,例如"单元测试sqlalchemy"但所有答案都涉及创建真实数据库(sqlite,postgres)来测试它。当你创造真实的东西时,它不是单元测试。

创建sqlite DB与在磁盘上创建文件没什么不同,但令人惊讶的是人们希望只模拟后者。我已经尝试使用setUp和sys.modules模拟数据库导入,它可以工作,但它模拟太多并且使用模型作为测试对象并非易事(模拟不支持所有需要的东西,如下一步

是否存在模拟数据库行为(创建数据库,提交,查询)的技术,但是仍然可以访问模型来对它们进行基本检查?也许有一些库只能模拟连接?

1 个答案:

答案 0 :(得分:3)

跟进我的这个Q将会被关闭',我相信没有单一的权威方式可以做到这一点,你需要选择你想如何模拟事情发生了。

基本上,SQLAlchemy是数据库设计和查询的抽象。这意味着,您可以将模型放在抽象中的不同位置:

  1. 真实数据库,包含测试数据
  2. 你可以设置一个sqlite实例。这个解决方案的优点是你不需要在python堆栈中调整任何东西,因为你在系统的边界上改变了东西,缺点是它需要做更多的工作维持,从而增加风险。

    • 带有数据文件

    将这些数据文件作为资源存储在您的代码中。然后为正在运行的测试加载正确的数据库。在测试之后,您需要tearDown()方法将db恢复到其原始状态。 好的一面是,用很少的代码很容易实现,但如果你修改你的模型,那将是一件很棒的工作。

    • 使用内存数据库

    在那里,您使用setUp()方法填充数据,并且没有数据库存储在您的git中或在代码之外处理。 但是,您仍然需要维护很多setUp()代码。

    cf that answer

      

    该策略将是最常用的建议策略。

    1. 模拟数据库访问
    2. 另一种方式是,它经常用于模拟HTTP连接,它可以序列化输出,以及SA和数据库之间通信的输入。我不知道图书馆这样做,但这将是一件很棒的事情。

      基本上,想象一下JSON文件,其中包含发送到数据库的所有请求以及从数据库返回的数据。每次参加测试时,您都只是重播该JSON记录。

      进行更改时,您可以记录I / O交互并对其进行序列化。有点像betamax库。

        

      这种策略是我最喜欢的实现方式,但有人必须为这样的工具编写实现!

      1. mock / monkey补丁sqlalchemy的个别元素
      2. 这将是痛苦和很多工作,仍然有很多人尝试这种方法。但是我想不出有这么好的理由,因为你的目标不是测试sqlalchemy,而是你自己的代码,你最终会嘲笑SQLAlchemy的大部分内容。

        1. 抽象代码中的所有数据库交互
        2. 如果所有数据库交互都是由您自己的代码中的接口抽象出来的,那么您只需用该模型替换该接口的实现,并声明您获得了正确的参数。优点是它易于测试和维护。虽然,我不建议这样做,因为那样你就不会检查你是否正确使用了SQLAlchemy库。