파이썬 unittest에서 pytest로 전환하기

구경회·2023년 6월 25일
1
post-thumbnail

들어가며

개인적으로 작업했던 프로젝트는 기존에 unittest를 이용해서 작성했다. 하지만 다음과 같은 이유로 인해 새로 작성하는 테스트는 pytest를 이용해 작성했다.

  1. unittest의 문법은 pep 규약과 잘 맞지 않는다. self.assertEqual(lhs, rhs) 같은 경우는 메서드 이름을 스네이크 케이스로 짓는 pep와 합치하지 않는다.
  2. 여러 assert를 기억하고 사용하기에 번거로움이 있다. 반면 pytest는 단순히 assert 만을 사용하면 되므로 편리하다.

하지만 기존 코드베이스에 unittest를 사용해 작성한 테스트가 상당히 많아 옛날 코드베이스는 그대로 놔두었다.

그런데 얼마 전에 나쁜 코드의 문제는 마치 중력처럼 다른 코드들도 나쁘게 만든다는데 있다는 걸 깨달았다. 새로 온 팀원은 아무래도 기존 코드베이스를 참고해서 작업하게 된다. 우연히 그 팀원이 기존에 unittest 로 작성한 부분을 참고해 self.assertEqual로 도배한 테스트코드를 작성한 것이다. 물론 코드리뷰 과정을 통해 pytest로 전환하기는 했지만 서로에게 불필요한 시간낭비였고 기존 코드베이스를 이대로 놔둘 수 없겠다는 생각이 들었다.

하지만 일일히 고칠 수는 없다

이제 고치기로 마음을 먹었지만, 단순히 손으로 고치기에는 양이 좀 많고 사실 머리를 쓸 일은 아닌 거 같았다. 그래서 정규식과 sed를 활용해 코드베이스를 고치기로 했다.

예시를 보자.

get = self.client.get("/posts")
self.assertEqual(get.status_code, 200)

위 코드는 pytest를 이용하면 다음과 같이 번역할 수 있다.

assert get.status_code == 200

즉, self.assertEqual(a, b)assert a == b처럼 번역할 수 있는 것이다. 이제 이걸 sed 문법에 맞게 쓰면 다음과 같이 할 수 있다.

sed -i '' 's/self\.assertEqual(\([^,]*\), \([^)]*\))/assert \1 == \2/' <filename>;   

현재 프로젝트의 테스트는 모두 tests/ 디렉토리 아래에서 관리하고 있다. 따라서 for loop를 이용해 다음과 같이 반복했다.

for test in $(find tests); do
	sed -i '' 's/self\.assertEqual(\([^,]*\), \([^)]*\))/assert \1 == \2/' $test;   
done
sed -i '' 's/self\.assertNotEqual(\([^,]*\), \([^)]*\))/assert \1 != \2/' $test;

assertNotEqual 은 위와 같이 할 수 있다.

sed -i '' 's/self\.assertTrue(\([^,]*\))/assert \1/'

하는 김에 조금만 더...

이제 unitest의 matcher들을 pytest의 matcher들로 모두 바꾸었다. 다시 코드를 보니 눈에 조금 밟히는 것이 있다.

assert get.status_code == 200

위 코드는 다음과 같이 바꾸면 좀 더 의미를 담아낼 수 있다.

from rest_framework import status

assert get.status_code == status.HTTP_200_OK

위 변경은 단순히 텍스트 대치이므로 쉽게 할 수 있다.

profile
즐기는 거야

0개의 댓글