-
유닛 테스트중 You can't execute queries until the end of the 'atomic' block 해결 방법Web/Django 2022. 5. 25. 19:11
회원가입 api의 유닛 테스트를 하던 중, email 중복을 거르기 위해 발생하는 에러인 integrity 에러가 발생하는 상황을 테스트하려고 할 때
django.db.transaction.TransactionManagementError: An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.
라는 에러가 발생하여 테스트를 통과하지 못하였다.
#views.py class SignupView(View): def post(self, request): try: ... except IntegrityError: return JsonResponse({'message' : 'email is already exists'}, status = 400)
#tests.py class UserSignupTest(TestCase): def setUp(self): ... def test_email_already_exist(self): client = Client() form = { 'name' : 'test1', 'email' : 'test1@gmail.com', 'is_doctor' : 'False', 'password' : '1q2w3e4r' } response = client.post('/users/signup', json.dumps(form), content_type='application/json') self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), {'message' : 'email is already exists'})
구글링을 해보니 transaction.atomic()을 사용하는 상황을 테스트 할때는, 테스트 클래스가 TestCase를 상속하는 게 아닌, TransactionTestCase를 상속해야 에러 없이 테스트를 진행할 수 있다고 한다. 따라서 TestCase 대신 TransactionTestCase를 상속하게 하면 문제가 해결된다.
아마도 unique=True를 검사하는 과정에서 transaction을 사용하는 것 같은데, 공식문서를 찾아보고 구글링을 해봐도 이 궁금증에 대한 해답을 찾기 어려웠다.
다만 주의해야할점이 있다. transaction을 사용하지 않는 테스트 함수의 클래스가 TransactionTestCase를 상속하면, 테스트 속도가 느려진다. 필자가 만든 클래스에는 총 7개의 테스트가 있는데, 이메일 중복 테스트는 transaction을 이용하는 상황이고, 나머지 6개는 이용하지 않는 상황이다. 7개의 테스트를 TransactionTestCase를 상속한 하나의 클래스에 몰아서 작성하고 테스트할 때 와 TestCase를 상속받는 클래스, TransactionTestCase를 상속받는 클래스 두 개로 나누어 테스트를 했을 때 속도가 눈에 띄게 차이가 난 것이다.
TransactionTestCase를 상속하는 하나의 클래스에 몰아서 처리할때 TestCase 클래스와, Transaction 클래스를 나누었을때 0.726 0.509 0.769 0.509 0.692 0.509 0.713 0.513 0.709 0.515 간단한 7개의 테스트를 실행했는데도 속도가 눈에띄게 차이가 났는데, 수많은 테스트를 한 클래스에 몰아서 테스트하려 하면 무시할 수 없는 테스트 속도의 손해가 발생할 것이다. 결론적으로 무조건 TranscationTestCase를 상속하는 것이 아닌, 테스트하려는 상황이 transaction을 사용하는지에 여부에 따라 나누어서 상속을 받아야 할 것이다.
'Web > Django' 카테고리의 다른 글
django가 제공해주는 회원가입/로그인 기능 (0) 2022.05.26 Django migration 순환참조 오류 해결방법 (0) 2022.05.15 ManyToManyField 사용의 장점 (0) 2022.04.13