为Django应用程序编写好的测试

Lud*_*mer 28 python django unit-testing django-testing

我从来没有在我的生活中写过任何测试,但我想开始为我的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)
Run Code Online (Sandbox Code Playgroud)

我想向您展示我的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) 
Run Code Online (Sandbox Code Playgroud)

Fel*_*ing 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使用测试框架本身来验证一切正常,我认为它正在运行.

总结:
根据您的要求进行测试,测试您自己的代码.

这只是我的观点.也许其他人有更好的建议.


S.L*_*ott 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".