개발을 하면서 어떠한 프로그램을 완성하기에 앞서 개발자가 해야할 중요한 일중 하나가 자신들이 만든 프로그램을 TEST(시험)하는 것이다. 사람이 만든 것은 완벽하지 못하지만 완벽을 추구하려고 노력해야한다. 완벽을 추구하는데 중요한 일이 바로 TEST이다.
프로그래밍에서 TEST는 크게 3가지로 나눌 수 있다.
- 처음부터 끝까지 모든 시스템을 Testing한다
- 웹브라우저에서 버튼,스크롤, 등등을 클릭해보면서 끝단에서 끝까지 Testing한다
- 제일 직관적이고, 제일 확인하기 쉽다
- 시간이 가장많이 소요되며 비용도 비싸다(인건비)
- API(Endpoint)에 request를 보내어 그 response를 확인하여 testing한다
- 부분 Testing 하는 것
- 부분적으로 Testing하지만, UI/End-To-End와 같이 시간과 비용이 많이 든다
- Unit단위 : 함수, 메소드
- Unit단위로 Testing한다
- Code로 Code를 Testing한다
- Testing 속도가 빠르다.
- 반복적으로 Testing 작업이 가능하다
- Unit단위 즉, 함수나 메소드 단위로 나누어 Test를 진행한다.
- 단위를 비교적 작게 함수나 메소드 단위로 testing하는 이유는 사람은 늘 실수를 할 수 있고, 실수는 실수를 낳을 수 있기때문에, 작은단위로 테스트하는 것이 더 완벽한 프로그램을 만들 수 있기 때문이다.
- 그래서 각 테스트의 unit은 반드시 독립적이여야 한다. 호출되는 순서와는 상관없이 별도로 작동해야한다.
- code로 code를 testing하는 것으로 기존에 작성한 code는 수정하지 않고 testing하는 것이 중요하다.
python 에는 unittest
라는 유닛테스트를 가능케하는 표준 라이브러리를 제공한다.
그 외 pytest
라는 패케지도 제공한다.
Python Unit Test 용어 및 개념
용어 | 개념 |
---|---|
TestCase | unit test 프레임 워크의 테스트 조직의 기본 단위 |
Fixture | 테스트를 진행할 때 필요한 테스트용 데이터 혹은 설정등을 말함. 주로 테스트가 실행되기 전이나 후에 생긴다 |
Assertion | unit test에서 테스트 하는 부분이 제대로 됬는지를 확인하는 부분. Assertion이 실패하면 테스트도 실패한다. |
[ mycalc.py ]
def add(a, b):
return a + b
def substract(a, b):
return a - b
[ test.py ]
import unittest
import mycalc
class MyCalcTest(unittest.TestCase): #unittest.TestCase를 상속받은 Test Class
def test_add(self): #test_ 라는 이름으로 시작하는 메소드는 모두 테스트 메소드가 됩니다.
c = mycalc.add(20, 10)
self.assertEqual(c, 30)
def test_substract(self):
c = mycalc.substract(20, 10)
self.assertEqual(c, 10)
if __name__ == '__main__':
unittest.main() #unittest.main() 코드를 통해 테스트가 수행됩니다.
[ python shell ]
$ python -m unittest --v
test_add (test.MyCalcTest) ... ok
test_substract (test.MyCalcTest) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
$ python test.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Test를 마치 시나리오를 구성하여 test할 필요가 있다. 예를들어 회원가입을 하고 그 회원이 로그인을 해야하는 경우, email정보를 가지고 로그인한다면 미리 회원가입을 사전준비하고 로그인하는 시나리오를 구성해야하는 것이다. 그리고 모든 시나리오가 끝나면 기록이 삭제되야 실제 이 프로그램에 영향이 끼치지 않을 것이다.
unit test는 사전준비 작업을 위해 setUp()
이라는 메서드를 지원하고 그 해당하는 Database의 기록을 삭제하기(Clean Up처리) 위해 tesrDown()
이라는 메서드를 제공한다
[ test.py ]
import unittest
class MyCalcTest(unittest.TestCase):
def setUp(self):
print("1. Executing the setUp method")
self.fixture = { 'a' : 1 }
def tearDown(self):
print("3. Executing the tearDown method")
self.fixture = None
def test_fixture(self):
print("2. Executing the test_fixture method")
self.assertEqual(self.fixture['a'], 1)
[ python shell ]
> python -m unittest --v
test_fixture (test_my_calc.MyCalcTest) ...
1. Executing the setUp method
2. Executing the text_fixture method
3. Executing the tearDown method
ok