테스트 코드
시간 낭비, 복잡도 증가, 허점을 보완하기 위해
작성한 코드들이 원하는 값을 내놓는지 확인하는 코드
테스트 주도 개발, TDD
(Test-Driven Development)
먼저 자동화된 테스트 코드를 작성한 후
테스트를 통과하기 위한 코드를 개발하는 방식의 개발 방식
python manage.py test
python manage.py test <앱이름> : 앱에서 작성한 하나의 test만 실행하고 싶을 때
from django.test import TestCase
https://www.django-rest-framework.org/api-guide/testing/
https://docs.djangoproject.com/en/4.2/topics/testing/advanced/
Faker
작성을 편리하게 해주는 라이브러리
자동으로 랜덤한 데이터를 생성해준다
pip install Faker
from faker import Faker
fake = Faker()
fake = Faker("ko_KR") # 한국어 (name만 가능)
fake.name()
fake.first_name()
fake.last_name()
fake.word() # 랜덤 단어 (비밀번호)
fake.sentence() # 랜덤 문장 (게시글 제목)
fake.text() # 랜덤 글 (게시글 내용)
https://pypi.org/project/Faker/
get_absolute_url
from django.urls import reverse
class Article(models.Model):
def get_absolute_url(self):
return reverse("article_detail_view", kwargs={"pk": self.pk})
https://docs.djangoproject.com/en/4.2/ref/models/instances/#get-absolute-url
아래는 강의 자료와 달라서 꽤나 짜증났던 부분..!
users > models.py:
from django.urls import reverse
class User(AbstractBaseUser):
def get_absolute_url(user_id):
return reverse("profile_view", kwargs={"user_id": user_id})
users > tests.py:
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status
from users.models import User
class UserRegistrationTest(APITestCase):
def test_registration(self):
url = reverse("user_view") # urls의 name을 가져옴
user_data = {
"username": "john",
"fullname": "테스터",
"email": "test@testuser.com",
"password": "johnpassword",
}
response = self.client.post(url, user_data)
self.assertEqual(response.status_code, 201)
class LoginUserTest(APITestCase):
def setUp(self):
self.data = {"email": "test@testuser.com", "password": "johnpassword"}
self.user = User.objects.create_user(
'test@testuser.com', 'johnpassword')
def test_login(self):
response = self.client.post(
reverse('token_obtain_pair'), data=self.data)
self.assertEqual(response.status_code, 200)
def test_get_user_data(self):
url = User.get_absolute_url(user_id=self.user.id)
access_token = self.client.post(
reverse('token_obtain_pair'), data=self.data).data["access"]
response = self.client.get(
path=url,
HTTP_AUTHORIZATION=f"Bearer {access_token}"
)
self.assertEqual(response.data["email"], self.data["email"])
"Reverse for '/users/1/' not found"
test_get_user_date의 self.cliendt.get에서 자꾸 에러가 났는데
path=reverse(url)에서 path=url로 바꿔주니 성공!
>>> reverse('뷰 함수')인데 get_absolute_url() 메서드에서 반환하는 URL은 '/users/1/'의 형식이었기 때문
articles > models.py:
from django.urls import reverse
class Article(models.Model):
def get_absolute_url(self):
return reverse("article_detail_view", kwargs={"article_id": self.id})
articles > tests.py:
from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status
from articles.models import Article
from articles.serializers import ArticleSerializer
from users.models import User
from faker import Faker
# 이미지 업로드
from django.test.client import MULTIPART_CONTENT, encode_multipart, BOUNDARY
from PIL import Image
import tempfile
def get_temporary_image(temp_file):
size = (200, 200)
color = (255, 0, 0, 0)
image = Image.new("RGBA", size, color)
image.save(temp_file, 'png')
return temp_file
class ArticleCreateTest(APITestCase):
@classmethod
def setUpTestData(cls):
cls.user_data = {'email': 'john', 'password': 'johnpassword'}
cls.article_data = {'title': 'title', 'content': 'content'}
cls.user = User.objects.create_user('john', 'johnpassword')
def setUp(self):
self.access_token = self.client.post(
reverse('token_obtain_pair'), self.user_data).data['access']
print(self.access_token)
def test_fail_if_not_logged_in(self):
url = reverse("article_view")
response = self.client.post(url, self.article_data)
self.assertEqual(response.status_code, 401)
def test_create_article(self):
response = self.client.post(
path=reverse("article_view"),
data=self.article_data,
HTTP_AUTHORIZATION=f"Bearer {self.access_token}"
)
self.assertEqual(response.status_code, 200)
print(response.data)
def test_create_article_with_image(self):
# 임시 이미지 파일 생성
temp_file = tempfile.NamedTemporaryFile()
temp_file.name = "image.png"
image_file = get_temporary_image(temp_file)
image_file.seek(0)
# setUpTestData의 article_data에 추가
self.article_data["image"] = image_file
# 전송
response = self.client.post(
path=reverse("article_view"),
data=encode_multipart(data=self.article_data, boundary=BOUNDARY),
content_type=MULTIPART_CONTENT,
HTTP_AUTHORIZATION=f"Bearer {self.access_token}"
)
self.assertEqual(response.status_code, 200)
class ArticleReadTest(APITestCase):
@classmethod
def setUpTestData(cls):
cls.faker = Faker()
cls.articles = []
for i in range(10):
cls.user = User.objects.create_user(
cls.faker.name(), cls.faker.word())
cls.articles.append(Article.objects.create(
title=cls.faker.sentence(), content=cls.faker.text(), user=cls.user))
def test_get_article(self):
for article in self.articles:
url = article.get_absolute_url()
response = self.client.get(url)
serializer = ArticleSerializer(article).data
for key, value in serializer.items():
self.assertEqual(response.data[key], value)
print(key, value)
'Django' 카테고리의 다른 글
DRF BooleanField (2) | 2023.04.25 |
---|---|
POETRY 가상환경 설정하기 (8) | 2023.04.24 |
파이썬 장고 실무 심화 4주차_SerializerMethodField, StringRelatedField (0) | 2023.04.21 |
Token 인증_JWT(JSON Web Token) (0) | 2023.04.21 |
파이썬 장고 실무 심화 3주차_JWT 토큰 로컬스토리지 (2) | 2023.04.21 |