为什么只有运行完整的测试套件时django测试才会失败? [英] why would a django test fail only when the full test suite is run?

查看:71
本文介绍了为什么只有运行完整的测试套件时django测试才会失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Django 1.5中进行了测试,并通过了以下条件:

I have a test in Django 1.5 that passes in these conditions:


  • 当单独运行时

  • 当完整的 TestCase 运行时

  • 当我所有应用程序的测试运行时

  • when run by itself in isolation
  • when the full TestCase is run
  • when all of my app's tests are run

但是当使用 python manage.py test 运行完整的测试套件时,它会失败。为什么会发生这种情况?

But it fails when the full test suite is run with python manage.py test. Why might this be happening?

异常测试使用 django.test.Client 将一些数据发布到端点,然后测试检查对象是否已成功更新。其他应用可以修改测试客户端还是数据本身?

The aberrant test uses django.test.Client to POST some data to an endpoint, and then the test checks that an object was successfully updated. Could some other app be modifying the test client or the data itself?

我尝试了一些打印调试,发现所有数据都按预期发送和接收。特定的失败是一个不存在的异常,当我尝试从数据库中获取要更新的对象时会引发该异常。奇怪的是,在异常处理程序本身中,我可以查询该类型的所有对象,并发现目标对象实际上确实存在。

I have tried some print debugging and I see all of the data being sent and received as expected. The specific failure is a does-not-exist exception that is raised when I try to fetch the to-be-updated object from the db. Strangely, in the exception handler itself, I can query for all objects of that type and see that the target object does in fact exist.

编辑:

当我发现我是由 id User 查询目标对象时,我的问题已解决。 code>而不是 id UserProfile ,但是这仍然让我感到困惑,在某些情况下这会起作用

My issue was resolved when I found that I was querying for the target object by id and User and not id and UserProfile, but it's still confusing to me that this would work in some cases but fail in others.

我还发现,使用 python manage.py test auth< myapp>

推荐答案

听起来您的问题不涉及模拟,但我整天都在调试具有类似症状的问题,您的问题是我在寻找解决方案时提出的第一个问题,因此我想在这里分享我的解决方案,以防万一它对其他人有帮助。就我而言,问题如下。

It sounds like your problem does not involve mocks, but I just spent all day debugging an issue with similar symptoms, and your question is the first one that came up when I was searching for a solution, so I wanted to share my solution here, just in case it will prove helpful for others. In my case, the issue was as follows.

我有一个单独通过的测试,但是作为完整测试套件的一部分运行时却失败了。在我的一个视图函数中,我正在使用Django send_mail()函数。在测试中,我没有 patch ed send_mail ,而是每次运行测试时都不会给我发送电子邮件。我的测试方法:

I had a single test that would pass in isolation, but fail when run as part of my full test suite. In one of my view functions I was using the Django send_mail() function. In my test, rather than having it send me an email every time I ran my tests, I patched send_mail in my test method:

from mock import patch
...

def test_stuff(self):
    ...

    with patch('django.core.mail.send_mail') as mocked_send_mail:

    ...

这样,在调用视图函数之后,我可以测试 send_mail 被调用为:

That way, after my view function is called, I can test that send_mail was called with:

self.assertTrue(mocked_send_mail.called)

当单独运行测试时,此方法运行良好,但与套件中的其他测试一起运行时,则失败。失败的原因是,当它作为套件的一部分运行时,会事先调用其他视图,从而导致加载 views.py 文件,从而导致之前导入send_mail 我有机会对其进行补丁补丁。因此,在我看来调用 send_mail 时,调用的是真正的 send_mail ,而不是我的修补版本。当我单独运行测试时,该函数在导入之前被模拟,因此在加载 views.py 后,修补版本最终被导入。 。 模拟文档中对此情况进行了说明,我以前读过几次,但是在学习了艰辛的方法后,现在已经很了解了……

This worked fine when running the test on its own, but failed when run with other tests in the suite. The reason this fails is that when it runs as part of the suite other views are called beforehand, causing the views.py file to be loaded, causing send_mail to be imported before I get the chance to patch it. So when send_mail gets called in my view, it is the actual send_mail that gets called, not my patched version. When I run the test alone, the function gets mocked before it is imported, so the patched version ends up getting imported when views.py is loaded. This situation is described in the mock documentation, which I had read a few times before, but now understand quite well after learning the hard way...

解决方案很简单:无需修补 django.core.mail.send_mail 我刚刚修补了在 views.py -中已经导入的版本。 myapp.views.send_mail 。换句话说:

The solution was simple: instead of patching django.core.mail.send_mail I just patched the version that had already been imported in my views.py - myapp.views.send_mail. In other words:

with patch('myapp.views.send_mail') as mocked_send_mail:
...

这篇关于为什么只有运行完整的测试套件时django测试才会失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆