Рубрики
Без рубрики

Учебник для тестирования Django

Тестирование является важным, но часто пренебрегающим частью любого проекта Django. В этом руководстве мы рассмотрим … Помечено Django, Python, учебник, тестирование.

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

Широко говоря, есть два типа тестов, которые вам нужно запустить:

  • Агрегаты тесты Маленькие, изолированные и сосредоточены на одной конкретной функции.
  • Интеграционные тесты Направлены на подражание поведения пользователя и объединить несколько кусков кода и функциональности.

Пока мы можем использовать Установка теста Чтобы подтвердить, что домашняя страница возвращает код состояния HTTP 200, AN Тест интеграции может имитировать весь регистрационный поток пользователя.

Для всех тестов ожидание заключается в том, что результат либо ожидается, неожиданный или ошибка. Ожидаемый результат будет 200 ответ на главную страницу, но мы можем – и должны – также проверять, что домашняя страница не возвращает что-то неожиданное, как 404 ответ. Все остальное было бы ошибкой, требующей дальнейшей отладки.

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

Полный исходный код – Доступно на Github Отказ

Когда запустить тесты

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

Макет

По умолчанию все новые приложения в проекте Django поставляются с Tests.py файл. Любой тест в этом файле, который начинается с test_ будет проходить тестовый бегун Django. Убедитесь, что все тестовые файлы начинаются с Test_ Отказ

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

Например:

|__app
    |__tests
        |-- __init__.py
        |-- test_forms.py   
        |-- test_models.py   
        |-- test_views.py   

Образец проекта

Давайте создадим небольшой проект Django с нуля и тщательно проверить его. Это будет имитировать Приложение Board Board Из главы 4 Django для начинающих Отказ

В командной строке запускайте следующие команды, чтобы начать наш новый проект. Мы разместим код в папке под названием Testy На рабочем столе, но вы можете найти код где угодно вы выбираете.

$ cd ~/Desktop
$ mkdir testy && cd testy
$ pipenv install django
$ pipenv shell
(testy) $ django-admin startproject myproject .
(testy) $ python manage.py startapp pages

Теперь обновите settings.py Чтобы добавить наши новые страницы Приложение и настроить Django для поиска уровня проекта Шаблоны папка.

# myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'pages.apps.PagesConfig', # new
]

TEMPLATES = [
    ...
        'DIRS': [os.path.join(BASE_DIR, 'templates')], # new
    ...
]

Создайте наши две шаблоны для тестирования на домашнюю страницу и о странице.

(testy) $ mkdir templates
(testy) $ touch templates/home.html
(testy) $ touch templates/about.html

Заполните шаблоны следующим простым кодом.


Homepage

About page

Обновите уровень проекта URLS.PY Файл, чтобы указать на страницы приложение.

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('pages.urls')), # new
]

Создать URLS.PY Файл в страницы приложение.

(testy) $ touch pages/urls.py

Затем обновите его следующим образом:

# pages/urls.py
from django.urls import path

from .views import HomePageView, AboutPageView

urlpatterns = [
    path('', HomePageView.as_view(), name='home'),
    path('about/', AboutPageView.as_view(), name='about'),
]

И как последний шаг добавьте наши взгляды.

# pages/views.py
from django.views.generic import TemplateView


class HomePageView(TemplateView):
    template_name = 'home.html'


class AboutPageView(TemplateView):
    template_name = 'about.html'

Запустите локальный сервер Django.

(testy) $ python manage.py runserver

Затем перейдите к домашней странице в http://127.0.0.1:8000/ и о странице в http://127.0.0.1:8000/about подтвердить все работает.

Время для испытаний.

SimpleteStcase

Наше приложение Django имеет только две статические страницы на данный момент. Там нет связана с базой данных, что означает, что мы должны использовать SimpleteStcase Отказ

Мы можем использовать существующие Страницы/Tests.py Файл для наших тестов на данный момент. Посмотрите на код ниже, который добавляет пять тестов на нашу домашнюю страницу. Сначала мы проверим, что это существует и возвращает 200 HTTP-код состояния. Затем мы подтверждаем, что использует URL-адрес по имени Главная Отказ Мы проверяем, что используется шаблон home.html , HTML соответствует тому, что мы набрали до сих пор, и даже проверить, что он не содержит неверного HTML. Это всегда хорошо, чтобы проверить оба Ожидается и Неожиданный поведение.

# pages/tests.py
from django.http import HttpRequest
from django.test import SimpleTestCase
from django.urls import reverse

from . import views


class HomePageTests(SimpleTestCase):

    def test_home_page_status_code(self):
        response = self.client.get('/')
        self.assertEquals(response.status_code, 200)

    def test_view_url_by_name(self):
        response = self.client.get(reverse('home'))
        self.assertEquals(response.status_code, 200)

    def test_view_uses_correct_template(self):
        response = self.client.get(reverse('home'))
        self.assertEquals(response.status_code, 200)
        self.assertTemplateUsed(response, 'home.html')

    def test_home_page_contains_correct_html(self):
        response = self.client.get('/')
        self.assertContains(response, '

Homepage

') def test_home_page_does_not_contain_incorrect_html(self): response = self.client.get('/') self.assertNotContains( response, 'Hi there! I should not be on the page.')

Теперь запустите тесты.

(testy) $ python manage.py test

Они все должны пройти.

Как упражнение, посмотрите, можете ли вы добавить класс для О репутации в этом же файле. Он должен иметь те же пять тестов, но нужно будет немного обновляться. Запустите тестовый бегун один раз. Правильный код ниже, поэтому попробуйте не пик …

# pages/tests.py
class AboutPageTests(SimpleTestCase):

    def test_about_page_status_code(self):
        response = self.client.get('/about/')
        self.assertEquals(response.status_code, 200)

    def test_view_url_by_name(self):
        response = self.client.get(reverse('about'))
        self.assertEquals(response.status_code, 200)

    def test_view_uses_correct_template(self):
        response = self.client.get(reverse('about'))
        self.assertEquals(response.status_code, 200)
        self.assertTemplateUsed(response, 'about.html')

    def test_about_page_contains_correct_html(self):
        response = self.client.get('/about/')
        self.assertContains(response, '

About page

') def test_about_page_does_not_contain_incorrect_html(self): response = self.client.get('/') self.assertNotContains( response, 'Hi there! I should not be on the page.')

Доска объявлений приложение

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

(testy) $ python manage.py startapp posts

Добавьте его к нашему settings.py файл.

# myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'pages.apps.PagesConfig',
    'posts.apps.PostsConfig', # new
]

Затем запустите мигрировать создать нашу начальную базу данных.

(testy) $ python manage.py migrate

Теперь добавьте базовую модель.

# posts/models.py
from django.db import models


class Post(models.Model):
    text = models.TextField()

    def __str__(self):
        """A string representation of the model."""
        return self.text

Создайте файл миграции базы данных и активируйте его.

(testy) $ python  manage.py makemigrations posts
(testy) $ python manage.py migrate posts

Для простоты мы можем просто пост через админу Django. Поэтому сначала создайте Суперзор учетная запись и заполните все подсказки.

(testy) $ python manage.py createsuperuser

Обновите наш admin.py файл, так что Сообщения Приложение активно в администрате Django.

# posts/admin.py
from django.contrib import admin

from .models import Post

admin.site.register(Post)

Затем перезапустите сервер Django с Python Manage.py Runserver и войдите в админ Django в http://127.0.0.1:8000/admin/ Отказ Вы должны увидеть экран входа в админ:

Нажмите на ссылку для + Добавить рядом с Сообщения Отказ Войдите в простой текст Привет мир! .

В «Сохране» вы увидите следующую страницу.

Теперь добавьте наши Виды файл.

# posts/views.py
from django.views.generic import ListView
from .models import Post


class PostPageView(ListView):
    model = Post
    template_name = 'posts.html'

Создать posts.html Файл шаблона.

(testy) $ touch templates/posts.html

И добавьте код ниже, чтобы просто вывести все сообщения в базе данных.


Message board homepage

    {% raw %}{% for post in object_list %}
  • {{ post.text }}
  • {% endfor %}{% endraw %}

Наконец, нам нужно обновить наши URLS.PY файлы. Начните с уровня проекта, расположенного на MyProject/URLS.PY Отказ

# myproject/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('', include('pages.urls')),
    path('admin/', admin.site.urls),
    path('posts/', include('posts.urls')),
]

Тогда создайте URLS.PY Файл в Сообщения приложение.

(testy) $ touch posts/urls.py

И заполнить его следующим образом.

# posts/urls.py
from django.urls import path

from .views import PostPageView

urlpatterns = [
    path('', PostPageView.as_view(), name='posts'),
]

Хорошо, jew! Были сделаны. Запустите локальный сервер Python Manage.py Runserver и перейдите на нашу новую страницу доски сообщений на http://127.0.0.1:8000/posts Отказ

Это просто отображает нашу запись на одну запись. Время для испытаний!

Прецедент

Testcase является наиболее распространенным классом для написания тестов в Джангу. Это позволяет нам насмешать запросы к базе данных.

Давайте проверим наш Пост Модель базы данных.

# posts/tests.py
from django.test import TestCase
from django.urls import reverse

from .models import Post


class PostTests(TestCase):

    def setUp(self):
        Post.objects.create(text='just a test')

    def test_text_content(self):
        post = Post.objects.get(id=1)
        expected_object_name = f'{post.text}'
        self.assertEquals(expected_object_name, 'just a test')

    def test_post_list_view(self):
        response = self.client.get(reverse('posts'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, 'just a test')
        self.assertTemplateUsed(response, 'posts.html')

С Testcase Тестовый бегун Django создаст пример тестовой базы данных только для наших тестов. Здесь мы наследили его текст «Просто тест» Отказ

В первом тесте мы подтверждаем, что тестовая запись имеет основной идентификатор 1 и контент матчей. Затем во втором тесте на просмотре мы подтверждаем, что он использует имя URL Сообщения , имеет 200 HTTP-код состояния ответа, содержит правильный текст и использует правильный шаблон.

Запустите новый тест, чтобы подтвердить все работает.

(testy) $ python manage.py test

Следующие шаги

Существует гораздо больше тестирования, которые могут быть добавлены в проект Django. Краткий список включает в себя:

  • Непрерывная интеграция : Автоматически запустить все тесты всякий раз, когда выполняется новый коммит, который можно сделать с помощью действий GitHub или услугу, такую как Трэвис СИ .
  • питиш : pteest является самым популярным усилением в встроенных инструментах тестирования Django и Python, что позволяет для более повторяющихся тестов и тяжелой пользы светильников.
  • охват : С Coverage.py Вы можете иметь приблизительный обзор общего тестового покрытия проекта.
  • Интеграционные тесты : Полезно для тестирования потока веб-сайта, такого как аутентификация или, возможно, даже платежи, которые полагаются на 3-й сторон.

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

Если вам нужна дополнительная помощь справки сейчас, отличный курс Разработка тестов с Django, Django Read Framework и Docker моим другом Майклом Германом.

Оригинал: “https://dev.to/learndjango/django-testing-tutorial-1a73”