Unit test : default db ... PK 변하지 말아줘

채록·2021년 3월 13일
0

Python & Django

목록 보기
29/34
post-thumbnail

PK.. auto increment 인건 알았지만...


I. Fail 발생

❯ python manage.py test apply
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.EEEEE
--------------------------------------------------------------------------------------------------------------------------------------------
ERROR: test_mywantus_get_success_user (apply.tests.MyWantusTest)
ERROR: test_mywantus_get_success_like (apply.tests.MyWantusTest)
ERROR: test_mywantus_get_success_bookmark (apply.tests.MyWantusTest)

진행한 테스트는 총 4개였다.

  • test_mywantus_get_success_user
  • test_mywantus_get_success_apply
  • test_mywantus_get_success_bookmark
  • test_mywantus_get_success_like

이중에 딱 하나만 성공한 것이다. (아마 가장 먼저 수행된것만 된듯 하다)

에러 메세지는 공통적으로 다음과 같았다.

django.db.utils.IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails (`test_wantwho`.`likes`, CONSTRAINT `likes_user_id_0899754c_fk_users_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))')

Foriegn Key로 사용되는 값이 잘못되었다는 것이다.




II. 문제 파악

출력 형태를 알아보기 위해 print를 찍어 보았다.

❯ python manage.py test apply
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
생성된 user의 아이디는 무엇?==============> 1 .
<=====apply 테스트 진행=====>
생성된 user의 아이디는 무엇?==============> 2 E
생성된 user의 아이디는 무엇?==============> 3 E
생성된 user의 아이디는 무엇?==============> 4 E

나는 하나의 instance만 생성했는데 auto increment특성으로 인해 하나의 test를 진행하고난후 user의 id가 하나씩 늘어갔다. 이때문에 그 다음의 test에서 user=1로 설정해주었던 것에서 모두 에러가 났던 것이다!




III. 해결하기

1) test에서 해결하기

auto increment때문에 말썽이라면 그 값을 안쓰면 된다! user객체를 생성하는데 사용되는 값은 id 뿐만이 아니라 name도 있다. name은 새로 만들어지나, 지워지나 모두 같은 이름이기 때문에 그 값을 사용하면 된다.

    def test_mywantus_get_success_like(self):
        print('<=====like 테스트 진행=====>')
        user = User.objects.get(name='보라돌이')

단점

내 로직의 경우 token의 유효성 확인이 필수이다. 저렇게 해준다 한들 token에서 입력되야 할 값은 user의 id이기 때문에 결국 먹히지 않는다 ㅎㅎㅎ

이게 먹혔던 경우는 login 유효성 확인이 필요없는 단순 get 로직에서 생성된 user의 정보를 확인했던 경우이다.


3) setUp의 PK 지정하기

애초에 setUp에서 create 할때 id 를 지정하면 된다.

class ApplyViewTest(TestCase):
    def setUp(self):
        User.objects.create(
            id        = 1,
            name      = '로그인',
            email     = 'wecode_signin@naver.com',
            image_url = 'https://wecode.co.kr/static/media/song.2cfd0cb6.png'
        )

이렇게 되면 만들어졌던 id=1 이 삭제되고 그 다음 test에서 다시 생성될때도 지정된 id 인 id=1로 생성된다!

pk를 임의로 지정해주기!




처음엔 id를 지정해 준다는 생각을 못했어서 조금 애먹었었다! 생각의 유연성? (이 상황에 적절한 단어가 맞나?ㅎㅎ) 을 길러야 겠다!

profile
🍎 🍊 🍋 🍏 🍇

0개의 댓글