Написание хороших тестов для приложений Django

Я никогда не писал никаких тестов в своей жизни, но я хотел бы начать писать тесты для моих проектов 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) 

2 ответов


Я не совершенен в тестировании, но несколько мыслей:

в общем, вы должны проверить каждую функцию, метод, класс, все, что вы написали сами.

это означает, что вам не нужно проверить функции, классы и т. д. что обеспечивает рамочная основа.

тем не менее, быстрая проверка ваших тестовых функций:

  • test_detail_status_code и test_list_status_code:
    Ok, чтобы проверить, настроено ли маршрутизация правильно или нет. Еще более важно, когда вы предоставляете свою собственную реализацию get_absolute_url().

  • test_list_numer_of_items:
    Ok, если определенное количество элементов должно быть возвращено представлением. Не обязательно, если число не важно (т. е. произвольно).

  • test_detail_template и test_list_template:
    Ok, чтобы проверить правильность установки переменных шаблона.

  • все остальные функции: не необходимый.
    В основном вы тестируете здесь, работает ли ORM правильно, работают ли списки так, как ожидалось, и доступны ли свойства объекта (или нет). Пока ты не менять, например save() метод модели и / или предоставьте свою пользовательскую логику, я бы не стал это проверять. Вы должны доверять разработчикам framework, что это работает правильно.

вам нужно только проверить, что у вас есть (окончание)написано.

модель классов может быть особый случай. Вы в основном должны проверить их, как я уже сказал, Если вы предоставляете пользовательскую логику. Но вы также должны проверить их требований. Е. Г. это может быть то, что поле не может быть null (или что это должен быть определенный тип данных, как integer). Поэтому вы должны проверить, что хранение объекта не удается, если у него есть null значение в этом поле.
Это делает не испытайте ОРМ для правильного следования вашей спецификации, но проверьте, что спецификация по-прежнему соответствует вашим требованиям. Возможно, вы измените модель и измените некоторые настройки (случайно или потому, что забыли о требованиях).
Но вам не нужно тестировать, например, такие методы, как save() или вы можете получить доступ к свойству.

конечно, когда вы используете глючный сторонний код... ну все может быть иначе. Но поскольку Django использует сам тестовый фреймворк, чтобы проверить, что все работает, я бы предположил, что это работает.

подведем итоги:
Протестируйте свои требования, Протестируйте свой собственный код.

это только моя точка зрения. Возможно, у других есть предложения получше.


разбейте свои тесты на два совершенно разных вида.

  • модельные тесты. Положите это в свой models.py файл с вашей моделью. Эти тесты будут выполнять методы в классах моделей. Вы можете сделать простой CRUD (создать, получить, обновить, удалить), чтобы просто доказать, что ваша модель работает. Не проверяйте каждый атрибут. Сделать тестовое поле по умолчанию и save() правила, Если вам интересно.

    для вашего примера, создать TestNews класс, который создает, получает, обновляет и удаляет News товар. Обязательно проверьте результаты по умолчанию. Этот урок должен быть коротким и по существу. Вы можете, если ваше приложение требует этого, протестировать различные виды обработки фильтров. Ваш модульный тестовый код может (и должен) предоставить примеры "правильного" способа фильтрации News.

  • UI тесты. Положите их в отдельный . Эти тесты будут проверять функции и шаблоны представления.

    • имя TestCase с "условием", которое вы создаете. "TestNotLoggedIn". "TestLoggedIn". "TestNoValidThis". "TestNotAllowedToDoThat". Ваш setUp будет делать логин и любые другие шаги, необходимые для установления необходимого условия.

    • назовите каждый метод теста с действием и результатом. "test_get_noquery_should_list", "test_post_should_validate_with_errors", "test_get_query_should_detail".