개발일지/스파르타코딩클럽

파이썬 장고 실무 심화 5주차 : 테스트코드(3)

마이구미+ 2023. 5. 4. 21:05

<DRF로 테스트코드 작성하기>

- 이미지 없는 게시글 작성 테스트

# articles/tests.py

from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status
from users.models import User


class ArticleCreateTest(APITestCase):
    @classmethod
    def setUpTestData(cls):
        cls.user_data = {"email": "test@test.test", "password": "1234"}
        cls.article_data = {"title": "테스트제목", "content": "테스트내용"}
        cls.user = User.objects.create_user("test@test.test", "1234")

    def setUp(self):
        self.access_token = self.client.post(
            reverse("token_obtain_pair"), self.user_data).data["access"]

    ...

    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.data["message"], "글 작성 완료!") 
        self.assertEqual(response.status_code, 201) # 둘 중 골라서 하기
  • 아직 클래스메소드에 대해 정확하게 받아들이진 못한 것 같다..
  • 어쨌든 둘 다 self.를 통해서 접근하는데 뭐 때문에 나눠지는 건지.......다시 보니 모르겠네
  • 음 엑세스 토큰을 얻기 위해선 로그인 데이터가 필요하니까 self.user_data를 써야 해서 setUpTestData에 같이 못 쓴건가...?
  • 여튼 이번 테스트코드는 이전에 로그인 안 했을 때 게시글 작성하는 코드에 HTTP_AUTHORIZATION을 넣어 로그인 정보를 추가해주었다
  • 포스트맨에서 헤더에 AUTHORIZATION 추가하는 거랑 같다고 보면 될 것 같다

- 이미지를 포함한 게시글 작성 테스트

  • 이미지 파일을 만드는 과정과 보내는 과정이 필요하다
# articles/tests.py
...
# 이미지 업로드
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
  • 임포트 했던 곳 바로 밑에 작성해준다
  • 임시 이미지를 만들어서 저장하는 함수인 것 같다
# articles/tests.py
...
class ArticleCreateTest(APITestCase):
    @classmethod
    def setUpTestData(cls):
        cls.user_data = {"email": "test@test.test", "password": "1234"}
        cls.article_data = {"title": "테스트제목", "content": "테스트내용"}
        cls.user = User.objects.create_user("test@test.test", "1234")

    ...

    def test_create_article_with_image(self):
        # 임시 이미지 파일 생성
        temp_file = tempfile.NamedTemporaryFile()   # 장고에서 제공하는 무언가 이름이 있는 임시 파일 생성
        temp_file.name = "image.png"                # 임시 파일의 이름 설정
        image_file = get_temporary_image(temp_file) # 위에서 정의한 get_temporary_image()에 임시 파일을 보내 임시 이미지 파일을 받아옴
        image_file.seek(0)                          # 이미지의 첫 번째 프레임을 받아옴
        self.article_data["image"] = image_file     # 위에 setUpTestData에서 정의한 article_data에 방금 생성한 이미지를 넣어줌
  • 어렵다~
  • 전송까지 해줘야 한다!
# articles/tests.py
...
        # 전송
        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.data["message"], "글 작성 완료!")
  • 위에 이미지 없는 게시글 작성 코드에서 response 부분을 떼와서 data는 encode_multipart로 바꿔주고(이미지 등 파일을 포함한 데이터는 encode를 해야 하는 것 같다) content_type도 지정한다