팀프로젝트를 만들어 봅시다!
저번 주 튜터님에게 배웠던 test.py를 이용한 테스트를 해볼 수 있는 방법을 보았는데.
내가 만든 것을 구축하고 테스트 해보는 것이 직관적으로 판단을 하기도 좋고 postman을 이용해서 일일이 확인을 하지 않고 볼수 있다는 것이 아주 편하다는 것을 알았습니다!
accounts test.py
from .models import PasswordQuestion
from django.test import TestCase
from rest_framework.test import APIClient
from rest_framework import status
from django.contrib.auth import get_user_model
User = get_user_model() # 현재 활성화된 사용자 모델을 가져옵니다.
class AccountAPITest(TestCase):
def setUp(self):
self.client = APIClient()
self.admin_user = User.objects.create_superuser(
username='admin_user', email='admin@example.com', password='admin_password')
# 암호 질문 생성
self.password_question = PasswordQuestion.objects.create(
question='What is your favorite color?')
# 유저 생성
self.user = User.objects.create_user(
username='test_user', email='test@example.com', password='test_password', password_question_id=self.password_question.id, password_answer="Test Answer")
# 모든 테스트에 사용할 사용자로 로그인
self.client.force_authenticate(user=self.user)
def test_create_password_question(self):
# 관리자로 로그인
self.client.force_authenticate(user=self.admin_user)
# 유효한 질문을 포함하여 암호 질문 생성 (절대 경로로 수정)
question_data = {'question': 'What is your favorite color?'}
response = self.client.post('/api/accounts/password/', question_data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# 생성된 암호 질문이 데이터베이스에 있는지 확인
created_question = PasswordQuestion.objects.get(
question='What is your favorite color?')
self.assertIsNotNone(created_question)
def test_change_password(self):
# 비밀번호 변경 요청
change_data = {
'password_question': self.password_question.id,
'password_answer': 'Test Answer',
'new_password': 'new_test_password',
'confirm_password': 'new_test_password'
}
response = self.client.post(
f'/api/accounts/profile/{self.user.id}/', change_data)
# 변경 요청이 실패한 경우 오류 메시지 출력
if response.status_code != status.HTTP_200_OK:
print(response.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_profile_update(self):
# 프로필 업데이트 요청
update_data = {'email': 'new_email@example.com'}
response = self.client.put(
f'/api/accounts/profile/{self.user.id}/', update_data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_delete_account(self):
# 계정 삭제 요청
response = self.client.delete(
f'/api/accounts/profile/{self.user.id}/')
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
articles test.py
from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient
from .models import Article, Comment # Article과 Comment 모델을 불러옵니다.
from django.contrib.auth import get_user_model
User = get_user_model() # 현재 활성화된 사용자 모델을 가져옵니다.
# ArticleDetailAPIViewTest 클래스를 정의합니다.
class ArticleDetailAPIViewTest(TestCase):
def setUp(self): # 각 테스트 메서드가 실행되기 전에 실행되는 설정 메서드입니다.
# 테스트에 필요한 초기 상태를 설정합니다.
self.user = User.objects.create_user(
username='testuser', password='12345') # testuser라는 이름의 사용자를 생성합니다.
self.client = APIClient() # API 클라이언트를 생성합니다.
self.client.force_authenticate(user=self.user) # 클라이언트를 특정 사용자로 인증합니다.
self.article = Article.objects.create( # Article 모델의 인스턴스를 생성하여 테스트할 게시물을 만듭니다.
title='Test Article', content='Test Content', author=self.user)
def test_create_comment(self): # 댓글 작성을 테스트하는 메서드입니다.
url = reverse('articles:detail', kwargs={ # 'articles:detail' URL 패턴을 역으로 해석하여 URL을 생성합니다.
'article_id': self.article.id})
data = {'content': 'Test Comment Content'} # 댓글의 내용을 포함하는 데이터를 생성합니다.
# 생성된 URL에 데이터를 전송하여 댓글을 작성합니다.
response = self.client.post(url, data, format='json')
# 응답의 상태 코드를 확인하여 요청이 성공적으로 처리되었는지 확인합니다.
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
comment = Comment.objects.last() # Comment 모델에서 마지막 댓글을 가져옵니다.
# 작성된 내용과 게시물, 작성자가 올바른지 확인합니다.
self.assertEqual(comment.content, 'Test Comment Content')
self.assertEqual(comment.article, self.article)
self.assertEqual(comment.author, self.user)
# 댓글의 내용이 빠진 경우를 테스트하는 메서드입니다.
def test_create_comment_missing_content(self):
url = reverse('articles:detail', kwargs={ # 'articles:detail' URL 패턴을 역으로 해석하여 URL을 생성합니다.
'article_id': self.article.id})
data = {} # 데이터에 내용이 빠진 경우를 표현하기 위해 빈 딕셔너리를 생성합니다.
# 생성된 URL에 데이터를 전송하여 댓글을 작성합니다.
response = self.client.post(url, data, format='json')
# 응답의 상태 코드를 확인하여 요청이 실패하고 '400 Bad Request' 상태 코드를 반환하는지 확인합니다.
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
class CommentAPIViewTest(TestCase):
def setUp(self):
# 테스트를 위한 초기 설정
self.user = User.objects.create_user(
username='testuser', password='12345') # 테스트용 유저 생성
self.client = APIClient() # 테스트용 클라이언트 생성
self.client.force_authenticate(user=self.user) # 인증된 유저로 설정
self.article = Article.objects.create(
title='Test Article', content='Test Content', author=self.user) # 테스트용 게시물 생성
self.comment = Comment.objects.create(
content='Test Comment', author=self.user, article=self.article) # 테스트용 댓글 생성
def test_create_reply(self):
# 답글 생성 테스트
url = reverse('articles:comment', kwargs={
'comment_id': self.comment.id}) # URL 생성
data = {'content': 'Test Reply Content'} # 생성할 답글 데이터
response = self.client.post(
url, data, format='json') # POST 요청하여 답글 생성
self.assertEqual(response.status_code,
status.HTTP_201_CREATED) # 응답 코드 확인
reply = Comment.objects.last() # 가장 최근에 생성된 댓글 가져오기
self.assertEqual(reply.content, 'Test Reply Content') # 답글 내용 확인
self.assertEqual(reply.parent_comment, self.comment) # 부모 댓글 확인
self.assertEqual(reply.author, self.user) # 작성자 확인
def test_create_reply_missing_content(self):
# 댓글 생성 시 content가 없는 경우 테스트
url = reverse('articles:comment', kwargs={
'comment_id': self.comment.id}) # URL 생성
data = {} # content가 빠진 데이터
response = self.client.post(
url, data, format='json') # POST 요청하여 답글 생성
self.assertEqual(response.status_code,
status.HTTP_400_BAD_REQUEST) # 응답 코드 확인
def test_update_comment(self):
# 댓글 수정 테스트
url = reverse('articles:comment', kwargs={
'comment_id': self.comment.id}) # URL 생성
data = {'content': 'Updated Test Comment'} # 수정할 댓글 데이터
response = self.client.put(url, data, format='json') # PUT 요청하여 댓글 수정
self.assertEqual(response.status_code, status.HTTP_200_OK) # 응답 코드 확인
self.comment.refresh_from_db() # DB에서 댓글 다시 가져오기
self.assertEqual(self.comment.content,
'Updated Test Comment') # 댓글 내용 확인
def test_update_missing_content(self):
# 댓글 수정 시 content가 없는 경우 테스트
url = reverse('articles:comment', kwargs={
'comment_id': self.comment.id}) # URL 생성
data = {} # content가 빠진 데이터
response = self.client.put(url, data, format='json') # PUT 요청하여 댓글 수정
self.assertEqual(response.status_code,
status.HTTP_400_BAD_REQUEST) # 응답 코드 확인
def test_delete_comment(self):
# 댓글 삭제 테스트
url = reverse('articles:comment', kwargs={
'comment_id': self.comment.id}) # URL 생성
response = self.client.delete(url) # DELETE 요청하여 댓글 삭제
self.assertEqual(response.status_code,
status.HTTP_204_NO_CONTENT) # 응답 코드 확인
self.assertFalse(Comment.objects.filter(
pk=self.comment.id).exists()) # 댓글이 삭제되었는지 확인
def test_delete_comment_wrong_user(self):
# 다른 유저가 댓글 삭제 시도 시 테스트
another_user = User.objects.create_user(
username='anotheruser', password='12345') # 다른 유저 생성
self.client.force_authenticate(user=another_user) # 다른 유저로 인증 설정
url = reverse('articles:comment', kwargs={
'comment_id': self.comment.id}) # URL 생성
response = self.client.delete(url) # DELETE 요청하여 댓글 삭제
self.assertEqual(response.status_code,
status.HTTP_403_FORBIDDEN) # 응답 코드 확인
이제 새로 생각을 해보아야 할 부분은 게시물을 검색하고 필터링 하는 방법을 알아보아야 합니다.
먼저 좋아요, 조회수, 추천글 기능을 넣어야 합니다.
from rest_framework import serializers
from .models import Article, Comment, ArticleView
class ArticleSerializer(serializers.ModelSerializer):
like_users_count = serializers.SerializerMethodField()
favorites_count = serializers.SerializerMethodField()
class Meta:
model = Article
fields = ['id', 'title', 'content', 'url',
'like_users_count', 'favorites_count']
def get_like_users_count(self, instance):
return instance.like_users.count()
def get_favorites_count(self, instance):
return instance.favorites.count()
def to_representation(self, instance):
ret = super().to_representation(instance)
article_views_count = ArticleView.objects.filter(
article=instance).count() # ArticleView의 개수를 세기
ret['article_views'] = article_views_count # 결과에 article_views 필드 추가
return ret
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ['id', 'article', 'content']
이렇게 serializer를 작성하고, 거기에 맞추어 게시글을 작성하고 만드는 방식으로 이용해서 만들어 보도록 하겠습니다.
'코딩 교육 TIL' 카테고리의 다른 글
2024-05-09 AI 코딩 TIL (0) | 2024.05.09 |
---|---|
2024-05-08 AI 코딩 TIL (0) | 2024.05.08 |
2024-05-03 AI 코딩 TIL (0) | 2024.05.03 |
2024-05-02 AI 코딩 TIL (1) | 2024.05.02 |
2024-04-30 AI 코딩 TIL (0) | 2024.04.30 |