我从未在生活中写过任何测试,但我想开始为我的Django项目编写测试。我已经阅读了一些关于测试的文章,并决定尝试为一个非常简单的Django应用程序或者开始编写一些测试。
该应用有两个视图(列表视图和详细视图)和一个包含四个字段的模型:
class News(models.Model):
title = models.CharField(max_length=250)
content = models.TextField()
pub_date = models.DateTimeField(default=datetime.datetime.now)
slug = models.SlugField(unique=True)
我想向您展示我的tests.py文件并询问:
有意义吗?
我是否正在测试正确的事情?
是否有我没有遵循的最佳做法,你可以指点我吗?
我的tests.py(它包含11个测试):
# -*- coding: utf-8 -*-
from django.test import TestCase
from django.test.client import Client
from django.core.urlresolvers import reverse
import datetime
from someproject.myapp.models import News
class viewTest(TestCase):
def setUp(self):
self.test_title = u'Test title: bąrekść'
self.test_content = u'This is a content 156'
self.test_slug = u'test-title-bareksc'
self.test_pub_date = datetime.datetime.today()
self.test_item = News.objects.create(
title=self.test_title,
content=self.test_content,
slug=self.test_slug,
pub_date=self.test_pub_date,
)
client = Client()
self.response_detail = client.get(self.test_item.get_absolute_url())
self.response_index = client.get(reverse('the-list-view'))
def test_detail_status_code(self):
"""
HTTP status code for the detail view
"""
self.failUnlessEqual(self.response_detail.status_code, 200)
def test_list_status_code(self):
"""
HTTP status code for the list view
"""
self.failUnlessEqual(self.response_index.status_code, 200)
def test_list_numer_of_items(self):
self.failUnlessEqual(len(self.response_index.context['object_list']), 1)
def test_detail_title(self):
self.failUnlessEqual(self.response_detail.context['object'].title, self.test_title)
def test_list_title(self):
self.failUnlessEqual(self.response_index.context['object_list'][0].title, self.test_title)
def test_detail_content(self):
self.failUnlessEqual(self.response_detail.context['object'].content, self.test_content)
def test_list_content(self):
self.failUnlessEqual(self.response_index.context['object_list'][0].content, self.test_content)
def test_detail_slug(self):
self.failUnlessEqual(self.response_detail.context['object'].slug, self.test_slug)
def test_list_slug(self):
self.failUnlessEqual(self.response_index.context['object_list'][0].slug, self.test_slug)
def test_detail_template(self):
self.assertContains(self.response_detail, self.test_title)
self.assertContains(self.response_detail, self.test_content)
def test_list_template(self):
self.assertContains(self.response_index, self.test_title)
答案 0 :(得分:18)
我在测试方面并不完美,但有些想法:
基本上你应该测试你自己写的每一个函数,方法,类等等。
这意味着您不必测试框架提供的函数,类等。
也就是说,快速检查你的测试功能:
test_detail_status_code
和test_list_status_code
:
确定您是否已正确配置路由。当您提供自己的get_absolute_url()
实施时更为重要。
test_list_numer_of_items
:
好的,如果视图应返回一定数量的项目。如果数字不重要(即任意),则没有必要。
test_detail_template
和test_list_template
:
好的,检查模板变量是否设置正确。
所有其他功能:不需要。
你在这里基本测试的是ORM是否正常工作,列表是否按预期工作以及是否可以访问对象属性。只要你不改变,例如模型的save()
方法和/或提供您的自定义逻辑,我不会测试它。您应该相信框架开发人员可以正常工作。
你只需要测试你所写的内容。
模型类可能是一个特例。如我所说,如果你提供自定义逻辑,你基本上必须测试它们。但是你也应该根据你的要求测试它们。例如。可能是一个字段不允许是null
(或者它必须是某个数据类型,如整数)。因此,如果该对象在此字段中具有null
值,则应测试存储对象是否失败
这样做不测试ORM是否正确遵循您的规范,但测试规范仍然满足您的要求。可能是您更改了模型并更改了某些设置(偶然或因为您忘记了要求)
但你不必测试,例如像save()
这样的方法,或者你可以访问一个属性。
当然,当你使用有缺陷的第三方代码时...好的东西可能会有所不同。但是,由于Django使用测试框架本身来验证一切正常,我认为它正在发挥作用。
总结一下:
根据您的要求进行测试,测试您自己的代码。
这只是我的观点。也许其他人有更好的建议。
答案 1 :(得分:5)
将测试分为两种完全不同的类型。
模型测试。将这些文件放在您的models.py
文件中。这些测试将在您的模型类中执行这些方法。您可以执行简单的CRUD(创建,检索,更新,删除)来简单地证明您的模型有效。不要测试每个属性。如果您感到好奇,请测试字段默认值和save()
规则。
对于您的示例,创建一个TestNews
类,用于创建,获取,更新和删除News
项。请务必测试默认日期结果。这个课程应该简短而重要。如果您的应用需要,您可以测试各种过滤处理。您的单元测试代码可以(并且应该)提供过滤News
的“正确”方法的示例。
UI测试。将它们放在单独的tests.py
文件中。这些测试将测试视图函数和模板。
使用您正在创建的“条件”命名TestCase。 “TestNotLoggedIn”。 “TestLoggedIn”。 “TestNoValidThis”。 “TestNotAllowedToDoThat”。您的setUp
将执行登录以及建立所需条件所需的任何其他步骤。
使用操作和结果命名每个测试方法。 “test_get_noquery_should_list”,“test_post_should_validate_with_errors”,“test_get_query_should_detail”。