【问题标题】:How to have Django test case and Selenium server use same database?如何让 Django 测试用例和 Selenium 服务器使用相同的数据库?
【发布时间】:2012-08-20 16:16:22
【问题描述】:

我有一个 Django(v1.4,使用 Postgresql)项目,为此我编写了一堆工作单元测试。这些使用FactoryBoy 来生成大部分数据。

我现在开始使用 LiveServerTestCase 和 Selenium 编写一些集成测试。我刚刚意识到我的测试和实时测试服务器使用不同的数据库。这意味着我的测试中工厂创建的数据对 Selenium 不可用。

我不确定最好的进步方式。我认为我可以使用固定装置来提供可以工作的数据,尽管使用工厂来代替这很痛苦。

有没有一种方法可以让我继续使用工厂来生成适用于我的 Selenium 测试的数据?我真的希望我的测试和 LiveServerTestCase 使用相同的数据库。

【问题讨论】:

    标签: django selenium integration-testing


    【解决方案1】:

    我发现了为什么会发生这种情况,以及一些可能的解决方法,包括上面 Ilya Baryshev 的回答。

    如果您的测试源自 Django 的 TestCase,并且如果您的数据库支持事务,那么每个测试都在其自己的事务中运行,并且外部任何人(没有其他线程、外部进程或其他测试)都无法看到在其中创建的对象由您测试的数据库。

    LiveServerTestCase 使用线程,所以它会遇到这个问题。所以设计者让它继承自 TransactionTestCase 而不是 TestCase,这会禁用这些事务,以便全局可见。

    发生在我身上的是,我在我的测试类中添加了一些 mixin,其中一个引入了 TestCase。这不会导致错误,但它会默默地将LiveServerTestCase 的基类替换为TestCase,从而再次启用事务,从而导致您描述的问题。

    Ilya 的 SQLite 内存数据库解决方法有效,因为 Django 包含检测何时使用 SQLite :memory: 数据库的代码,该数据库实际上在线程之间共享相同的连接,因此您可以在 LiveServerThread 中看到您的测试对象,因为它们在里面 相同的交易。然而,这有一些警告:

    防止两个线程通过此共享连接同时查询数据库很重要,因为这有时可能会随机导致测试失败。因此您需要确保两个线程不会访问同时数据库。特别是,这意味着在某些情况下(例如,在单击链接或提交表单之后),您可能需要检查 Selenium 是否接收到响应以及是否已加载下一页,然后再继续执行进一步的测试。例如,通过让 Selenium 等到在响应中找到 HTML 标记来执行此操作(需要 Selenium > 2.13)...

    https://docs.djangoproject.com/en/1.4/topics/testing/#live-test-server

    在我的例子中,一旦我们在测试开始时识别出 autocommit 被关闭,并找出原因(因为我们输入了我们不应该做的 TestCase 代码),我们就能够修复继承层次结构以避免拉入TestCase,然后从实时服务器线程和测试中都可以看到同一个数据库。

    这也适用于 Postgres 数据库,因此它将为 velotron 提供解决方案。

    【讨论】:

    • 多么痛苦。令人烦恼的是问题(TestCase 的使用)如此无形地发生。感谢您回到这里。
    • 抱歉恢复了这个,但是,我是否正确地读到TransactionTestCase禁用事务的基类?好像是反过来?
    • 就是这样。 TransactionTestCase 用于使用事务的测试,因此不能在内部事务运行,因为您不能在 SQL 中嵌套事务,因此它会禁用自己的事务。
    【解决方案2】:

    您是否尝试过使用 sqlite 作为数据库后端进行测试?

    当使用内存 SQLite 数据库运行测试时,同样 数据库连接将由两个并行线程共享: 运行实时服务器的线程和运行服务器的线程 运行测试用例。

    来自Django docs

    如果您没有使用常规 ORM 之外的任何东西,您也可以从测试加速中受益。

    【讨论】:

    • 哦,好主意 - 下次我会尝试做这些测试,然后会报告!
    • 我的应用程序需要 Postgres,我希望我可以使用 SQLite 解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 2013-10-18
    • 2015-02-24
    相关资源
    最近更新 更多