이번 2차 프로젝트에서 unit test를 배웠고, 모든 app마다 tests.py를 작성하게 되었다. 프로젝트를 진행하면서 개인프로젝트로 했던 DanoshopClone, InstagramClone 에도 unit test를 추가하게 되었는데 인스타그램 클론코딩프로젝트에 unit test 를 작성할 때 어떻게 해야 할지 모를 문제에 직면했다.
보통 유닛테스트는 def setUp(self):
을 통해 가상의 데이터를 만들고 테스트 코드를 돌려서 결과를 확인하게 되는데 이때 나오는 결과값도 우리가 뷰를 돌렸을 때 나오는 값과 동일하게 작성하면 된다.
예를 들어보자.
# view.py 에 작성한 결과
result = [{
'id':data.id,
'name':data.name,
'price':data.price,
} for data in datas]
return JsonResponse({'data_list':result}, status=200)
# unit test 결과작성
self.assertEqual(response.json(),
{
'data_list':
[{
'id':1,
'name':'pencil',
'price':2000
}
{
'id':3,
'name':'pen',
'price':2500
}]
}
)
이런식으로 가상 데이터를 setUp()
에 작성 후 그 결과값을 예상하여 뷰에 맞게 입력하여 실행하면 된다.
부딪힌 문제는 created_at
이었다. 뷰의 결과값에 created_at
이 있었는데 이거는 인스턴스가 생성될 때의 시간이기 때문에 예상해서 실행을 할 수가 없었다. 결론적으로는 해결을 하였고, posting 을 get 해오는 뷰를 작성하였었는데 게시글에는 시간이 나와야 하기 때문에 created_at
이 결과값에 들어갈 수밖에 없었다. 이걸 그대로 출력하게 되면 DateTimeField
이기 때문에 결과값이
datetime(datetime....
의 형식으로 나온다. 이것을 우리가 원하는 형식으로 출력되게 바꾸려면 strftime
메소드를 쓴다.
unit test 에서는 setUp 에 만드는 데이터를 변수에 지정해놓고 결과값에는 뷰와 같이 변수.created_at.strftime 형식으로 만들어서 unit test를 완료하였다.
# views.py
results = [{
'id' : data.id,
'content' : data.content,
'image' : [data.image for data in Image.objects.filter(posting=data)],
'created_at': data.created_at.strftime('%Y-%m-%d %H:%M:%S')
} for data in posting]
# unit test
self.assertEqual(response.json(),
{'posting_list':[{
'id' : 11,
'content' : 'hihi',
'image' : ['cat.cat','cat1.cat'],
'created_at' : posting.created_at.strftime('%Y-%m-%d %H:%M:%S')
}]}
)
덕분에 쉽게 해결했습니다 감사합니다