웹사이트 검색

Python unittest - 단위 테스트 예제


오늘은 파이썬 단위 테스트에 대해 알아보고 파이썬 단위 테스트 예제 프로그램을 살펴보겠습니다. 이전 튜토리얼에서 파이썬 zip 기능에 대해 배웠습니다.

파이썬 단위 테스트

Python unittest 모듈은 소스 코드 단위를 테스트하는 데 사용됩니다. 프로젝트를 테스트해야 한다고 가정해 보겠습니다. 함수가 반환할 데이터의 종류를 알고 있습니다. 거대한 코드를 작성한 후에는 출력이 올바른지 여부를 확인해야 합니다. 일반적으로 우리가 하는 일은 출력을 인쇄하고 참조 출력 파일과 일치시키거나 출력을 수동으로 확인하는 것입니다. 이 고통을 줄이기 위해 Python은 unittest 모듈을 도입했습니다. 이 모듈을 사용하면 몇 가지 간단한 코드로 함수의 출력을 확인할 수 있습니다. 이 튜토리얼에서는 Python unittest 모듈의 기본 사용법에 대해 논의하고 클래스 함수를 테스트하기 위해 몇 가지 Python 단위 테스트 사례를 작성합니다.

Python 단위 테스트 예제 소스

우선 단위 테스트를 위한 코드를 작성해야 합니다. 우리는 Python 수업을 듣게 될 것입니다. 클래스의 주요 목적은 사람의 이름을 저장하고 검색하는 것입니다. 따라서 데이터를 저장하는 set_name() 함수와 클래스에서 이름을 검색하는 get_name() 함수를 작성합니다.

class Person:
    name = []

    def set_name(self, user_name):
        self.name.append(user_name)
        return len(self.name) - 1

    def get_name(self, user_id):
        if user_id >= len(self.name):
            return 'There is no such user'
        else:
            return self.name[user_id]


if __name__ == '__main__':
    person = Person()
    print('User Abbas has been added with id ', person.set_name('Abbas'))
    print('User associated with id 0 is ', person.get_name(0))

클래스 파일의 이름을 Person.py로 지정했습니다. 그리고 위 코드의 출력은 아래와 같습니다.

$ python3.6 Person.py 
User Abbas has been added with id  0
User associated with id 0 is  Abbas
$

파이썬 단위 테스트 구조

이제 단위 테스트를 위한 코딩 방법을 알아보겠습니다. 개별 테스트 케이스는 unittest.TestCase를 서브클래싱하여 생성됩니다. 적절한 함수를 재정의하거나 추가하여 테스트에 논리를 추가할 수 있습니다. 다음 코드는 a가 b와 같으면 성공합니다.

import unittest


class Testing(unittest.TestCase):
    def test_string(self):
        a = 'some'
        b = 'some'
        self.assertEqual(a, b)

    def test_boolean(self):
        a = True
        b = True
        self.assertEqual(a, b)

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

python unittest 모듈을 실행하는 방법

Python 단위 테스트 결과 및 기본 기능

이 단위 테스트에는 3가지 가능한 결과가 있습니다. 아래에 언급되어 있습니다.

  1. OK: 모든 테스트 사례가 통과되면 출력에 OK가 표시됩니다.
  2. 실패: 테스트 사례 중 하나라도 실패하여 AssertionError 예외가 발생한 경우
  3. 오류: AssertionError 예외 이외의 예외가 발생한 경우

unittest 모듈에는 여러 기능이 있습니다. 아래에 나열되어 있습니다.

Method Checks that
assertEqual(a,b) a==b
assertNotEqual(a,b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a,b) a is b
assertIs(a,b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)

파이썬 단위 테스트 예제

이제 소스 클래스 Person에 대한 단위 테스트를 작성할 시간입니다. 이 클래스에서 우리는 get_name()set_name()의 두 가지 함수를 구현했습니다. 이제 unittest를 사용하여 해당 기능을 테스트합니다. 그래서 우리는 이 두 가지 기능에 대해 두 가지 테스트 사례를 설계했습니다. 다음 코드를 보면 쉽게 이해할 수 있습니다.

import unittest

# This is the class we want to test. So, we need to import it
import Person as PersonClass


class Test(unittest.TestCase):
    """
    The basic class that inherits unittest.TestCase
    """
    person = PersonClass.Person()  # instantiate the Person Class
    user_id = []  # variable that stores obtained user_id
    user_name = []  # variable that stores person name

    # test case function to check the Person.set_name function
    def test_0_set_name(self):
        print("Start set_name test\n")
        """
        Any method which starts with ``test_`` will considered as a test case.
        """
        for i in range(4):
            # initialize a name
            name = 'name' + str(i)
            # store the name into the list variable
            self.user_name.append(name)
            # get the user id obtained from the function
            user_id = self.person.set_name(name)
            # check if the obtained user id is null or not
            self.assertIsNotNone(user_id)  # null user id will fail the test
            # store the user id to the list
            self.user_id.append(user_id)
        print("user_id length = ", len(self.user_id))
        print(self.user_id)
        print("user_name length = ", len(self.user_name))
        print(self.user_name)
        print("\nFinish set_name test\n")

    # test case function to check the Person.get_name function
    def test_1_get_name(self):
        print("\nStart get_name test\n")
        """
        Any method that starts with ``test_`` will be considered as a test case.
        """
        length = len(self.user_id)  # total number of stored user information
        print("user_id length = ", length)
        print("user_name length = ", len(self.user_name))
        for i in range(6):
            # if i not exceed total length then verify the returned name
            if i < length:
                # if the two name not matches it will fail the test case
                self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
            else:
                print("Testing for get_name no user test")
                # if length exceeds then check the 'no such user' type message
                self.assertEqual('There is no such user', self.person.get_name(i))
        print("\nFinish get_name test\n")


if __name__ == '__main__':
    # begin the unittest.main()
    unittest.main()

unittest 모듈은 정의된 순서가 아니라 이름 순서대로 테스트 함수를 실행합니다. 그리고 우리는 set_name 테스트가 먼저 실행되기를 원하기 때문에 테스트 사례 함수의 이름을 test_0_set_nametest_1_get_name으로 지정했습니다.

Python 단위 테스트 예제 출력

$ python3.6 -m unittest -v PersonTest.Test
test_0_set_name (PersonTest.Test) ... Start set_name test

user_id length =  4
[0, 1, 2, 3]
user_name length =  4
['name0', 'name1', 'name2', 'name3']

Finish set_name test

ok
test_1_get_name (PersonTest.Test) ... 
Start get_name test

user_id length =  4
user_name length =  4
Testing for get_name no user test
Testing for get_name no user test

Finish get_name test

ok

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
$

Python unittest 튜토리얼에 관한 모든 것입니다. 자세한 내용은 공식 문서를 참조하세요. 추가 문의사항은 댓글란을 이용해주세요. :)