django test코드 , lazy-loading

김하진·2022년 7월 22일
0

1 Unit Test 개념 및 용어

TestCase : unittest 프레임 워크의 테스트 조직의 기본 단위
Fixture : 테스트를 진행할때 필요한 테스트용 데이터 혹은 설정 등을 이야기 한다. 주로 테스트 가 실행되기 전이나 후에 생긴다.
assertion : unittest에서 테스트 하는 부분이 제대로 됬는지를 확인하는 부분. Assertion이 실패하면 테스트도 실패한다.

API 테스트

class TestLoginUser(APITestCase):
    def setUp(self):
        
        self.data = {'username':'hajin','password':'asdfasdf'}
        self.user = User.objects.create_user('hajin','asdfasdf')
        user_profile = UserProfile.objects.filter(user=self.user.id)
        info = ({
            "user_id" : self.user.id,
            "mongle_grade" : 100,
            "profile_img" : "sdfsdf.com",
        })
        user_profile.create(**info)



    def test_login(self):
        url = "/user/login"
        response = self.client.post(url, self.data)
        self.assertEqual(response.status_code, 200)

    def test_get_main(self):
        access_token = self.client.post(("/user/login"),self.data).data['access']
        response = self.client.get(
            path="/jin/main/",
            HTTP_AUTHORIZATION = f"Bearer {access_token}"
            )

        with CaptureQueriesContext(connection) as ctx:
            user_profile_data = MainPageDataSerializer(self.user).data
            my_worry_get = WorryBoard.objects.select_related("letter").filter(author=self.user)
        self.assertEqual(response.status_code, 200)
        self.assertEqual({"user_profile_data":user_profile_data},{"user_profile_data":user_profile_data})

우선 내가 작성한 API 테스트이다, 테스트 코드는 실행시 테스트용 DB를 따로 만들어주고, 테스트가 실행 될때 마다 DB를 초기화 시킨다.

그래서 든 의문점은, 할때마다 그럼 빌드업을 계속 해줘야하나, 그렇다면 인증은 어떻게 하지? 였다.

setUP() 함수를 통해서 기초적인 빌드업을 할 수 있다. 우선 우리프로젝트에서는 Userprofile 이 없으면 get요청시 오류가 나기때문에 setup 업에서 함께 지정을 해주었고, HTTP_AUTHORIZATION = f"Bearer {access_token}" 을 통해서 가져 올 수 있다.

TestCase, ctx

        with CaptureQueriesContext(connection) as ctx:
            
            my_worry = worry_obj_my_letter(user.id)

APi 테스트 말고, 따로도 테스트를 할 수 있다. 우선 지금 쿼리최적화를 위해서 작성중인데, 이부분은 좀더 공부가 필요할 것 같다.

ctx 를 통해서 쿼리를 보고 싶었지만, 쿼리가 찍히지 않는 이슈가 발생하였다. 그래서 튜터님한테 물어 본 결과

lazy 한 쿼리의 상태라서 그렇다고 한다.

Lazy-loading

Django의 ORM은 다른 ORM과 마찬가지로 Lazy-loading방식을 사용한다. Lazy-loading이란 ORM에서 명령을 실행할 때마다 데이터베이스에 접근하여 데이터를 가져오는 것이 아닌 모든 명령처리가 끝나고 실제 데이터를 불러와야할 때 데이터베이스 Query문을 실행하는 방식을 말한다.

Query문을 실행하는 시점
다음은 Django에서 Query문을 실행하는 시점(QuerySet을 불러올 때)이다.
1. 슬라이싱(Slicing)
2. Pickling/Caching
3. repr()
4. len()
5. list()
6. bool()

f문을 사용해 boolean값을 확인하게 될 때 포함한다. 그러므로 찾는 값의 존재여부만 파악할 때는 if문을 사용하는 것보다 .exists()를 이용하여 확인하는 것이 성능면에서는 효율적이다.(하지만 그 값으로 evaluation을 해야할 경우에는 if문을 사용)

Eager-loading
Eager-loading(즉시 로딩)은 Lazy-loading의 반대 개념이다. Lazy-loading은 Query문을 하나, 하나 실행하여 데이터를 가져온다면 Eager-loading은 지금 당장 사용하지 않을 데이터도 포함하여 Query문을 실행하기 때문에 밑에 설명할 Lazy-loading의 N+1문제의 해결책으로 많이 사용하게 된다.
Django에서 Eager-loading을 실행하는 방법은 select_related 메소드와 prefetch_related 메소드를 사용한다.

profile
진킴

0개의 댓글