본문 바로가기

회고록(TIL&WIL)

TIL 2022.08.09 프로젝트 DRF Test Code

pip install faker

Faker 클래스를 이용해서 가상의 데이터들 무작위, 자동으로 생성 가능

setUpData 에서 테스트용 데이터 생성하고

CaptureQueriesContext 이용해서 실제로 작동되는 쿼리문을 확인 할 수 있다.

connection은 같이 한세트로 묶어서 import 해와야하고

query_debugger는 앞서 게시한 글에서 적어놓은 대로 테스트코드에도 쓸 수 있다.

reverse 함수를 이용해서 urls 지정 시 name="" 에 지정해놓은 값을 통해서 간편하게 사용 할 수 있다.

해당 함수에 kwarg={"":""} 값을 줘서 url에 주는 데이터를 지정해 줄 수 있다.

 

user app tests.py

import json
from django.urls import reverse
from faker import Faker
from rest_framework.test import APITestCase
from rest_framework import status

from _utils.query_utils import query_debugger
from project.models import Project
from .models import MeetTime, Region, Skills, User, UserProfile

from django.test.utils import CaptureQueriesContext
from django.db import connection

# 회원가입 테스트
class UserRegistrationTest(APITestCase):
    # 모든 테스트 시작 전 호출되는 함수
    def setUp(self):
        self.data = {"email": "test@mail.com", "password":"test"}
        self.user = User.objects.create_user("test@mail.com", "test")
        
    # 모든 테스트 마지막 호출 되는 함수
    def tearDown(self):
        pass
    
    # 중복된 아이디로 회원가입 시 (400)
    def test_registration_duplicate(self):
        url = reverse("join_view")
        user_data = {
            "email" : "test@mail.com",
            "username": "중복",
            "password": "test",
            "password_confirm": "test"
        }
        response = self.client.post(url, user_data)
        # print(response.data)
        self.assertEqual(response.status_code, 400)
        
    # 정상적인 회원가입 (201)
    def test_registration(self):
        url = reverse("join_view")
        user_data = {
            "email" : "newtest@mail.com",
            "username": "패스",
            "password": "newtest",
            "password_confirm": "newtest"
        }
        response = self.client.post(url, user_data)
        # print(response.data)
        self.assertEqual(response.status_code, 201)
        
# 로그인 테스트
class LoginUserTest(APITestCase):
    # 로그인 테스트할 계정
    def setUp(self):
        self.data = {"email": "test@mail.com", "password":"test"}
        self.data_none_pwd = {"email": "test@mail.com"}
        self.data_none_email = {"password":"test"}
        self.user = User.objects.create_user("test@mail.com", "test")
        
    # 정상 로그인
    @query_debugger
    def test_login(self):
        with CaptureQueriesContext(connection) as ctx:
            response = self.client.post(reverse("token_obtain_pair"), self.data)
            # print(response.data["access"])
            self.assertEqual(response.status_code, 200)
            print("로그인 성공 쿼리", ctx.captured_queries)
    
    # 패스워드 없을 경우
    def test_login_miss_pwd(self):
        with CaptureQueriesContext(connection) as ctx:
            response = self.client.post(reverse("token_obtain_pair"), self.data_none_pwd)
            self.assertEqual(response.status_code, 400)
        
    # 아이디 없을 경우
    def test_login_miss_email(self):
        response = self.client.post(reverse("token_obtain_pair"), self.data_none_email)
        self.assertEqual(response.status_code, 400)
        
    # 유저 정보 확인
    @query_debugger
    def test_get_user_data(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx:
            response = self.client.get(
                path=reverse("user_view"),
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data['email'], self.data['email'])
            print("유저 확인 쿼리", ctx.captured_queries)

class UserProfileTest(APITestCase):
    @classmethod
    def setUpTestData(cls):
        cls.data = {"email": "test@mail.com", "password":"test"}
        cls.user = User.objects.create_user("test@mail.com", "test")
        cls.faker = Faker()
        
        for i in range(1):
            cls.user = User.objects.create_user(cls.faker.name(), cls.faker.word())
            for i in range(10):
                instance = Project.objects.create(title=cls.faker.word(),
                                                description=cls.faker.word(),
                                                thumnail_img_path=cls.faker.sentence(),
                                                content=cls.faker.word(),
                                                user=cls.user,
                                                github_url="http://www.naver.com")
                instance.bookmark.set(cls.user.username)
                instance.skills.add(1)
                
        cls.skills = Skills.objects.create(name = 'Python') # SKILLS 129
        cls.meettime = MeetTime.objects.create(time_type = '상관 없음') # 3
        cls.region = Region.objects.create(name = '서울특별시') # 17
        cls.userprofile = UserProfile.objects.create(
                user = cls.user,            
                description=cls.faker.word(),
                profile_image = cls.faker.sentence(),
                github_url = "http://www.naver.com",
                meet_time = cls.meettime,
                region = cls.region
            )
        cls.userprofile.skills.add(1)
                    
        
    @query_debugger
    def test_userprofile_post(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx:
            url = reverse("user_view")
            data = {"decription": self.faker.word(),
                    "skills": 1, 
                    "meet_time": 1, 
                    "region": 1}
            response = self.client.post(
                url,
                data,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
            print("프로필 등록 쿼리", json.dumps(ctx.captured_queries, indent=3))
            
   
    # 나의 프로젝트 출력
    @query_debugger
    def test_my_project_view(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx:
            url = reverse("my_project_view")
            response = self.client.get(
                url,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
            print("나의 프로젝트 출력 쿼리", json.dumps(ctx.captured_queries, indent=3))
    
    @query_debugger
    def test_my_bookmark_project_view(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx:
            url = reverse("my_bookmark_project_view")
            response = self.client.get(
                url,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
            print("북마크한 프로젝트 출력 쿼리", json.dumps(ctx.captured_queries, indent=3))
            
    
    @query_debugger
    def test_another_userprofile(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx:
            url = reverse("another_user_view", kwargs={"user_id":self.user.pk})
            response = self.client.get(
                url,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
            print("다른 유저 프로필 출력 쿼리", json.dumps(ctx.captured_queries, indent=3))

 

project app tests.py

from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status

from faker import Faker
import json

from django.test.utils import CaptureQueriesContext
from django.db import connection

from .models import Project
from user.models import Skills, User

from _utils.query_utils import query_debugger

class ProjectReadTest(APITestCase):
    @classmethod
    def setUpTestData(cls):
        cls.data = {"email": "test@mail.com", "password":"test"}
        cls.user = User.objects.create_user("test@mail.com", "test")
        cls.faker = Faker()
        cls.projects = []
        Skills.objects.create(name="Python")
        for i in range(1):
            cls.user = User.objects.create_user(cls.faker.name(), cls.faker.word())
            for i in range(10):
                instance = Project.objects.create(title=cls.faker.word(),
                                                description=cls.faker.word(),
                                                thumnail_img_path=cls.faker.sentence(),
                                                content=cls.faker.word(),
                                                user=cls.user,
                                                github_url="http://www.naver.com")
                instance.bookmark.set(cls.user.username)
                instance.skills.add(1)
                cls.projects.append(instance)
    
    # 게시물 리스트 출력                
    @query_debugger
    def test_get_project_list(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx :    
            response = self.client.get(
                path=reverse("project_view"),
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            # print(response.data)
            self.assertEqual(response.status_code, 200)
            
            print("게시물 리스트 확인 쿼리", json.dumps(ctx.captured_queries, indent=3))
    
    # 게시글 쓰기
    @query_debugger
    def test_post_project(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx :    
            url = reverse("project_view")
            data = {"title":self.faker.word(),
                    "description":self.faker.word(),
                    "thumnail_img_path":self.faker.sentence(),
                    "content":self.faker.word(),
                    "user":self.user,
                    "github_url":"http://www.naver.com",
                    "skills": 1}
            response = self.client.post(
                url,
                data,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
                
            print("게시물 쓰기 쿼리", json.dumps(ctx.captured_queries, indent=3))
    
    # 게시물 상세 조회
    @query_debugger        
    def test_get_project(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx :
            project = self.projects[0]
            url = project.get_absolute_url()
            
            response = self.client.get(
                path = url,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            # print(response.data)
            self.assertEqual(response.status_code, 200)
            
        print("게시물 상세조회 쿼리", json.dumps(ctx.captured_queries, indent=3))
            
    # 게시글 수정
    @query_debugger        
    def test_put_project(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx :    
            url = reverse("project_detail_view", kwargs={"project_id": 1})
            data = {"title": "바꾼 제목"}
            response = self.client.put(
                url,
                data,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
                
            print("게시물 수정 쿼리", json.dumps(ctx.captured_queries, indent=3))
            
    # 댓글 작성
    @query_debugger        
    def test_post_comment(self):
        # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx :    
            url = reverse("comment_view", kwargs={"project_id": 1})
            data = {"comment": "댓글 내용"}
            response = self.client.post(
                url,
                data,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
                
            print("댓글 작성 쿼리", json.dumps(ctx.captured_queries, indent=3))
            
        
    # 북마크 클릭 시
    @query_debugger
    def test_bookmark(self):
         # 액세스 토큰을 받아와서 HTTP_AUTHORIZATION에 주는 것이 중요!
        access_token = self.client.post(reverse("token_obtain_pair"), self.data).data['access']
        with CaptureQueriesContext(connection) as ctx :    
            url = reverse("bookmark", kwargs={'project_id': 1})
            data = {"project_id" : 1}
            response = self.client.post(
                url,
                data,
                HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )
            print(response.data)
            self.assertEqual(response.status_code, 200)
                
            print("북마크 쿼리",  json.dumps(ctx.captured_queries, indent=3))