Тестирование в Django (Часть 2) — Модель Mommy против Django.
Тестирование в Django (Часть 2) — Модель Mommy против Django.
В последнихpost я познакомил вас с тестированием в Django, и мы рассмотрели лучшие практики, а также несколько примеров. На этот раз я покажу вам более сложный пример и познакомлю вас сModel Mommy для создания образцов данных.
Почему вы должны заботиться?
В последнем посте я сказал, что «https://github.com/rbarrois/factory_boy[factory_boy],model_mommy иmock используются вместо фикстур или ORM для заполнения необходимые данные для тестирования. И приборы, и ORM могут работать медленно и должны обновляться всякий раз, когда меняется ваша модель ».
Подводя итог, тестовые приспособления Django проблематичны, потому что они:
должны обновляться каждый раз, когда меняется ваша модель / схема,
действительно очень медленно; и
иногда жестко закодированные данные могут привести к сбою ваших тестов в будущем.
Таким образом, используя Model Mommy, вы можете создавать приборы, которые загружаются быстрее и которые легче обслуживать с течением времени.
Тестовые приспособления Django
Давайте начнем с рассмотрения нашего примера тестирования модели в последнем посте:
Здесь мы просто создали объект Whatever() и утверждали, что созданный заголовок соответствует ожидаемому заголовку.
Если вы скачали проект изrepo, запустите сервер и выполните тесты:
Вы увидите, что вышеперечисленные тесты проходят:
Теперь вместо того, чтобы каждый раз создавать новый экземпляр с каждым атрибутом (скучно!), Мы можем использовать Model Mommy для оптимизации процесса.
Топ ошибок в Django-проектах, которые допускают начинающие разработчики
Я собрал в одном месте топ ошибок, которые допускают новички в проектах на Django. Речь о ситуациях, когда новичок в одну харю с нуля делает проект: например, тестовое или пет-проджект.
Я проверял много таких проектов: начиная домашками на моих курсах по веб-разработке и заканчивая недавними тестовыми от выпускников Learn Python.
Не ищите в этом списке неочевидных вещей: тут собраны довольно банальные вещи. Это скорее чеклист и план по дополнительному обучению, а не супер-секретные ниндзя практики.
У меня набралось 11 ошибок, от самых грубых к менее критичным по моей внутренней шкале. Для каждой ошибки я старался рассказать о том, почему это плохо и как это исправить.
Приватные данные в репо
Открываешь settings.py , а там как минимум SECRET_KEY , а то и ещё какой-нибудь пароль к базе данных и токен доступа к Фейсбучному аккаунту лежит плейнтекстом.
Главная проблема тут в том, что как только вы запушили код в публичный репо, все эти данные можно считать скомпрометированными: какой-нибудь бот их уже нашёл, протестировал и положил к себе в базу. Может быть, злоумышленник не сможет получить никакого профита от вот конкретно вашего секретного ключа, но чтобы не думать об этом каждый раз, лучше выработать правило: никаких секретов в репозитории.
Самый простой способ управлять секретными данными — использовать переменные окружения, просто через os.environ . Более продвинутый — настроить управление конфигурациями в проекте. Например, с помощью django-configurations.
В репозитории лишние файлы
Смотришь такой репо, а там в папке media куча тестовых файлов, где-нибудь лежит db.sqlite и до кучи какой-нибудь pycache .
В реальных проектах это зло потому что даже если эти файлы удалить, они останутся в истории гита и репозиторий после пары месяцев такой разработки начинает весить непозволительно много. Ещё это значит, что автор кода не очень хорошо владеет гитом.
Порешать эту проблему стабильно нужно в два этапа: настроить .gitignore и ввести процесс саморевью перед коммитом. С .gitignore всё просто: берёте какой-нибудь готовый шаблон (например, Гитхаб может его сгенерировать), добавляете туда свои специфичные директории, пушите этот файл первым коммитом. С саморевью посложнее, но профитнее. Каждый раз перед тем, как сделать коммит, я подробно смотрю дифф того, что в этот коммит попадает. Это помогает не добавлять в коммит те файлы, которых в нём быть не должно (и спасает от кучи других ошибок).
Нет ридми
Смотришь на репо на Гитхабе и вопросов всё больше: что это за проект, какая функциональность, на каком питоне/ОС запускать, как разворачивать, вообще нифига непонятно.
В реальных проектах это зло, которое приводит к тому, что знания о том, как делать разные вещи с проектом, передаются через Слак или типа того. Если мы говорим про опенсорс, то это неуважение к пользователю: он нашёл наш проект, заинтересовался, открыл его, время потратил, а мы ему фигу вместо приветствия показываем.
Потратьте полчаса на ридми. Найдите хороший шаблон, который вам нравится, и заполните его для своего проекта. Только не забываете поддерживать его актуальным со временем. Например, у меня для некоторых проектов стоит ежемесячная задача: проверить актуальность документации.
Неправильное разбиение по коммитам
Смотришь в историю коммитов, а там один коммит с комментарием “initial commit” и больше ничего нет.
Разбиение по коммитам и комментарии к ним — это очень важный кусок информации о проекте. В реальности с его помощью можно узнать, когда, кто, почему и как внёс изменения, что с ними было до этого, как человек думал и какие проблемы решал. К тому же это полезно самому разработчику. У вас бывало такое, что вы весь вечер что-то кодите и вот везде куча всего и нихрена не работает, хочется всё удалить? Вот при правильном использовании гита такого не бывает: вы двигаетесь маленькими шажками и фиксируете их в vcs. В любой момент можно откатиться, посмотреть как было раньше и не надо в голове держать весь контекст.
Чтобы этого добиться, надо стараться разбивать задачу на совсем маленькие кусочки, типа полчаса-час. Идеально брать большую задачу, расписывать её на такие шажки прям на бумаге и по очереди их выполнять, по коммиту на каждую.
Неправильный нейминг
Тут несколько частых типов ошибок. Во-первых, иногда встречаются названия, которые вообще ничего не значат, например i , j , foo , temp . Во-вторых, иногда названия нарушают PEP8, например, класс XML_VALIDATOR . В-третьих, они иногда не говорят о том, для чего сущность нужна и что она делает, например xml для генератора xml-файла заданного формата.
Для решения есть два шага: технический и организационный. Технический простой — настройте flake8 с нужными вам плагинами (например, flake8-variables-names) и гоняйте его каждый раз перед коммитом (можно настроить прекоммит хук, например, с помощью pre-commit). Организационный сложнее: надо вообще перестать использовать плохие названия переменных. Даже для “просто потестить”, даже если “да я сразу перепишу”. Давайте нормальные имена вещам сразу, это больно только первое время.
Неправильная структура проекта
В корне проекта много файлов с кодом, requirements.txt лежит в какой-то директории, а докерфайл лежит в третьей.
Для расположения разных штук в проекте, как и для многого другого, есть правила. Если я вижу что-то кастомное, мне приходится это запоминать и переучиваться для этого проекта, это неудобно.
Лучшее, что можно сделать для борьбы с этой проблемой — освоить cookiecutter. Это штука, которая разворачивает проект из шаблона, шаблоны можно писать самим. Но и этого делать не нужно, их уже полно. Просто отыщите шаблон, который нужен вам для конкретного проекта. Например, Django+DRF+PostgreSQL+Docker. А потом просто воспользуйтесь им, подпилив для себя (обычно в таких шаблонах всегда есть что-то лишнее).
Неправильная декомпозиция
Самая частая проблема тут — вообще вся логика во вьюхах. Открываешь views.py и там прям простыня.
В реальных проектах это смерти подобно потому что в таких вьюхах сразу появляются баги, которые никто кроме автора не может исправить, а следом появляется копипаста как самый простой способ переиспользовать код и ничего не сломать (сразу). В небольших проектах это значит, что автор не умеет в базовую декомпозицию кода, не понимает, зачем это нужно, а значит пишет плохорасширяемый и сложносопровождаемый код.
Правильно декомпозировать код — навык, которому надо долго учиться. В идеале — на практике, с ревью от опытных товарищей и всем таким. Если хотите начать хоть с чего-то, возьмите flake8-functions и настройте под себя. Этот плагин не даст вам писать слишком длинные функции с кучей параметров. О, а ещё у меня есть статья про дизайн функций.
Свои велосипеды вместо использования библиотек
Сидишь, пишешь-пишешь код, отлаживаешь, тратишь время. А потом всё удаляешь и заменяешь парой импортов из сторонних модулей, которые делают то же, только стабильнее, быстрее и правильнее. Обидно, да? Особенно часто такое происходит у начинающих разработчиков с Джангой — она ж огромная, там рил дохуя всего. Если вам нужна дефолтная авторизация по емейлу/паролю — она есть, даже вьюхи писать не надо. Нужно по модели отрисовать форму, дать заполнить, при удачном заполнении создать объект и сохранить в базу, а при неудачном отрисовать форму с ошибками? Это тоже есть, называется CreateView. Хотите по русскому названию сущности генерировать путь? Есть python-slugify или TitleSlugDescriptionModel в django-extensions.
Даже если вам нужно что-то, что вы можете написать за полчаса, лучше взять эту функциональность из сторонней библиотеки, если это возможно. Очень часто это полчаса превращаются в два и ещё час на отладку и всё равно не обрабатывают какие-нибудь крайние случаи, а в коде из сторонней библиотеки всё чики-пуки.
Чтобы не изобретать изобретённое, надо знать, что изобретено. Поэтому советую взять за правило читать всю документацию модулей, которые вы используете. Да, для Джанго это задача не на часок. Зато закроете прочитанную документацию вы другим человеком, обещаю. Кроме этого, перед реализацией какой-то функции хорошо бы приучить себя гуглить, нет ли библиотек, которые это делают. Эта практика экономит десятки, сотни, тысячи часов.
Нет тестов
Это очень частая проблема не только у новичков: не писать тесты. Какие тесты, чё ты хочешь вообще, скажи спасибо, что код есть, окей?
Не окей, братан. Самые простые интеграционные тесты займут часок на написание и сразу будут приносить кучу профита. Если ты пишешь юнит-тесты, то это значит, что ты лучше декомпозируешь код. В конце концов это значит, что ты умеешь писать тесты, а это мастхев для почти любого реального проекта.
Чтобы научиться писать тесты, нужно писать тесты. Тут как с декомпозицией: это навык, который долго приобретается через практику. Начать можно, например, со статьи Getting Started With Testing in Python. Советую сразу начинать с использования pytest, он очень крутой и распространённый в боевых проектах.
Нет аннотаций типов
Какого типа аргумент принимает на вход функция get_api_auth(token) ? А что возвращает? Нифига непонятно. И так не только в этой функции, а в каждой функции в проекте. То ли дело get_api_auth(token: str) -> Header .
Аннотации типов несут огромную пользу: делают код читаемее и защищают от ошибок ( mypy проверяет, что вы передаёте в функцию аргументы тех типов, что были заявлены). По моему опыту в реальных проектах аннотации пока используются не везде, но уже много где. Кроме того, я не видел ни одного джуна, который умеет в аннотации типов, поэтому если бы он мне попался, получил бы большую фору.
Я разделяю владение аннотациями типов на три уровня. Давайте сосредоточимся на первом, это когда вы умеете в аннотацию базовых типов без особых извращений и настроили mypy для проверки. Это работа на пару вечеров. Начать можно с пары гайдов (например, Using Python’s Type Annotations и Python Type Checking Guide), добавления в закладки базового читлиста и использования flake8-annotations-coverage (он не даёт писать неаннотированный код всегда).
Нет CI
Выше у нас появилось куча вещей, которые нужно постоянно запускать: flake8 , mypy , pytest . Если это не делается автоматом, то пиши пропало: нельзя всё время помнить про это всё, перед некоторыми коммитами что-то да забудешь. Тут-то и пригождается CI.
В 2021 настроить CI — совсем простое дело. В первый раз, конечно, придётся повозиться, но оно того стоит. Самые популярные варианты–Github Actions, Travis и Gitlab CI, у всех есть бесплатные варианты.
Короче, советую потратить время на овладение этим навыком, там нет каких-то хитрых инфрастурктурных девопс пререквизитов. Про Тревис я писал в отдельной статье (Короче говоря: TravisCI). Про Github Actions хорошо написано в официальной помощи, начать можно с интро.
Django Testing Tutorial
Testing is an important but often neglected part of any Django project. In this tutorial we’ll review testing best practices and example code that can be applied to any Django app. I also cover testing in depth with many examples in my three books: Django for Beginners, Django for APIs, and Django for Professionals.
Broadly speaking there are two types of tests you need to run:
- Unit Tests are small, isolated, and focus on one specific function
- Integration Tests are aimed at mimicking user behavior and combine multiple pieces of code and functionality
While we might we use a unit test to confirm that the homepage returns an HTTP status code of 200, an integration test could mimic the entire registration flow of a user.
For all tests the expectation is that the result is either expected, unexpected, or an error. An expected result would be an HTTP 200 response on the homepage, but we can—and should—also test that the homepage does not return something unexpected, like an HTTP 404 response. Anything else would be an error requiring further debugging.
The main focus of testing should be unit tests. You can’t write too many of them. They are far easier to write, read, and debug than integration tests. They are also quite fast to run.
When to write/run tests
In the words of Django co-creator Jacob Kaplan-Moss, «Code without tests is broken as designed.» You should write and run tests all the time. Whenever new code has been added to a project, it is not done until tests are added to confirm it works as intended and doesn’t break other project code.
A beginner might think that writing tests takes too long but tests very quickly save huge amounts of time. Even for a solo developer, projects grow in size. Who knows if that new 3rd party integration works properly or subtly breaks an important part of your site? What if you step away from the code for a few weeks/months and can’t remember everything? Or if a colleague needs to make a change?
Tests can be confusing to write initially—hence this tutorial—but practically speaking the same patterns are used over and over again.
It is common on many projects to rely on a continuous integration service to automatically run all existing tests on every new commit. This way you don’t have to run tests manually.
Initial Set Up
Complete set up instructions can be found here for installing Python, Django, Git and the rest. In this tutorial we will use the standard Unix prompt of $ to precede all commands.
Assuming you already have Python installed and know how to use the command line, navigate to the Desktop and create a new directory called djangotesty .
We will create a new virtual environment called .venv and install Django. These instructions place it on the Desktop but any location you can easily access is fine.
Now create a new Django project called django_project and run migrate to set up the initial database.
Run runserver now to confirm everything is installed properly. If you visit http://127.0.0.1:8000/ in your web browser you should see the following image:
We will create two apps in this tutorial and test both thorougly: a pages app with two static pages and a messageboard app with a list view. A fuller description of creating these apps and Django itself can be found in my book Django for Beginners. Since the focus here is on testing, I will tersely give the commands to set up each now.
Hello, World and About Page
Let’s create a basic home page and about page that we can then test. A fuller description of a Django Hello, World app can be found here. I will tersely give the commands here so we can focus on testing instead.
Create a new app called pages .
Add it to the INSTALLED_APPS configuration within django_project/settings.py .
Ultimately we need dedicated views, urls, and templates for these two pages. We’ll start with the views.
Update pages/views.py with two class-based views, HomePageView and AboutPageView , that rely on the corresponding templates home.html and about.html .
Create a new file, pages/urls.py , for our two URL paths. We import both views at the top of the file, set them to «» and about/ , and provide each with a URL name.
Update the django_project/urls.py file with our pages app URL paths.
Lastly we need to create the template files for home.html and about.html referenced in pages/views.py . Django will automatically look for a templates/app_name directory within each app so create that now.
Then in your text editor create pages/templates/pages/home.html and pages/templates/pages/about.html . Populate the templates with the following simple code.
Then navigate to the homepage at http://127.0.0.1:8000/ and about page at http://127.0.0.1:8000/about to confirm everything is working.
Django Testing
Django comes with a small set of its own tools for writing tests, notably a test client and four provided test case classes. These classes rely on Python’s unittest module and TestCase base class.
The Django test client can be used to act like a dummy web browser and check views. This can be done within the Django shell for one-off tests but is more commonly integrated into unit tests.
Most Django unit tests rely on TestCase but on occasions when an application does not rely on a database, SimpleTestCase can be used instead.
SimpleTestCase
Since our pages app only has two static pages at the moment we can use SimpleTestCase in the existing pages/tests.py file.
Take a look at the code below which adds four tests for our homepage. First, we test that the URL works correctly and the / web page, the homepage, returns an HTTP 200 Response. Second, we confirm calling the page by its URL name via reverse(). This is why we added name=»home» to the pages/urls.py URL path for the homepage. Third, we confirm the template used is home.html . And finally we check the template’s content looking for the HTML snippet <h1>Homepage</h1> and also that incorrect HTML is not on the page. It’s always good to test both expected and unexpected behavior.
Now run the tests. They should all pass.
As an exercise, see if you can add a class for AboutPageTests in this same file. It should have the same five tests but will need to be updated slightly. Run the test runner once complete. The correct code is below so try not to peak.
Run the new tests now.
There are many more tests we could conceivably add but for static webpages these tests cover the basics: validating an HTTP 200 response, the correct view and template are used, and checking the template’s content.
Message Board app
Now let’s create our message board app so we can try testing out database queries. First create a new app called posts .
Add it to the django_project/settings.py file.
Then run migrate to update the database.
Now add a basic model.
Create a database migration file and activate it.
For simplicity we can just a post via the Django admin. So first create a superuser account and fill in all prompts.
Update our admin.py file so the posts app is active in the Django admin.
Then restart the Django server with python manage.py runserver and login to the Django admin at http://127.0.0.1:8000/admin/. You should see the admin’s login screen:
Click on the link for + Add next to Posts . Enter in the simple text Hello world! .
On «save» you’ll see the following page.
Now add our posts/views.py file.
Create a posts/templates/posts/posts.html template file in your text editor and add the code below to simply output all posts in the database.
Finally, we need to update our urls.py files. Start with the project-level one located at django_project/urls.py .
Then create a posts/urls.py file in your text editor and populate it as follows.
Okay, phew! We’re done. Start up the local server python manage.py runserver and navigate to our new message board page at http://127.0.0.1:8000/posts.
It simply displays our single post entry. Time for tests!
TestCase
TestCase is the most common class for writing tests in Django. It allows us to mock queries to the database.
setUpTestData() lets us create initial data once, at the class level, for the entire TestCase . This technique allows for much faster tests than creating the data from scratch for each individual unit test within the class.
Let’s test out our Post database model.
The first unit test, test_model_content , checks that the data in our mock database matches what was initially created in setUpTestData . Then we check the URL to confirm it returns an HTTP 200 Response. And finally test_homepage uses reverse to call the URL name, checks for an HTTP 200 Response, verifies the correct template is used, and confirms that HTML content matches what is expected.
We can run tests on a project-wide basis or specify a more granular approach, such as per-app by adding the app name to the end. Let’s test just these three new tests in the posts app.
Now run all our project’s tests which will include both the pages app and the posts app.
Test Layout
As Django projects grow in complexity, it is common to delete the initial app/tests.py file and replace it with an app-level tests folder that contains individual tests files for each area of functionality. Therefore instead of a single pages/tests.py file you could have a pages/tests/ directory and within it decided files—all starting with test_ —for different areas of the app.
We don’t have anywhere near enough tests yet for this refactoring to make sense but as a project expands further dividing the tests in this fashion can help reason about the code.
Next Steps
There is far more testing-wise that can be added to a Django project. A short list includes:
- Continuous Integration: automatically run all tests whenever a new commit is made, which can be done using Github Actions or a service like Travis CI.
- pytest: pytest is the most popular enhancement to Django and Python’s built-in testing tools, allowing for more repeatable tests and a heavy use of fixtures.
- coverage: With coverage.py you can have a rough overview of a project’s total test coverage.
- Integration tests: useful for testing the flow of a website, such as authentication or perhaps even payments that rely on a 3rd party.
All three of my books on Django contain comprehensive testing so if you’re interested in learning more about Django testing, they are a good resource (and the first several chapters of each can be read for free online):
I also recommend Adam Johnson’s book, Speed Up Your Django Tests, which is a more advanced but excellent guide to tests.
© LearnDjango | Django is a registered trademark of the Django Software Foundation.
Добавление юнит-тестирования в проект Django
Практически невозможно создавать веб-сайты, которые будут идеально работать сразу без каких-либо ошибок. По этой причине вы должны тестировать ваше веб-приложение, чтобы находить эти ошибки и упреждающе работать с ними. Чтобы повысить эффективность тестирования, очень часто используется разбивка тестов на модули, которые проверяют конкретный функционал веб-приложения. Эта практика называется юнит-тестированием. Это упрощает обнаружение ошибок, поскольку тесты фокусируются на небольших частях (юнитах) вашего проекта, никак не затрагивая другие его части.
Тестирование веб-сайта может стать сложной задачей, поскольку он включает несколько слоев логики, например обработку HTTP-запросов, валидацию форм и отрисовку шаблонов. Однако Django предоставляет набор инструментов, которые избавляют от множества проблем при тестировании веб-приложений. В Django предпочтительным способом написания тестов является использование модуля unittest Python, хотя вы можете использовать другие фреймворки для тестирования.
В этом руководстве вы выполните настройку набора тестов для вашего проекта Django и напишете юнит-тесты для моделей и представлений в вашем приложении. Вы научитесь запускать эти тесты, анализировать их результаты и искать причины падения тестов.
Предварительные требования
Прежде чем начать выполнение этого руководства, вам потребуется следующее:
- Django, установленный на вашем сервере с настроенной средой программирования. Чтобы сделать это, вы можете воспользоваться одним из наших руководств по установке веб-фреймворка Django и настройке среды программирования.
- Проект Django с моделями и представлениями. В этом руководстве мы будем использовать проект из нашей серии обучающих материалов по разработке Django.
Шаг 1 — Добавление набора тестов для вашего приложения Django
Набор тестов в Django — это все тест-кейсы для всех приложений в вашем проекте. Чтобы утилита тестирования Django могла обнаружить все имеющиеся тест-кейсы, вы должны записать тест-кейсы в скрипт, название которого начинается с test . На этом шаге вы должны будете создать структуру каталогов и файлов для вашего набора тестов и создать внутри пустой тест-кейс.
Если вы ознакомились с серией обучающих материалов по разработке Django, у вас в распоряжении должно быть приложение Django с именем blogsite .
Давайте создадим папку для хранения всех наших скриптов тестов. Вначале необходимо активировать виртуальную среду:
Затем перейдите в каталог приложения blogsite , в папку, которая содержит файлы models.py и views.py , а затем создайте новую папку с именем tests :
Далее необходимо превратить эту папку в пакет Python, добавив файл __init__.py :
Теперь вы должны добавить файл для тестирования ваших моделей и другой файл для тестирования представлений:
В заключение вы создадите пустой тест-кейс в файле test_models.py : Вам нужно будет импортировать класс TestCase Django и сделать его родительским классом для вашего класса тест-кейса. В дальнейшем вы сможете добавить в этот тест-кейс методы для тестирования логики в ваших моделях. Откройте файл test_models.py :
Теперь добавьте в файл следующий код:
Вы успешно добавили набор тестов в приложение blogsite . Далее вам необходимо заполнить данные для пустого тест-кейса модели, которую вы создали.
Шаг 2 — Тестирование кода Python
На этом шаге вы протестируете логику кода в файле models.py . В частности, вы должны будете протестировать метод save модели Post , чтобы убедиться, что при вызове он создает корректный слаг для тайтла поста.
Давайте начнем с изучения кода, который уже находится в файле models.py для метода save модели Post :
Вы увидите следующее:
Мы можем убедиться, что он проверяет, есть ли у поста, который будет сохранен, значение слага, и если нет, вызывает slugify для создания слага. Это тип логики, который вы можете захотеть протестировать, чтобы убедиться, что слаги действительно были созданы при сохранении поста.
Чтобы протестировать это, вернитесь к файлу test_models.py :
Затем обновите его содержимое, добавив код в выделенные части:
Этот новый метод test_post_has_slug создает новый пост с именем "My first post" , а затем указывает для поста автора и сохраняет пост. После этого, используя метод assertEqual из модуля unittest Python, он проверяет корректность слага для поста. Метод assertEqual проверяет, равны ли два переданных ему аргумента, что определяется оператором "==" , и генерирует ошибку в противном случае.
Сохраните и закройте test_models.py .
Это пример того, что можно протестировать. Чем больше логики вы будете добавлять в ваш проект, тем больше тестов вам потребуется. Если вы добавите в метод save дополнительную логику или создадите новые методы для модели Post , вам нужно будет добавить сюда дополнительные тесты. Вы можете добавить их в метод test_post_has_slug или создать новые методы тестирования, но их имена должны начинаться с test .
Вы успешно создали тест-кейс для модели Post , где вы проверяли, что слаги создаются корректно после сохранения. На следующем шаге вы должны будете написать тест-кейс для тестирования представлений.
Шаг 3 — Использование тестового клиента Django
На этом шаге вы напишете тест-кейс, который тестирует представление с помощью тестового клиента Django. Тестовый клиент — это класс Python, который действует как шаблонный браузер, позволяя вам тестировать ваши представления и взаимодействовать с приложением Django таким же образом, как это делал бы пользователь. Вы можете получить доступ к тестовому клиенту, сославшись на self.client в ваших тестовых методах. Давайте, например, создадим тест-кейс в test_views.py . Откройте файл test_views.py :
Затем добавьте следующее:
ViewsTestCase содержит метод test_index_loads_properly , который использует тестовый клиент Django для посещения стартовой страницы веб-сайта ( http:// your_server_ip :8000 , где your_server_ip — это IP-адрес сервера, который вы используете). Затем тестовый метод проверяет, содержит ли ответ код состояния 200 , который означает, что страница отправляет ответ без ошибок. В результате вы можете быть уверены, что при посещении страницы пользователем она также не будет генерировать ошибки.
Помимо кода состояния вы можете узнать о других свойствах ответа тестового клиента, которые вы можете протестировать, на странице тестирования ответов документации Django.
На этом шаге вы создали тест-кейс для тестирования того, что визуализация представления стартовой страницы выполняется без ошибок. Теперь ваш набор тестов содержит два тест-кейса. На следующем шаге вы запустите их для просмотра результатов.
Шаг 4 — Запуск тестов
Теперь, когда вы завершили сборку набора тестов для проекта, пришло время запустить эти тесты и посмотреть их результаты. Чтобы запустить тесты, перейдите в папку blog (содержащую файл manage.py приложения):
Запустите их с помощью следующей команды:
Вы увидите примерно следующий вывод в вашем терминале:
Этот вывод содержит две точки .. , каждая из которых отображает выполненный тест-кейс. Теперь вы можете изменить test_views.py , чтобы вызвать падение теста. Сначала откройте файл с помощью следующей команды:
Затем измените выделенный код на следующий:
Здесь вы изменили код состояния с 200 на 404 . Теперь снова запустите тест из каталога с файлом manage.py :
Вывод должен выглядеть так:
Вы увидите сообщение, содержащее описание ошибки, указывающее скрипт, тест-кейс и метод, который не был выполнен. Также оно сообщает причину ошибки, в данном случае код состояния не равен 404 , в форме сообщения AssertionError: 200 ! = 404 . AssertionError здесь возникает в выделенной строке кода в файле test_views.py :
Она указывает, что утверждение является ложным, т. е. код состояния ответа ( 200 ) не соответсвует ожидаемому результату ( 404 ). Теперь вы можете видеть, что две точки .. , идущие перед сообщением об ошибке, теперь превратились в . F , что говорит о том, что первый тест-кейс был пройден успешно, а второй — нет.
Заключение
В этом руководстве вы создали набор тестов в вашем проекте Django, добавили тест-кейсы для тестирования логики модели и представления,узнали, как запускать тесты, и проанализировали вывод теста. В качестве следующего шага вы можете создать новые тестовые скрипты для кода Python в других файлах помимо models.py и views.py .
Ниже представлено несколько статей, которые могут оказаться полезными при создании и тестировании сайтов с помощью Django:
- Документация по юнит-тестам Django
- Серия обучающих материалов по масштабированию Django
Также вы можете найти на нашей странице материалов по теме Django другие руководства и проекты.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.