与其他测试用例一起运行时,Django单元测试失败

时间:2013-12-09 22:03:53

标签: django unit-testing

我与Django单元测试的行为不一致。在我使用sqlite的开发机器上,如果我分别在我的两个应用程序上运行测试,则测试通过,但如果我运行manage.py test一次测试所有内容,我会在两次测试中始终获得单元测试失败。

在我使用Postgres的登台服务器上,我有一个特定的测试在单独测试时有效(例如manage.py test MyApp.tests.MyTestCase.testSomething),但在运行整个测试用例时失败(例如manage.py test MyApp.tests.TestCase)。

其他相关的StackOverflow问题似乎有两个解决方案:

  1. 使用Django TestCase而不是Python等价
  2. 使用TransactionTestCase确保在每次测试后正确清理数据库。
  3. 我试过两个都无济于事。出于挫折感,我也尝试使用django-nose,但我看到了同样的错误。我在Django 1.6上。

3 个答案:

答案 0 :(得分:1)

除了在所有测试中使用TestCase之外,还需要确保删除在设置方法中完成的任何修补:

def setUp(self):
    self.patcher = patch('my.app.module')

def tearDown(self):
    self.patcher.stop()

答案 1 :(得分:1)

我只花了一整天调试类似的问题。就我而言,问题如下。

在我的一个视图函数中,我使用的是Django git rebase origin/Master函数。在我的测试中,我没有在每次运行测试时向我发送电子邮件,而是在我的测试方法中send_mail()编辑patch

send_mail

这样,在调用我的视图函数后,我可以测试from mock import patch ... def test_stuff(self): ... with patch('django.core.mail.send_mail') as mocked_send_mail: ... 被调用:

send_mail

这在单独运行测试时工作正常,但在套件中运行其他测试时失败。失败的原因是,当它作为套件的一部分运行时,其他视图会事先被调用,从而导致self.assertTrue(mocked_send_mail.called) 文件被加载,导致views.py在之前导入有机会send_mail它。因此,在我的视图中调用patch时,实际的send_mail会被调用,而不是我的修补版本。当我单独运行测试时,该函数在导入之前被模拟,因此修补后的版本最终会在加载send_mail时导入。这种情况在mock documentation中有所描述,我之前已经阅读了几次,但是在学习了很多方法之后现在明白了......

解决方案很简单:我只是修补了views.py - django.core.mail.send_mail中已导入的版本,而不是修补views.py。换句话说:

myapp.views.send_mail

我花了很长时间调试,所以我想我会分享我的解决方案。我希望它对你也有用。您可能没有使用模拟,在这种情况下,这可能对您没有帮助,但我希望它能帮到某些人。

答案 2 :(得分:1)

今天,通过一系列测试,我发生了同样的事情。我进行了23次常规django.test.TestCase测试,然后进行了一次django.contrib.staticfiles.testing.StaticLiveServerTestCase测试。最终的测试在与其他测试一起运行时总是会失败,但会自行通过。

解决方案

在23个常规TestCase测试中,我确实实现了常规TestCase的子类,以便为测试提供针对我的应用程序的一些通用功能。在tearDown方法中,我无法调用super方法。一旦我在tearDown方法中调用了super方法,它就起作用了。因此,这里的课程是检查以确保您正在清理方法。