13

我有一个单元测试在一个断言中失败,该断言在同一测试用例类中的另一个测试中通过。

这是通过的测试:

def test_home(self):
    c = Client()
    resp = c.get('/')
    self.assertEqual(resp.status_code, 200)
    self.assertTrue('a_formset' in resp.context)

这是失败的测试:

def test_number_initial_number_of_forms(self):
    c = Client()
    resp = c.get('/')
    self.assertEqual(resp.context['a_formset'].total_form_count(), 1)

在第二个测试中,我得到了错误TypeError: 'NoneType' object has no attribute '__getitem__'

如果我执行第二个测试

def test_number_initial_number_of_forms(self):
    c = Client()
    resp = c.get('/')
    self.assertTrue('a_formset' in resp.context)
    self.assertEqual(resp.context['a_formset'].total_form_count(), 1)

我得到错误TypeError: argument of type 'NoneType' is not iterable。我已经在第二个测试中通过打印语句确认 response.content 包含我希望获得的页面,状态代码是正确的,并且模板是正确的。但是响应的上下文始终None在第二个测试中。

我正在通过标准的“python manage.py test ...”接口运行我的 Django 单元测试,所以我不相信我遇到了“ context is empty from the shell ”的问题。

这是怎么回事?

编辑:

如果我添加print type(resp.context['a_formset'])到每个测试中,对于我得到的工作测试<class 'django.forms.formsets.AFormFormSet'>。对于非工作测试,我TypeError: 'NoneType' object has no attribute '__getitem__'再次获得。

4

3 回答 3

8

这是因为您遇到了一些错误,退出了 shell 并重新启动它。

但是你忘了启动环境......

from django.test.utils import setup_test_environment
>>> setup_test_environment()

那是我的问题。希望它有效...

于 2014-01-30T10:47:58.797 回答
5

今天我遇到了同样的问题。第二测试得到相同的页面在 response.context 中没有任何内容

我做了一个研究,发现1)测试客户端使用信号来填充上下文,2)我的视图方法没有被调用来进行第二次测试

我打开了一个调试器,发现有罪的是“缓存中间件”。知道我找到了这张票和这个SO 问题(后者有一个解决方案)。

因此,简而言之:第二个请求是从缓存中提供的,而不是从视图中提供的,因此视图没有被执行,并且测试客户端没有得到信号并且没有能力填充上下文。

我不能为我的项目禁用缓存中间件,所以我在我的设置中添加了下一个黑客行:

if 'test' in sys.argv:
   CACHE_MIDDLEWARE_SECONDS = 0

希望这可以帮助某人

于 2013-06-19T11:06:20.997 回答
0

您还可以通过在测试方法中调用 cache.clear() 手动清除缓存:

from django.core.cache import cache
import pytest


class TestPostView:

    @pytest.mark.django_db(transaction=True)
    def test_index_post(self, client, post):
        cache.clear()
        response = client.get('/')
于 2021-08-20T20:39:53.167 回答