1. 유닛테스트
Python 에서 유닛 테스트를 수행하기 위해 기본적으로 제공되는 unittest 모듈 (Unit testing framework)을 사용할 수 있다. 유닛 테스트 코드를 작성하기 위해서는 일반적으로 다음과 같은 절차를 따른다.
- 먼저 unittest 모듈을 import 한 후,
- "unittest.TestCase"로부터 파생된 사용자 테스트 클래스를 만든다.
- 테스트 클래스 안에 "test" 로 시작하는 테스트 메서드를 생성한다. 테스드 메서드에서는 일반적으로 테스트하고자 하는 함수나 메서드를 호출하고 그 결과값을 self.assert*() 메서드를 사용하여 확인한다 (assertEqual, assertTrue, assertFalse, assertRaises, assertRegex 등 다양한 assert 메서들을 사용할 수 있다).
- 테스트 클래스가 완성되었으면, unittest.main()을 호출하여 테스트를 실행시킨다.
예를 들어, myCalc.py 라는 파일 안에 아래 두 함수가 있다고 가정하고, 이 함수들에 대한 유닛 테스트를 작성해 보자.
# myCalc.py def add(a, b): return a + b def substract(a, b): return a - b
아래는 유닛 테스트를 위한 코드로서 unittest.TestCase 로부터 파생된 MyCalcTest 클래스를 작성하였다. 그리고, test_add 와 test_substract 테스트 메서드를 작성하였고, 그 안에서 myCalc 함수를 실행한 결과를 self.assertEqual()를 사용하여 검사하였다. 마지막 라인에 unittest.main() 이 실행되면, 테스트 메서드들이 실행되게 된다.
# tests.py import unittest import myCalc class MyCalcTest(unittest.TestCase): def test_add(self): 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()
![](/images/basics/unittest.png)
파이썬 unittest는 위 그림 하단 좌측에서 보듯이, 전체 스크립트 단위, 테스트 클래스 단위 또는 메서드/함수 단위로 실행할 수 있다.
2. Test Fixture
테스트 시나리오에 따라 어떤 경우는 테스트 전에 테스트를 위한 사전 준비 작업을 할 필요가 있다. 또한 테스트가 끝난 후 Clean up을 해야하는 경우도 있을 수 있다. unittest는 이렇게 사전 준비 작업을 위해 setUp() 이라는 메서드를, 사후 Clean up 처리를 위해 tearDown() 이라는 메서드를 사용할 수 있도록 있다. 이러한 setUp, tearDown 기능을 Test Fixture라 하며, Fixture는 각각의 테스트 메서드가 실행되기 전과 후에 매번 실행된다.
예를 들어, 아래와 같은 간단한 유틸러티 모듈(myUtil.py)이 있다고 하고, 이에 대한 유닛 테스트를 진행한다고 가정해 보자.
# myUtil.py import os def filelen(filename): f = open(filename, "r") f.seek(0, os.SEEK_END) return f.tell() def count_in_file(filename, char_to_find): count = 0 f = open(filename, "r") for word in f: for char in word: if char == char_to_find: count += 1 return count
아래 MyUtilTest 라는 유닛 테스트 클래스는 test_filelen(), test_count_in_file() 두 개의 테스트 메서드를 가지고 있다. 이들 각각의 테스트 메서드가 실행되기 전에 항상 setUp() 메서드가 실행되어 테스트 파일을 생성하고, 테스트 실행후 tearDown() 메서드가 실행하여 사용한 테스트 파일을 지우게 된다.
import unittest import os import myUtil class MyUtilTest(unittest.TestCase): testfile = 'test.txt' # Fixture def setUp(self): f = open(MyUtilTest.testfile, 'w') f.write('1234567890') f.close() def tearDown(self): try: os.remove(MyUtilTest.testfile) except: pass def test_filelen(self): leng = myUtil.filelen(MyUtilTest.testfile) self.assertEqual(leng, 10) def test_count_in_file(self): cnt = myUtil.count_in_file(MyUtilTest.testfile, '0') self.assertEqual(cnt, 1) if __name__ == '__main__': unittest.main()