Запись хороших тестов для приложений 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) 
28
задан Ben James 3 February 2010 в 13:06
поделиться

2 ответа

Используйте утилиту dos2unix или unix2dos для преобразования окончаний строк в требуемый формат. Существуют собственные реализации этих утилит как для unix, так и для Windows-систем.

-121--4222951-
seen = set()
for x in foo:
    if x in seen:
        continue
    seen.add(x)
    # do something

Для получения дополнительной информации см. документацию set .

Также примеры в нижней части itertools документации модуля содержат генератор unique _ everseen , который можно использовать так:

for x in unique_everseen(foo):
    # do something
-121--4690792-

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

В основном вы

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

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

  • test _ detail _ status _ code и test _ list _ status _ code :
    Хорошо, чтобы проверить, правильно ли настроена маршрутизация или нет. Еще более важно, когда вы предоставляете собственную реализацию get _ absolute _ url () .

  • test _ list _ numer _ of _ items :
    OK, если представление должно вернуть определенное количество предметов. Необязательно, если число не является важным (т.е. произвольным).

  • test _ detail _ template и test _ list _ template :
    Проверьте правильность настройки переменных шаблона.

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

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

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

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

Чтобы подвести итог:
проверьте свой собственный код.

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

18
ответ дан 28 November 2019 в 03:51
поделиться

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

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

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

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

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

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

5
ответ дан 28 November 2019 в 03:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: