Тестирование в Django
При разработке веб-приложений большинство программистов часто избегают тестирования. Я основном говорю о начинающих программистах. Да и многие , кто уже довольно долго в этой профессии и которые разрабатывают коммерческие приложения довольно часто избегают тестирования , а многие незнакомы с ней
В этой статье мы будем рассматривать тестирования для веб-приложений , которые создаются с использованием фреймворка Django
Так для чего вам нужно тестирование и зачем тратить на это время и ресурсы?
Как забавно не звучало бы на первый взгляд , но тестирование позволяет вам экономить ваше время. Как обычно происходит проверка работоспособности написанного кода, если вы не используете тестирование ? Мы обычно это делаем вручную , вводя определенные данные и смотря как работает наш код. Но со временем проект разрастается и у вас десятки компонентов , которые взаимодействуют друг с другом и измненения в одном компоненте может влиять на другие компоненты. И это будет занимать большое время при ручном тестировании системы, а некоторые ошибки вы не сможете отследить до того , пока это не окажется в продакшене. А автоматизированные тесты помогут вам отследить многие ошибки до выкладки на продакшен.
Когда вы пишите новый код, то написанные вами правильно тесты позволяют убедиться в том , что ваш код работает правильно.
Также , при измении вами старого кода или кто-то из ваших коллег изменит какую-то часть нашего приложения , то тесты покажут, поломался ли ваш функционал или нет.
Тестирование веб-приложений - очень сложная задача. Так как нам нужно протестировать обработку HTTP запросов , валидацию форм , отрисовку шаблонов. Но во фреймворке Django есть средства которые упрощают нам тестирование и в этой статье рассмотрим конкретно тестирование использованием этих средств
Создадим app
python manage.py startapp blog
Давайте вначале опишем наши модели для блога
from django.db import models
from django.utils import timezone
class Category(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(max_length=255)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Категория'
verbose_name_plural = 'Категории'
def get_absolute_url(self):
return f'/category/{self.slug}/'
class Post(models.Model):
class Statuses(models.TextChoices):
DRAFT = 'DRAFT', 'Черновик'
PUBLISHED = 'PUBLISHED', 'Опубликован'
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=1024)
content = models.TextField()
created_at = models.DateTimeField(default=timezone.now)
updated_at = models.DateTimeField()
status = models.CharField(max_length=10, choices = Statuses.choices, default=Statuses.DRAFT)
category = models.ForeignKey(Category, related_name='posts', on_delete=models.CASCADE)
def __str__(self):
return self.title
class Meta:
ordering = ('-created_at',)
verbose_name = 'Пост'
verbose_name_plural = 'Посты'
@property
def is_published(self):
return self.status == Post.Statuses.DRAFT
Создадим миграции и применим их следующими командами:
python manage.py makemigrations
python manage.py migrate
Как вы можете заметить , внутри app есть файл tests.py, где мы можем написать наши тесты для этого приложения. Для начала это приемлемый путь.
У модели Category есть метод get_absolute_url , который возвращает url с использованием поля slug. В нашем первом тесте мы проверим правильно ли работает этот метод для вновь созданного объекта модели Category. Создадим наш первый тестовый класс CategoryModelTests который наследуется от TestCase и напишем первый тест методом test_absolute_url_is_correct. Методы должны начинаться с "test_"
from django.test import TestCase
from blog.models import Category
class CategoryModelTests(TestCase):
def test_absolute_url_is_correct(self):
new_category = Category(name='Первый пост', slug='first-post')
new_category.save()
self.assertEqual(new_category.get_absolute_url(), '/category/first-post/')
Запустим
python manage.py test
Наш тест запустился и отработал успешно
Для модели Post у нас есть метод is_published , который возвращает опубликован ли пост или нет. Этот метод неправильно работает и это сделано специально , чтобы найти неправильное поведение при тестировании. Давайте напишем новый тест для модели Post, который проверяет правильно ли работает метод is_published
from django.test import TestCase
from blog.models import Category, Post
class CategoryModelTests(TestCase):
def test_absolute_url_is_correct(self):
new_category = Category.objects.create(name='Первый пост', slug='first-post')
self.assertEqual(new_category.get_absolute_url(), '/category/first-post/')
class PostModelTests(TestCase):
def test_is_published_post(self):
category = Category.objects.create(name='Первый пост', slug='first-post')
new_post = Post.objects.create(title='Первый опубликованный пост',
slug='first-published-post',
category=category,
status=Post.Statuses.PUBLISHED,
)
self.assertTrue(new_post.is_published)
После запуска тестов мы видим , что у нас запустилось два теста и один тест упал. Тут в выводе мы видим на какой строчке упал и по какой причине
Давайте пофиксим наш метод Is_published в модели Post
@property
def is_published(self):
return self.status == Post.Statuses.PUBLISHED
Запустим заново тесты и посмотрим на результат:
Заключение
В данной статье мы написали первые тесты для нашего проекта Django и было описано для чего нужно тестирование в проектах. Тестирвание очень важная часть разработки и не стоит им пренебрегать