Skip to content

2.21. 내용정리: 24일차

흔한 찐따 edited this page Apr 17, 2022 · 2 revisions

단위 테스트 (Unit Test)

  • 단위 테스트(유닛 테스트; unit test) 는 컴퓨터 프로그래밍에서 소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차다.
  • 즉, 모든 함수와 메소드에 대한 테스트 케이스(Test case)를 작성하는 절차를 말한다.
  • 이를 통해서 언제라도 코드 변경으로 인해 문제가 발생할 경우, 단시간 내에 이를 파악하고 바로 잡을 수 있도록 해준다.
  • 이상적으로, 각 테스트 케이스는 서로 분리되어야 한다. 이를 위해 가짜 객체(Mock object)를 생성하는 것도 좋은 방법이다.
  • 유닛 테스트는 (일반적인 테스트와 달리) 개발자(developer) 뿐만 아니라 보다 더 심도있는 테스트를 위해 테스터(tester)에 의해 수행되기도 한다.

단위 테스트를 하는 이유

  • 프로그래밍을 하는데 있어 효율적이고 생산성이 높은 테스트 방식이다.
  • 코드의 작은 부분들(ex. 함수)이 잘 동작하는지 테스트하기 때문에 대규모 프로젝트에서 많이 사용되는 방식이다.
  • 따라서 수많은 오픈 소스 프로젝트에서도 단위 테스트 방식을 사용하고 있다.

파이썬에서 단위 테스트 사용하기

파이썬에서도 단위 테스트를 지원한다.

unittest

기본 예시

  • unittest 라이브러리는 테스트를 구성하고 실행하는 데 풍부한 도구 모음을 제공하고 있다.
  • 아래는 문자열에 관련된 3개의 메서드를 테스트하기 위한 간단한 예시이다.
  • 파이썬 공식 문서의 unittest — 기본 예시 예시를 참고하였다.
import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()
  • 테스트 케이스는 unittest.TestCase 를 서브 클래스 해서 생성하였다.
  • 각각 3개의 테스트는 test 글자로 시작하는 이름을 가진 메서드로 정의했다.
  • 이 명명 규칙은 테스트 실행자가 어떤 메서드가 테스트인지 알게 해준다.
  • 각 테스트의 핵심은 기대되는 결과를 확인하기 위해 assertEqual() 를 호출한다.
  • 조건을 검증하기 위해 assertTrue() 또는 assertFalse() 를 호출한다.
  • 특정 예외가 발생했는지 검증하기 위해 assertRaises() 를 호출하는 것이다.
  • assert 문장을 대신하여 이 메서드들을 사용하면 테스트 실행자가 모든 테스트 결과를 취합하여 리포트를 생성할 수 있다.
  • setUp()tearDown() 메서드로 각각의 테스트 메서드 전과 후에 실행될 명령어를 정의할 수 있다.
  • 마지막 블록은 테스트를 실행하는 간단한 방법을 보여준다.
  • unittest.main() 은 테스트 스크립트에 명령행 인터페이스를 제공한다.
  • 명령행에서 위 스크립트를 실행하면, 다음과 같은 출력이 나온다.

결과

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

-v 옵션을 테스트 스크립트에 넘겨주게 되면 unittest.main() 은 높은 상세도(verbosity)를 설정하여 그에 따른 출력이 나온다.

test_isupper (__main__.TestStringMethods) ... ok
test_split (__main__.TestStringMethods) ... ok
test_upper (__main__.TestStringMethods) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

pytest

  • pytest 라이브러리는 테스트를 작성하기에 간편한 문법을 가지고 있는 제삼자의 단위 테스트 프레임워크이다.
  • 파이썬 표준 라이브러리인 unittest 모듈에 대한 단위 테스트용 비표준 대안 라이브러리이다.
  • 표준 라이브러리가 아닌 비표준 라이브러리이지만, 여러 파이썬 오픈 소스 프로젝트에서 사용되고 있는 라이브러리이다.
  • pytest 라이브러리는 파이썬 표준 라이브러리인 unittest 를 기반으로 만들어진 라이브러리이다.
  • 따라서 unittest 라이브러리보다 더 많은 기능들을 제공하고 있다.
  • pytest 라이브러리에 대한 좀 더 자세한 설명을 참고하려면 pytest 공식 문서 를 참고하면 된다.
  • 먼저, pytest 를 사용하기 위해서는 명령 프롬프트에 pip 명령어를 통해 설치해야 한다.
    • 설치 명령어: pip install pytest

예시

  • 먼저, test_sample.py 라는 파이썬 파일을 생성한다.
  • 그 다음, 다음과 같이 함수 func 을 정의한다.
def func(x):
    return x + 1
  • 그 다음, 함수명 앞이나 뒤에 test_ 혹은 _test 를 붙여서 테스트를 위한 함수를 정의한다.
def test_answer():
    assert func(3) == 5
  • 결과를 확인하려면 명령 프롬프트에 pytest -v test_sample.py 를 입력하면 된다.
  • 여기서 -v 옵션을 주면 아래의 결과처럼 좀 더 자세한 정보를 확인할 수 있다.
  • 결과는 아래와 같다.

결과

test_sample.py::test_answer FAILED                                                                               [100%]

====================================================== FAILURES =======================================================
_____________________________________________________ test_answer _____________________________________________________

    def test_answer():
>       assert func(3) == 5
E       assert 4 == 5
E        +  where 4 = func(3)

test_sample.py:7: AssertionError
=============================================== short test summary info ===============================================
FAILED test_sample.py::test_answer - assert 4 == 5
================================================== 1 failed in 0.45s ==================================================
  • 즉, 테스트의 결과값이 5가 나오지 않고 4가 나왔다는 것을 확인할 수 있다.
  • 파이썬 표준 라이브러리인 unittest 를 통해 테스트하는 방법과 pytest 를 통해 사용하는 방법 모두 동일하다.
  • 하지만 pytest 는 파이썬 표준 라이브러리인 unittest 보다 지원하는 기능이 더 많다.
  • 뿐만 아니라, 여러 오픈 소스 프로젝트에서도 사용되고 있어서 권장되고 있는 방식이다.