我刚开始学习单元测试并坚持这个问题。
我得到了这样的项目结构(现在是Django 1.6.2):
./manage.py
./myproject
./myproject/urls.py
./myproject/myapp/
./myproject/myapp/urls.py
./myproject/myapp/views.py
./tests/
./test/test_example.py
在./myproject/urls.py中我有:
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^myapp/', include('myproject.myapp.urls')),
)
在./myproject/myapp/urls.py中我有:
from django.conf.urls import patterns, url
urlpatterns = patterns('myproject.myapp.views',
url(r'^example1/$', 'itemlist'),
url(r'^example1/(?P<item_id>\w+)/$', 'item'),
)
我写了基本测试并将其放入./test/test_example.py
import unittest
from django.test import Client
class PagesTestCase(unittest.TestCase):
def setUp(self):
self.client = Client()
def test_itemlist(self):
response = self.client.get('/myapp/example1/')
self.assertEqual(response.status_code, 200)
def test_item(self):
response = self.client.get('/myapp/example1/100100/')
self.assertEqual(response.status_code, 200)
我从shell运行这个测试:
cd ./tests
python manage.py test
第一次测试运行正常,但他的第二次测试总是失败并显示'404 not found'状态代码。
两个网址在浏览器中都正常运行。
另外,我试过这个:
cd ./
python manage.py shell
>>> from django.test.client import Client
>>> c = Client()
>>> r = c.get('/myapp/example1/100100/')
>>> r.status_code
200
我无法弄清楚如何正确运行这些测试。似乎没有传递给视图的模式,因为参数对我有用。但所有固定网址都是由django.test.client正确找到的。
谢谢!
编辑:我刚发现我的myproject / myapp / views.py 中有404个火灾有一个代码:
def item(request, item_id):
try:
item = Item.objects.get(pk = int(item_id))
except (ValueError, Item.DoesNotExist):
raise Http404
这里是Item.DoesNotExist异常。我不知道为什么找不到这个项目?
答案 0 :(得分:0)
改用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'),
)
我们将使用为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)
应该可以解决问题。
答案 1 :(得分:0)
除了使用reverse
之外,如果测试数据库中没有所需的模型,您还可以获得404(如注释之一所述)。您还应该使用Django的TestCase
而不是python的unittest
,因为前者从后者继承而来,但是(与其他方式相比)与数据库的交互要容易得多。
设置测试数据的示例:
from django.test import TestCase
from django.urls import reverse
# Or whatever your object is.
from .models import Item
class ItemViewsTestCase(TestCase):
"""Tests for Item views."""
@classmethod
def setUpTestData(cls):
"""Set up test data available for all tests in this class."""
cls.item = Item.objects.create(name='Testing')
def test_item_list_view(self):
# Note, self.client we get for free from Django's TestCase.
response = self.client.get(reverse('itemlist'))
self.assertEqual(response.status_code, 200)
def test_item_detail_view(self):
# This url pattern expects an Item.id so use the item we set up.
url = reverse('item', args=[self.item.id])
response = self.client.get(url)
self.assertEqual(response.status_code, 200)