본문 바로가기
CS/Python

[python3] Python 에서 유닛테스트 만들기 - 초보자편

by Warehaus 2022. 11. 7.

 

 

2022.04.27 - [CS/Python] - python 개발자 로드맵 ( developer roadmap ) 에 따라서 개발공부하기

 

python 개발자 로드맵 ( developer roadmap ) 에 따라서 개발공부하기

예전에 DevOps 업무를 수행하기 위해서 어떤 능력이 필요한지 roadmap.sh 에서 확인해 본 적이 있다. 파이썬을 현업에서 적극적으로 사용하고 있지만 가끔 기본적인 내용에 대해 엦어버릴 때가 있는

armin.tistory.com

 

 

 

 

오늘은 제가 매일 사용하고 있는 python unittest module에 대해 정리해 보려 합니다.

이전 글에서도 간단히 작성했던 기억은 있는데 

로드맵 리뷰를 하다보니 unit-test 항목이 있어서

다시한번 가볍게 짚고 넘어가겠습니다.

 

 

 

unittest framework


 

 

저는 업무에서 unittest 프레임워크를 적극 사용하고 있습니다.

프레임워크 내용은 아래 링크를 확인하시면 상세히 확인 가능합니다.

 

 

https://docs.python.org/ko/3/library/unittest.html

 

unittest — 단위 테스트 프레임워크 — Python 3.11.0 문서

unittest — 단위 테스트 프레임워크 소스 코드: Lib/unittest/__init__.py (당신이 이미 테스트 기본 개념에 친숙하다면, assert 메서드 목록으로 건너뛰어도 좋습니다.) unittest 단위 테스트 프레임워크는

docs.python.org

 

포스팅 내용을 가볍게 읽어보신 뒤  링크되어 있는 잘 정리된 문서를 보시면 더 이해하기 수월하실 것이라고 생각합니다.

 

 

 

 

유닛테스트 시작하기


 

유닛테스트를 시작하기 전에

우리가 무엇을 해야할 지 한번 짚고 넘어가야 합니다.

 

유닛테스트가 무엇인가요?

 

대부분의 개발자들이 이 질문에 대해서 어느정도 답변은 하실 것이라고 생각합니다.

 

기능에 대한 input / output 을 테스트 하는 행위라고 저는 답할 것 같습니다.

 

이 답변이 틀리지는 않았는지  더블체크를 해 보았습니다.  

 

유닛 테스트(unit test)는 컴퓨터 프로그래밍에서 소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차다. 즉, 모든 함수와 메소드에 대한 테스트 케이스(Test case)를 작성하는 절차를 말한다. 
- 출처 : 위키

 

 

결국 어떤 기능을 구현했을 때, 그 기능이 제대로 동작하는지에 대해 검증하는 것이 유닛테스트이고

파이썬에서 구현 된 기능이 제대로 수행하는지 테스트 하는 과정이 제가 이번 포스팅으로 남기고자 하는 부분입니다.

 

유닛 테스트를 어떻게 하는지 알아보기 전에

우선, 테스트 할 기능이 있어야 합니다.

 

예제 코드이니 2개의 인자를 더하는 덧셈 코드를 만들어 보겠습니다.

 

 

[pyadder.py]

def add( x, y ):
    r = x+y
    print( r )
    return r

add( 3 , 4)

 

add 함수는 아마 .. 잘 동작할 것입니다..

 

python3 pyadder.py 
7

 

참 단순한 기능이라  

add( 3, 4 ) 같은 코드를 추가해서

잘 도네?

 

하고 지운다음 add 메서드를 사용하게

일반적인 사람의 심리입니다.

 

제가 많은 사람들을 겪어보지는 못했지만

이거 보시는 분들이 이런 경험이 없다고 하면 거짓말쟁이십니다.

 

근데 그것도 테스트이긴 테스트입니다.

돌려봤고, 결과가 나왔고

잘 됐으니까요

 

실제 적용해도 잘 돌거에요

 

근데 코드를 계속 변경하다보면 언젠가 말썽을 피우게 됩니다.

그래서 우리는 CI/CD 같은 것들을 이용해서 매 커밋 또는 릴리즈마다 테스트를 돌려줍니다.

 

테스트 종류도 많죠

 

근데 그럴때 엑셀로 테스트 리스트를 만들어서

사람이 칠수는 없으니 유닛테스트를 만들어야 합니다.

 

도구.. 도구를 가져와 봅니다.

 

[unittest.py]

import unittest
import pyadder

class pyadder_ut(unittest.TestCase):
    def test_basic(self):
        r = pyadder.add( 3, 4)
        self.assertEqual( r, 7 )


if __name__ == '__main__':
    unittest.main()

 

pyadder module을 import한 뒤, 3 + 4 가 잘 되는지 유닛테스트를 구성해 보았습니다. 

실행하면 다음과 같은 결과를 볼 수 있습니다.

 

$ python3 pyadder_ut.py 
7
7
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

 

실패하면 어떻게 나오는지도 궁금하실 것 같아 결과를 추가해 봅니다.

pyadder 코드를 아래처럼 빼기로 바꿨습니다.

 

def add( x, y ):
    r = x - y
    print( r )
    return r

 

결과는 다음과 같습니다.

 

$ python3 pyadder_ut.py 
-1
F
======================================================================
FAIL: test_basic (__main__.pyadder_ut)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/armincho/toy_projects/python3_study/pyadder_ut.py", line 8, in test_basic
    self.assertEqual( r, 7 )
AssertionError: -1 != 7

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

 

 

마치며

 

사실 테스트 코드를 작성하는 방법은 생각보다 단순합니다.

어려운건 기능을 추가할 때 마다 이런 테스트들을 작성하는 팀 문화를 만드는 것 입니다.

 

제 짧은 소견입니다만..

이런 유닛테스트 구현은 코드리뷰 때 어느정도 강제성을 띄어야 하지 않나 싶습니다.

업무 관리 측면에서도  어느정도 신경써 줘야 되는 부분이구요.

 

근데 바쁘면 사실 정신없습니다.

터지더라도 일단 넣은다음에 고치게 되는데..

 

아무리 이런저런 그루들이 미리 하는게 더 싸게 먹힌다고 하더라도

그것도 다음이 있을때 이야기 인 것 같습니다.

 

그래도..

 

조금이라도 나아지려면

이런 노력들이 꼭 수반되어야 한다고 생각합니다.

 

모두 좋은 개발자가 되시기를 바라며

 

 

wh