Автор выбрал фонд Open Internet/Free Speech для получения пожертвования в рамках программы Write for DOnations.
Практически невозможно создавать веб-сайты, которые будут идеально работать сразу без каких-либо ошибок. По этой причине вы должны тестировать ваше веб-приложение, чтобы находить эти ошибки и упреждающе работать с ними. Чтобы повысить эффективность тестирования, очень часто используется разбивка тестов на модули, которые проверяют конкретный функционал веб-приложения. Эта практика называется юнит-тестированием. Это упрощает обнаружение ошибок, поскольку тесты фокусируются на небольших частях (юнитах) вашего проекта, никак не затрагивая другие его части.
Тестирование веб-сайта может стать сложной задачей, поскольку он включает несколько слоев логики, например обработку HTTP-запросов, валидацию форм и отрисовку шаблонов. Однако Django предоставляет набор инструментов, которые избавляют от множества проблем при тестировании веб-приложений. В Django предпочтительным способом написания тестов является использование модуля unittest
Python, хотя вы можете использовать другие фреймворки для тестирования.
В этом руководстве вы выполните настройку набора тестов для вашего проекта Django и напишете юнит-тесты для моделей и представлений в вашем приложении. Вы научитесь запускать эти тесты, анализировать их результаты и искать причины падения тестов.
Прежде чем начать выполнение этого руководства, вам потребуется следующее:
Набор тестов в Django — это все тест-кейсы для всех приложений в вашем проекте. Чтобы утилита тестирования Django могла обнаружить все имеющиеся тест-кейсы, вы должны записать тест-кейсы в скрипт, название которого начинается с test
. На этом шаге вы должны будете создать структуру каталогов и файлов для вашего набора тестов и создать внутри пустой тест-кейс.
Если вы ознакомились с серией обучающих материалов по разработке Django, у вас в распоряжении должно быть приложение Django с именем blogsite
.
Давайте создадим папку для хранения всех наших скриптов тестов. Вначале необходимо активировать виртуальную среду:
- cd ~/my_blog_app
- . env/bin/activate
Затем перейдите в каталог приложения blogsite
, в папку, которая содержит файлы models.py
и views.py
, а затем создайте новую папку с именем tests
:
- cd ~/my_blog_app/blog/blogsite
- mkdir tests
Далее необходимо превратить эту папку в пакет Python, добавив файл __init__.py
:
- cd ~/my_blog_app/blog/blogsite/tests
- touch __init__.py
Теперь вы должны добавить файл для тестирования ваших моделей и другой файл для тестирования представлений:
- touch test_models.py
- touch test_views.py
В заключение вы создадите пустой тест-кейс в файле test_models.py
: Вам нужно будет импортировать класс TestCase
Django и сделать его родительским классом для вашего класса тест-кейса. В дальнейшем вы сможете добавить в этот тест-кейс методы для тестирования логики в ваших моделях. Откройте файл test_models.py
:
- nano test_models.py
Теперь добавьте в файл следующий код:
from django.test import TestCase
class ModelsTestCase(TestCase):
pass
Вы успешно добавили набор тестов в приложение blogsite
. Далее вам необходимо заполнить данные для пустого тест-кейса модели, которую вы создали.
На этом шаге вы протестируете логику кода в файле models.py
. В частности, вы должны будете протестировать метод save
модели Post
, чтобы убедиться, что при вызове он создает корректный слаг для тайтла поста.
Давайте начнем с изучения кода, который уже находится в файле models.py
для метода save
модели Post
:
- cd ~/my_blog_app/blog/blogsite
- nano models.py
Вы увидите следующее:
class Post(models.Model):
...
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
...
Мы можем убедиться, что он проверяет, есть ли у поста, который будет сохранен, значение слага, и если нет, вызывает slugify
для создания слага. Это тип логики, который вы можете захотеть протестировать, чтобы убедиться, что слаги действительно были созданы при сохранении поста.
Закройте файл.
Чтобы протестировать это, вернитесь к файлу test_models.py
:
- nano test_models.py
Затем обновите его содержимое, добавив код в выделенные части:
from django.test import TestCase
from django.template.defaultfilters import slugify
from blogsite.models import Post
class ModelsTestCase(TestCase):
def test_post_has_slug(self):
"""Posts are given slugs correctly when saving"""
post = Post.objects.create(title="My first post")
post.author = "John Doe"
post.save()
self.assertEqual(post.slug, slugify(post.title))
Этот новый метод test_post_has_slug
создает новый пост с именем "My first post"
, а затем указывает для поста автора и сохраняет пост. После этого, используя метод assertEqual
из модуля unittest
Python, он проверяет корректность слага для поста. Метод assertEqual
проверяет, равны ли два переданных ему аргумента, что определяется оператором "=="
, и генерирует ошибку в противном случае.
Сохраните и закройте test_models.py
.
Это пример того, что можно протестировать. Чем больше логики вы будете добавлять в ваш проект, тем больше тестов вам потребуется. Если вы добавите в метод save
дополнительную логику или создадите новые методы для модели Post
, вам нужно будет добавить сюда дополнительные тесты. Вы можете добавить их в метод test_post_has_slug
или создать новые методы тестирования, но их имена должны начинаться с test
.
Вы успешно создали тест-кейс для модели Post
, где вы проверяли, что слаги создаются корректно после сохранения. На следующем шаге вы должны будете написать тест-кейс для тестирования представлений.
На этом шаге вы напишете тест-кейс, который тестирует представление с помощью тестового клиента Django. Тестовый клиент — это класс Python, который действует как шаблонный браузер, позволяя вам тестировать ваши представления и взаимодействовать с приложением Django таким же образом, как это делал бы пользователь. Вы можете получить доступ к тестовому клиенту, сославшись на self.client
в ваших тестовых методах. Давайте, например, создадим тест-кейс в test_views.py
. Откройте файл test_views.py
:
- nano test_views.py
Затем добавьте следующее:
from django.test import TestCase
class ViewsTestCase(TestCase):
def test_index_loads_properly(self):
"""The index page loads properly"""
response = self.client.get('your_server_ip:8000')
self.assertEqual(response.status_code, 200)
ViewsTestCase
содержит метод test_index_loads_properly
, который использует тестовый клиент Django для посещения стартовой страницы веб-сайта (http://your_server_ip:8000
, где your_server_ip
— это IP-адрес сервера, который вы используете). Затем тестовый метод проверяет, содержит ли ответ код состояния 200
, который означает, что страница отправляет ответ без ошибок. В результате вы можете быть уверены, что при посещении страницы пользователем она также не будет генерировать ошибки.
Помимо кода состояния вы можете узнать о других свойствах ответа тестового клиента, которые вы можете протестировать, на странице тестирования ответов документации Django.
На этом шаге вы создали тест-кейс для тестирования того, что визуализация представления стартовой страницы выполняется без ошибок. Теперь ваш набор тестов содержит два тест-кейса. На следующем шаге вы запустите их для просмотра результатов.
Теперь, когда вы завершили сборку набора тестов для проекта, пришло время запустить эти тесты и посмотреть их результаты. Чтобы запустить тесты, перейдите в папку blog
(содержащую файл manage.py
приложения):
- cd ~/my_blog_app/blog
Запустите их с помощью следующей команды:
- python manage.py test
Вы увидите примерно следующий вывод в вашем терминале:
OutputCreating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.007s
OK
Destroying test database for alias 'default'...
Этот вывод содержит две точки ..
, каждая из которых отображает выполненный тест-кейс. Теперь вы можете изменить test_views.py
, чтобы вызвать падение теста. Сначала откройте файл с помощью следующей команды:
- nano test_views.py
Затем измените выделенный код на следующий:
from django.test import TestCase
class ViewsTestCase(TestCase):
def test_index_loads_properly(self):
"""The index page loads properly"""
response = self.client.get('your_server_ip:8000')
self.assertEqual(response.status_code, 404)
Здесь вы изменили код состояния с 200
на 404
. Теперь снова запустите тест из каталога с файлом manage.py
:
- python manage.py test
Вывод должен выглядеть так:
OutputCreating test database for alias 'default'...
System check identified no issues (0 silenced).
.F
======================================================================
FAIL: test_index_loads_properly (blogsite.tests.test_views.ViewsTestCase)
The index page loads properly
----------------------------------------------------------------------
Traceback (most recent call last):
File "~/my_blog_app/blog/blogsite/tests/test_views.py", line 8, in test_index_loads_properly
self.assertEqual(response.status_code, 404)
AssertionError: 200 != 404
----------------------------------------------------------------------
Ran 2 tests in 0.007s
FAILED (failures=1)
Destroying test database for alias 'default'...
Вы увидите сообщение, содержащее описание ошибки, указывающее скрипт, тест-кейс и метод, который не был выполнен. Также оно сообщает причину ошибки, в данном случае код состояния не равен 404
, в форме сообщения AssertionError: 200 ! = 404
. AssertionError
здесь возникает в выделенной строке кода в файле test_views.py
:
from django.test import TestCase
class ViewsTestCase(TestCase):
def test_index_loads_properly(self):
"""The index page loads properly"""
response = self.client.get('your_server_ip:8000')
self.assertEqual(response.status_code, 404)
Она указывает, что утверждение является ложным, т. е. код состояния ответа (200
) не соответсвует ожидаемому результату (404
). Теперь вы можете видеть, что две точки ..
, идущие перед сообщением об ошибке, теперь превратились в . F
, что говорит о том, что первый тест-кейс был пройден успешно, а второй — нет.
В этом руководстве вы создали набор тестов в вашем проекте Django, добавили тест-кейсы для тестирования логики модели и представления,узнали, как запускать тесты, и проанализировали вывод теста. В качестве следующего шага вы можете создать новые тестовые скрипты для кода Python в других файлах помимо models.py
и views.py
.
Ниже представлено несколько статей, которые могут оказаться полезными при создании и тестировании сайтов с помощью Django:
Также вы можете найти на нашей странице материалов по теме Django другие руководства и проекты.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.