Django 5 для начинающих

Прогресс по курсу:  9/1004

2.8 Введение в тестирование приложений
2 из 2 шагов пройдено

Что еще мы можем проверить? Как насчет имени URL для каждой страницы?

Добавим в blog/urls.py имя home для пути к главной странице и about для страницы about.

from django.urls import path
from blog import views

urlpatterns = [
    path("", views.index, name="home"),
    path("about/", views.about, name="about"),
]

 

Мы можем использовать очень удобную утилитарную функцию Django reverse для проверки обоих вариантов.

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

blog/tests.py:

from django.test import SimpleTestCase
from django.urls import reverse  # new


class HomepageTests(SimpleTestCase):

    def test_url_exists_at_correct_location(self):
        response = self.client.get("/")
        self.assertEqual(response.status_code, 200)

    def test_url_available_by_name(self):  # new
        response = self.client.get(reverse("home"))
        self.assertEqual(response.status_code, 200)


class AboutpageTests(SimpleTestCase):

    def test_url_exists_at_correct_location(self):
        response = self.client.get("/about/")
        self.assertEqual(response.status_code, 200)

    def test_url_available_by_name(self):  # new
        response = self.client.get(reverse("about"))
        self.assertEqual(response.status_code, 200)


Запустите тесты снова, и убедимся что они работают правильно:


До сих пор мы проверяли расположение URL и имена URL, но не проверяли наши шаблоны.

Давайте убедимся, что правильные шаблоны - index.html и about.html используются на каждой странице и что они отображают ожидаемое содержимое Index и О нас соответственно.

Для этого мы можем использовать assertTemplateUsed и assertContains.

blog/tests.py:

from django.test import SimpleTestCase
from django.urls import reverse


class HomepageTests(SimpleTestCase):

    def test_url_exists_at_correct_location(self):
        response = self.client.get("/")
        self.assertEqual(response.status_code, 200)

    def test_url_available_by_name(self):
        response = self.client.get(reverse("home"))
        self.assertEqual(response.status_code, 200)

    def test_template_name_correct(self):  # new
        response = self.client.get(reverse("home"))
        self.assertTemplateUsed(response, "blog/index.html")

    def test_template_content(self):  # new
        response = self.client.get(reverse("home"))
        self.assertContains(response, "Index")


class AboutpageTests(SimpleTestCase):

    def test_url_exists_at_correct_location(self):
        response = self.client.get("/about/")
        self.assertEqual(response.status_code, 200)

    def test_url_available_by_name(self):
        response = self.client.get(reverse("about"))
        self.assertEqual(response.status_code, 200)

    def test_template_name_correct(self):  # new
        response = self.client.get(reverse("about"))
        self.assertTemplateUsed(response, "blog/about.html")

    def test_template_content(self):  # new
        response = self.client.get(reverse("about"))
        self.assertContains(response, "О нас")


Запустите тесты в последний раз, чтобы проверить нашу новую работу. Все тесты должны пройти:


Опытные программисты могут посмотреть на наш код тестирования и заметить, что в нем много повторений:

Например, мы устанавливаем ответ каждый раз для всех восьми тестов. В целом, это хорошая идея - придерживаться концепции DRY(Don't Repeat Yourself) программирования, но модульные тесты работают лучше всего, когда они самодостаточны и чрезвычайно многословны.

По мере расширения тестов по соображениям производительности может оказаться более целесообразным объединить несколько утверждений в меньшее количество тестов, но это уже более сложная и часто субъективная тема, выходящая за рамки данного курса. Мы лишь рассматриваем основные тесты.

В будущем вы еще много раз затронете тестирование, особенно когда начнете работать с базами данных. Пока же нужно понять, насколько просто и важно добавлять тесты каждый раз, когда мы добавляем новую функциональность в наш проект Django.

Если у вас возникли трудности, вы можете клонировать проект с гитхаба - https://github.com/Permin0ff/Cource_FirstProject_2


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Понятно, что тут вводный урок и тема осознанно дана поверхностно для ознакомления, но хотелось бы видеть чуть больше по тому что уже успели показать, а именно:

1. Более подробное описание функции reverse, о ней ничего не сказано, пока не понятно, зачем она тут нужна.
2. Более подробное описание используемых методов и атрибутов:
    - self.client - что за атрибут.
    - client.get - какие параметры принимает метод и что делает, хотя бы в двух словах.
    - assertEqual (и все ему подобные, показанные в уроке) - какие параметры принимает метод и что делает, хотя бы в двух словах.
3. В предыдущем уроке вроде в комментариях писали, что наименование методов в классах тестирования обязательно должно начинаться с префикса 'test_', если это так, то тоже наверное стоит указать.

Просто пока в данном блоке все сводится к банальному перепечатыванию, в отличии от предыдущих ...

И закономерный вырос - вроде по содержанию посмотрел, но возможно это будет в "Продвинутый Django 5 для продолжающих" (в сами темы нырять раньше времени не стал, чтобы не спойлерить себе)?)

По get() небольшая ремарка, он ранее был в курсе, но использовался для извлечения ключей из словаря, тут аналогичный функицонал?)

@Нарбеков_Марсель,

1. Функция reverse используется для получения url-адреса по имени маршрута, будет рассматриваться дальше в лекции.

2. client это класс тестового клиента, типа простого браузера, специально для тестирования.

get это его метод создания GET-запроса по определённому адресу(параметр path),  в параметре data можно передать словарь с параметрами GET-запроса. Метод возвращает ответ в виде объекта Response.

assertEqual метод проверки на равенство, эквивалентен assert val1 == val2.

3. Тестирование будет рассматриваться подробнее в 2м курсе.

@Дмитрий_Селезнев, Понял, спасибо!

Добрый день! Подскажите, пожалуйста, а как можно использовать pytest или pytest-django вместо unittest?

@Иван_Кедров, сначала необходимо установить их, для этого выполняем:

pip install pytest-django

После этой команды будет установлены pytest и pytest-django.

Затем в корне проекта создадим файл с именем pytest.ini, с содержимым:

[pytest]
DJANGO_SETTINGS_MODULE = Cource_FirstProject.settings
python_files = tests.py test_*.py


Тесты будут запускаться командой в терминале pytest, unittest-тесты при этом тоже будут выполнятся.


Основное отличие от unittest'а в том что не нужно создавать классы, и для проверки, вместо методов assertEqual и подобных, используется стандартный оператор assert:

@Дмитрий_Селезнев, Спасибо!