본문 바로가기
Python

Python unittest 사용하기

by holy season 2023. 5. 16.
반응형

unittest 란?

unittest는 '단위 테스트 프레임워크'이며 JUnit으로부터 영감을 받고 다른 언어의 주요 단위 테스트 프레임워크와 비슷한 특징을 가지고 있다.

unittest는 테스트 자동화, 테스트를 위한 사전 설정(setup)과 종료(shutdown) 코드 공유, 테스트를 컬렉션에 종합하기, 테스트와 리포트 프레임워크등의 분리등을 지원한다.

객체 지향적인 방법으로 몇 가지 중요한 개념을 지원

테스트 픽스쳐(test fixture)

1개 또는 그 이상의 테스트를 수행할 때 필요한 준비와 그와 관련된 정리 동작에 해당

임시 또는 프락시 데이터베이스, 디렉터리를 생성하거나 서버 프로세스를 시작하는 것 등을 포함

테스트 케이스(test case)

테스트 케이스의 개별단위이며 특정한 입력 모음에 대해서 특정한 결과를 확인하는 데 사용한다.

unittest는 새로운 테스트 케이스를 만드는데 사용되는 베이스 클래스인 TestCase를 지원한다.

테스트 묶음(test suite)

여러 테스트 케이스, 테스트 묶음, 둘 다의 모임

서로 같이 실행 되어야 할 테스트들을 종합하는 데 사용된다.

테스트 실행자(test runner)

테스트 실행을 조율하고 테스트 결과를 사용자에게 제공하는 역할을 하는 컴포넌트

 

참고 사이트

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

 

unittest — Unit testing framework

Source code: Lib/unittest/__init__.py(If you are already familiar with the basic concepts of testing, you might want to skip to the list of assert methods.) The unittest unit testing framework was ...

docs.python.org

테스트 케이스(test case) 작성하기

unittest  라이브러리 임포트

테스트 케이스를 생성하기 위해서는 먼저 unittest 라이브러리를 불러와야 한다.

unittest 라이브러리를 불러는 명령어는 다음과 같다.

import unittest

unittest.TestCase 클래스를 상속받는 테스트 케이스 생성하기

테스트 케이스를 작성하려면 unittest.TestCase를 상속받는 클래스를 생성하여야 한다.

파이썬에서 unittest.TestCase를 상속받는 클래스를 생성하는 방법은 다음과 같다.

class 클래스명(unittest.TestCase):

테스트 픽스쳐 설정하기

unittest.TestCase 클래스를 상속받는 클래스를 생성하였다면 테스트를 하기 위한 사전 준비를 해야 한다.

unittest 프레임워크에서는 setUP() 메서드와 tearDown() 메서드로 사전준비를 할 수 있다.

이 두 메서드는 각각의 테스트가 실행되기 전(setUp), 실행되고 난 후 (tearDown) 메서드가 호출된다.

setUp() 메서드가 실행 중에 예외를 발생시킨다면 프레임워크는 테스트에 오류가 있는 것으로 간주하여 테스트 메서드를 실행하지 않는다.

따라서 setUp() 메서드를 예외가 나지 않게 잘 만드는 것이 중요하며 테스트 픽스쳐를 다음과 같이 만들 수 있다.

class SimpleTest(unittest.TestCase):
    # 테스트 픽스쳐 setUp
    def setUp(self):
        print('setUp! 테스트 시작!')
        self.a = 1
        self.b = 2

    # 테스트 픽스쳐 tearDown
    def tearDown(self):
        print('tearDown! 테스트 종료!')

이 테스트 케이스로 테스트를 진행하면 테스트를 진행할 메서드를 선언하지 않았기 때문에 아무 테스트도 진행하지 않는다.

테스트할 메서드 만들기

unittest.TestCase 클래스를 상속받은 테스트 케이스 클래스는 기본적으로 함수 이름을 'test_'로 시작해 함수명을 작성하면 테스트 메서드로 등록이 된다.

따라서 테스트 픽스쳐 setUp 메서드로 선언해둔 a와 b의 합과 차를 테스트 해보는 테스트 메서드를 작성해 보았다.

class SimpleTest(unittest.TestCase):
    # 테스트 픽스쳐 setUp
    def setUp(self):
        print('setUp! 테스트 시작!')
        self.a = 1
        self.b = 2

    def test_add(self):
        self.assertEqual(self.a + self.b, 3)

    def test_sub(self):
        self.assertEqual(self.a - self.b, 1, 'incorrect sub value!')

    # 테스트 픽스쳐 tearDown
    def tearDown(self):
        print('tearDown! 테스트 종료!')

실행 결과로 다음과 같은 화면이 나왔는데 테스트가 2번 실행되었고 테스트 마다 setUp(), tearDown() 메서드가 호출되었다.

self.assertEqaul() 메서드의 인자로 결과값, 예상되는 값[, 에러 메시지]를 넣어 테스트를 한 결과

성공 했을 경우 ok 실패 했을 경우 FAIL이 뜨며 assertEqual 메서드에 넣은 에러 메시지가 나타나게 된다.

테스트 실행하기

테스트를 실행하는 방법은 간단하게 다음과 같이 할 수 있다.

verbosity는 테스트 케이스의 상세도 이며 1일 경우에는 간단하게 표시, 2일 경우에는 어느 테스트 메서드를 실행하는지 알려준다.

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

테스트 케이스를 다른 파일에 작성하고 불러와서 테스트를 하고 싶은 경우 테스트 실행자테스트 묶음을 사용해서 테스트를 진행할 수 있다.

테스트 묶음 생성

테스트 묶음은 unittest의 TestSuite() 클래스를 사용해 생성 할 수 있으며 만들어진 TestSuite() 객체에 addTest를 하여 여러개의 테스트를 추가해서 테스트를 할 수 있다.

def suite():
    import testCases
    suite = unittest.TestSuite()

    # Crawling 전체 테스트
    # crawlingTestCase = unittest.makeSuite(testCases.CrawlingTest)
    # suite.addTest(crawlingTestCase)
    
    # 특정 테스트 추가
    suite.addTest(testCases.CrawlingTest('test_playAllUri_length'))

    return suite

unittest의 makeSuite() 메서드는 Python 3.13 버전에서 사라지게 된다는 오류가 나타나는데 이것을 해결하기 위한 방법으로는 unittest의 TestLoader() 클래스를 사용하는 것이다.

unittest.TestLoader() 객체를 생성하고 TestLoader 클래스의 메서드인 loadTestsFromTestCase() 메서드를 사용해 전체 테스트를 진행할 수 있다.

# 테스트 슈트 생성
def suite():
    import testCases
    suite = unittest.TestSuite()

	# testCases.py의 CrawlingTest 전체 테스트
    loader = unittest.TestLoader()
    crawlingTestCase = loader.loadTestsFromTestCase(testCases.CrawlingTest)
    suite.addTest(crawlingTestCase)
    
    return suite

테스트를 진행하여도 DeprecationWarning이 나오지 않는다.

테스트 실행자 작성

테스트 실행자는 다음과 같이 unittest의 TextTestRunner 클래스를 사용해 실행자를 생성할 수 있으며 unittest의 main과 같이 상세도 설정을 할 수 있다.

그러고 테스트 실행자의 run() 메서드를 호출하면 테스트 묶음의 테스트가 실행이 된다.

if __name__ == "__main__":

    # 테스트
    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite())

 

 

반응형

'Python' 카테고리의 다른 글

사용자 폴더 위치  (0) 2023.06.01
PySide6로 GUI 구성하기  (0) 2023.05.18
파이썬 실행파일(.exe) 파일 만들기  (0) 2023.05.11
tkinter로 화면 만들기  (0) 2023.05.10
Python venv 가상환경 생성 오류  (1) 2023.05.09