django.test.client 在现有 url 上收到 404 错误

ant*_*869 5 python django unit-testing django-unittest

我刚刚开始学习单元测试并遇到了这个问题。

\n\n

我得到这样的项目结构(现在是 it\xe2\x80\x99s Django 1.6.2):

\n\n
./manage.py\n./myproject\n./myproject/urls.py\n./myproject/myapp/\n./myproject/myapp/urls.py\n./myproject/myapp/views.py\n./tests/\n./test/test_example.py\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 ./myproject/urls.py 我有:

\n\n
from django.conf.urls import patterns, include, url\nurlpatterns = patterns('',\n    url(r'^myapp/', include('myproject.myapp.urls')),\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 ./myproject/myapp/urls.py 我有:

\n\n
from django.conf.urls import patterns, url\n\nurlpatterns = patterns('myproject.myapp.views',\n    url(r'^example1/$', 'itemlist'),  \n    url(r'^example1/(?P<item_id>\\w+)/$', 'item'),\n)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我编写了基本测试并将其放入./test/test_example.py

\n\n
import unittest\nfrom django.test import Client\n\nclass PagesTestCase(unittest.TestCase): \n    def setUp(self):\n        self.client = Client()\n\n    def test_itemlist(self):        \n        response = self.client.get('/myapp/example1/')\n        self.assertEqual(response.status_code, 200)\n\n    def test_item(self):        \n        response = self.client.get('/myapp/example1/100100/')\n        self.assertEqual(response.status_code, 200)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我从 shell 运行这个测试,如下所示:

\n\n
cd ./tests\npython manage.py test\n
Run Code Online (Sandbox Code Playgroud)\n\n

第一个测试运行正常,但第二个测试总是失败,并显示 \xe2\x80\x98404 not found\xe2\x80\x99 状态代码。

\n\n

两个 url 在浏览器中都工作正常。

\n\n

另外,我尝试了这个:

\n\n
cd ./\npython manage.py shell\n>>> from django.test.client import Client\n>>> c = Client()\n>>> r = c.get('/myapp/example1/100100/')\n>>> r.status_code\n200\n
Run Code Online (Sandbox Code Playgroud)\n\n

我只能\xe2\x80\x99t 弄清楚如何正确运行这些测试。似乎没有任何模式作为参数传递到视图中对我有用。但是 django.test.client 可以正确找到所有固定的 url。

\n\n

谢谢你!

\n\n

编辑:我刚刚发现 404 在我的 myproject/myapp/views.py 中触发

\n\n

有一段代码:

\n\n
def item(request, item_id):\n    try:\n        item = Item.objects.get(pk = int(item_id))\n    except (ValueError, Item.DoesNotExist):     \n        raise Http404\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里出现了 Item.DoesNotExist 异常。我不知道为什么找不到该项目?

\n

lwa*_*ore 1

使用该reverse()函数来构建 URL,即:

./myproject/myapp/urls.py文件中为每个 URL 模式指定一个名称参数,例如:

from django.conf.urls import patterns, url

urlpatterns = patterns('myproject.myapp.views',
    url(r'^example1/$', 'itemlist', name='example-one'),  
    url(r'^example1/(?P<item_id>\w+)/$', 'item', name='example-two'),
)
Run Code Online (Sandbox Code Playgroud)

我们将使用为参数指定的值name来构建 URL。

然后在./test/test_example.py

from django.core.urlresolvers import reverse

class PagesTestCase(unittest.TestCase): 
    ...
    def test_itemlist(self):
        url = reverse('example-one')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

    def test_item(self):
        url = reverse('example-two')    
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
Run Code Online (Sandbox Code Playgroud)

这应该够了吧。