Django, Django Rest-Framework 및 Djoser를 테스트하는 방법

이 블로그 게시물에서는 사용자를 위해 이메일 활성화를 사용하는 동안 djoser를 테스트하는 방법을 볼 것입니다.

요구 사항
  • 응용 프로그램 내에서 이미 djoser를 사용하고 있습니다.

  • 이메일 활성화와 함께 django, django restframework 및 djoser를 사용하고 있지만 인증을 테스트하는 데 어려움을 겪고 있습니까? 그 문제를 잠시 후에 해결해 봅시다.

    먼저 설정 파일을 프로덕션, 개발 및 테스트로 분리해야 합니다. 구조는 이렇게 생겼어요

    settings/
          __init__.py
          base.py
          production.py
          development.py
          testing.py
    


    가장 먼저 해야 할 일은 기본 프로젝트 내에 settings 라는 폴더를 만드는 것입니다. 폴더 이름에 주의하세요. settings.py 와 정확히 동일해야 하지만 .py 는 없어야 합니다.

    다음으로 아래 파일을 만듭니다.

    __init__.py
    base.py
    production.py
    development.py
    testing.py
    


    이러한 파일은 개발 시 제안된 이름으로 사용됩니다. django 설정은 development.py를 사용하고 테스트하는 동안에는 testing.py를 사용합니다.

    이제 모든 프로젝트에 대한 공통 설정을 base.py 에 복사해 보겠습니다. 모든 프로젝트에 공통적인 사항을 식별하는 것은 귀하에게 달려 있습니다.

    내 경우에는 base.py에 대해 다음을 입력합니다.

    BASE_DIR
    SECRET_KEY # read from environment variable
    INSTALLED_APPS
    MIDDLEWARE
    ROOT_URLCONF
    TEMPLATES
    WSGI_APPLICATION
    AUTH_PASSWORD_VALIDATORS
    LANGUAGE_CODE
    TIME_ZONE
    USE_I18N
    USE_TZ
    STATIC_URL
    DEFAULT_AUTO_FIELD
    AUTH_USER_MODEL
    # emial related parameter are read from env in my case
    EMAIL_BACKEND
    EMAIL_HOST
    EMAIL_PORT
    EMAIL_HOST_USER
    EMAIL_HOST_PASSWORD
    EMAIL_USE_TLS
    REST_FRAMEWORK # depends on your choice of drf settings
    DJOSER # common setting only we will extend it in other files
    

    production.py에 대한

    from .base import *
    
    DEBUG = False
    ALLOWED_HOSTS = ['yoursite.com'] # up to you choice what to allow
    DATABASES # i use different db for prod
    DJOSER.update({
    ....
    }) # i use different conf for prod 
    

    development.py에 대한

    from .base import *
    
    DEBUG = True
    ALLOWED_HOSTS = ['*'] # up to you choice what to allow
    DATABASES # i use different db for dev
    DJOSER.update({
    ....
    }) # i use different conf for dev
    


    for testing.py는 이 파일을 자세히 볼 수 있지만 지금은

    from .base import *
    
    DEBUG = True
    ALLOWED_HOSTS = ['*'] # up to you choice what to allow
    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
    DATABASES # i use different db for test
    DJOSER.update({
    ....
    }) # i use different conf for test
    


    이제 마지막 파일은 __init__.py이 파일은 설정을 동적으로 로드합니다.

    import os
    
    from . import base
    
    enviroment = os.environ.get('ENVIROMENT', 'development')
    
    if enviroment == 'production':
        from .production import *
    elif enviroment == 'testing':
        from .testing import *
    else:
        from .development import *
    


    Djoser는 다른 용도로 다른 직렬 변환기 클래스를 사용하지만 문서를 확인하는 데만 집중합니다Email serialzers.

    이제 testing.py 파일을 작성해 보겠습니다.

    from .base import *
    DEBUG = True
    ALLOWED_HOSTS = ['*']
    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
    DATABASES = {
        # 'default': {
        #     'ENGINE': 'django.db.backends.sqlite3',
        #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        # }
        # for postgresql: i use postgres 
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'djoser',
            'USER': 'djoser',
            'PASSWORD': 'djoser',
            'HOST': 'localhost',
            'PORT': '5432',
        }
    
        # for mysql:
        # 'default': {
        #     'ENGINE': 'django.db.backends.mysql',
        #     'NAME': 'djoser',
        #     'USER': 'djoser',
        #     'PASSWORD': 'djoser',
        #     'HOST': 'localhost',
        #     'PORT': '3306',
        # }
    }
    
    DJOSER_EMAIL = {
        'activation': 'your-authentication-app.email.ActivationEmail'
    }
    
    if 'EMAIL' in DJOSER:
        DJOSER['EMAIL'].update(DJOSER_EMAIL)
    else:
        DJOSER['EMAIL'] = DJOSER_EMAIL
    
    


    에서 알아차리면

    DJOSER_EMAIL = {
        'activation': 'your-authentication-app.email.ActivationEmail'
    }
    


    이메일 활성화 시리얼라이저를 your-authentication-app.email.ActivationEmail로 재정의하지만 아직 존재하지 않으므로 지금 생성해 보겠습니다.

    인증 앱에서 email.py라는 파일을 만들고 아래의 직렬 변환기를 넣고 이야기해 봅시다.

    from django.contrib.auth.tokens import default_token_generator
    
    # djoser imports
    from templated_mail.mail import BaseEmailMessage
    from djoser import utils
    from djoser.conf import settings
    
    EMAILS = {}
    
    class ActivationEmail(BaseEmailMessage):
        """Email Activation Token Generator
        """
        template_name = "email/activation.html"
    
        def get_context_data(self):
            # ActivationEmail can be deleted
            context = super().get_context_data()
            user = context.get("user")
            context["uid"] = utils.encode_uid(user.pk)
            context["token"] = default_token_generator.make_token(user)
            context["url"] = settings.ACTIVATION_URL.format(**context)
            uid, token = context['uid'], context['token']
            # here we store all the requested tokens in a dictionary for later use
            EMAILS[user.email] = {'uid': uid, 'token': token}
            return context
    


    djoser 직렬 변환기에서 추가하는 유일한 것은

    EMAIL = {}
    
    ...
    
    EMAILS[user.email] = {'uid': uid, 'token': token}
    


    서버에서 보낸 이메일을 저장하는 데 사용됩니다.

    참고: 테스트하는 동안 django가 실제 이메일을 보내는 것을 원하지 않기 때문에 EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'를 사용하고 있습니다.

    이제 우리는 사용자를 테스트할 것입니다. 테스트할 몇 가지 사례가 있지만 그 동안 무엇을 테스트할지는 스스로 결정해야 합니다.

    from django.urls import reverse
    from django.contrib.auth import get_user_model
    from rest_framework import status
    from rest_framework.test import APITestCase
    
    User = get_user_model()
    
    class UserViewSetTest(APITestCase):
    
        def setUp(self):
            """
            Set up method which is used to initialize before any test run.
            """
            self.user_info = self.generate_user_info()
    
        def generate_user_info(self):
            """Generate user data for new user.
            Returns:
                Dict: dictionary of the test user data.
            """
            return {
                "first_name": "fake.first_name()",
                "last_name": "fake.last_name()",
                "username": "fake.user_name()",
                "password": "fake.password()",
            }
    
        def test_create_user(self):
            """
            Test for creating users using API.
            """
            url = reverse("user-list")
            response = self.client.post(
                url,
                self.user_info,
            )
            self.assertEqual(response.status_code, status.HTTP_201_CREATED)
            user = User.objects.get(id=response.data['id'])
            self.assertEqual(user.email, self.user_info["email"])
            self.assertEqual(user.username, self.user_info["username"])
            # self.assertEqual(user.ssn, self.user_info["ssn"])
            self.assertTrue(user.password is not self.user_info["password"])
            self.assertTrue(user.is_deleted is not True)
            self.assertTrue(user.father_first_name is None)
            self.assertTrue(user.mother_first_name is None)
            self.assertTrue(user.password is not None)
            self.assertTrue(user.birth_date is not None)
    
        def test_get_token(self):
            """
            This test is used to test the login API. getting token and testing the token.
            """
            # Create a new user to login
            user_info = self.generate_user_info()
            new_user = self.client.post(
                reverse("user-list"),
                user_info,
            )
            self.assertEqual(new_user.status_code, status.HTTP_201_CREATED)
    
            # Activation of User
            from authentications.email import EMAILS
    
            activation_url = reverse('user-activation')
            activation_data = EMAILS[user_info["email"]]
            self.client.post(activation_url, activation_data)
    
            url = reverse("jwt-create")
            data = {
                "username": user_info["username"],
                "password": user_info["password"],
            }
            response = self.client.post(url, data)
    
            self.assertTrue(response.status_code, status.HTTP_200_OK)
            self.assertTrue(response.data["access"] is not None)
    
        def test_get_user(self):
            """
            This test for retrieving single user using API.
            """
    
            # Create a new user to login
            new_user = self.client.post(
                reverse("user-list"),
                self.user_info,
            )
            self.assertEqual(new_user.status_code, status.HTTP_201_CREATED)
    
            # Activate User
            from authentications.email import EMAILS
    
            activation_url = "http://127.0.0.1:8000/auth/users/activation/"
            activation_data = EMAILS[self.user_info["email"]]
            self.client.post(activation_url, activation_data)
    
            # Get token
            url = reverse("jwt-create")
            data = {
                "username": self.user_info["username"],
                "password": self.user_info["password"],
            }
    
            response = self.client.post(url, data)
            self.assertTrue(response.status_code, status.HTTP_200_OK)
    
            # Get user
            token = response.data["access"]
            self.client.credentials(HTTP_AUTHORIZATION=f"JWT {token}")
    
            url = reverse('user-list', kwargs={'id':new_user.data["id"]})
            get_user = self.client.get(url)
    
            self.assertEqual(get_user.status_code, status.HTTP_200_OK)
            self.assertEqual(get_user.data["id"], new_user.data["id"])
            self.assertEqual(get_user.data["email"], new_user.data["email"])
    
            test_user = self.client.post(
                reverse("user-list"),
                self.generate_user_info(),
            )
            url = url = reverse('user-list', kwargs={'id': test_user.data['id'] })
            get_user = self.client.get(url)
            self.assertEqual(get_user.status_code, status.HTTP_404_NOT_FOUND)
    


    위의 테스트에는 원하는 테스트 유형이 있지만 이 블로그의 주요 목적은 전자 메일 활성화를 사용하여 djoser를 테스트하는 방법을 알려주는 것입니다.

    그것이 당신을 돕기를 바랍니다.

    즐기다.

    좋은 웹페이지 즐겨찾기