[python] pytest

- 5 mins

pytest

pytest는 내장 단위테스트 모듈인 unittest와 같은 단위테스트 모듈이다.

내장 모듈은 아니고, pip으로 설치해주어야한다.

$ pip install pytest

참고로 pytest는 python3 버전에서만 동작한다.

사용법을 알아보자.


우선 숫자를 받아서 2배로 리턴해주는 doubler 라는 함수를 정의해보자.

# sample_test.py


def doubler(a):
    return a * 2

이번엔 doubler 함수의 테스트 함수를 만들어보자.

# sample_test.py


def doubler(a):
    return a * 2


def test_doubler1():
    assert doubler(10) == 20

이 때, 테스트 함수의 이름은 반드시 test 를 접미사로 붙여야 한다.

또한 특이한 점은, import pytest 와 같이 따로 모듈을 import 할 필요가 없다는 점이다.

다음과 같이 pytest 명령을 통해 코드를 실행시키기만 하면 된다.

$ pytest sample_test.py
============================= test session starts ==============================
platform linux -- Python 3.6.5, pytest-4.3.0, py-1.8.0, pluggy-0.8.1
rootdir: /home/kdc, inifile:
collected 1 item

sample_test.py .                                                         [100%]

=========================== 1 passed in 0.04 seconds ===========================

1개의 item에 대한 테스트가 passed 되었다는 내용이 출력된다.

테스트 케이스를 좀 더 만들어서 실행해보자.

# sample_test.py


def doubler(a):
    return a * 2


def test_doubler1():
    assert doubler(10) == 20


def test_doubler2():
    assert doubler(50) == 100


def test_doubler3():
    assert doubler(30) == 50


def doubler_test1():
    assert doubler(100) == 200


def doubler_test2():
    assert doubler(10) == 10

테스트 케이스 4개를 더 추가했다.

실행해보자.

$ pytest sample_test.py
============================= test session starts ==============================
platform linux -- Python 3.6.5, pytest-4.3.0, py-1.8.0, pluggy-0.8.1
rootdir: /home/kdc, inifile:
collected 3 items

sample_test.py ..F                                                       [100%]

=================================== FAILURES ===================================
________________________________ test_doubler3 _________________________________

    def test_doubler3():
>       assert doubler(30) == 50
E       assert 60 == 50
E        +  where 60 = doubler(30)

sample_test.py:13: AssertionError
====================== 1 failed, 2 passed in 0.26 seconds ======================

테스트 케이스를 총 5개 만들었는데, 3개의 아이템만 수집된 것을 볼 수 있다. (collected 3 items)

마지막 2개의 테스트 케이스는 함수명이 test 로 시작하지 않기때문에 pytest에서 인식하지 못한것이다.

그리고 test_doubler3 에서 에러가 발생했는데, 단순히 에러가 난 것이 아니라 상세한 결과를 출력해주고있다.

doubler(30) 의 기대값을 50으로 설정했었는데, 실제로는 60이 리턴되었다는 메시지가 출력되고있다.

pytest 를 쓰지 않고, 다음과 같이 코드를 추가해서 그냥 python 명령으로 실행해보면 차이를 알 수 있다.

# sample_test.py


def doubler(a):
    return a * 2


def test_doubler1():
    assert doubler(10) == 20


def test_doubler2():
    assert doubler(50) == 100


def test_doubler3():
    assert doubler(30) == 50


def doubler_test1():
    assert doubler(100) == 200


def doubler_test2():
    assert doubler(10) == 10


if __name__ == "__main__":
    test_doubler1()
    test_doubler2()
    test_doubler3()
    doubler_test1()
    doubler_test2()

테스트 함수를 직접 실행하도록 코드를 추가했다.

실행해보자.

$ python sample_test.py
Traceback (most recent call last):
  File "sample_test.py", line 25, in <module>
    test_doubler3()
  File "sample_test.py", line 13, in test_doubler3
    assert doubler(30) == 50
AssertionError

실제 어떤 값이 리턴됐다거나 하는 디테일한 정보는 빠지고,

단순히 에러가 났다는 메시지를 출력하고 종료된다.


pytest는 unittest와 달리 모듈의 특정 함수를 사용하지 않고 간단하게 테스트코드를 작성할 수 있다는 장점이 있다.

unittest였다면 다음과 같이 코드를 작성해야 했을 것이다.

# sample_test.py
import unittest


def doubler(a):
    return a * 2


class DoublerTest(unittest.TestCase):
    def test_doubler1(self):
        self.assertEqual(doubler(10), 20)

    def test_doubler2(self):
        self.assertEqual(doubler(50), 100)

    def test_doubler3(self):
        self.assertEqual(doubler(30), 50)

    def doubler_test1(self):
        self.assertEqual(doubler(100), 200)

    def doubler_test2(self):
        self.assertEqual(doubler(10), 10)


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

다시 pytest를 이용한 테스트코드를 보면서 차이를 비교해보자.

# sample_test.py


def doubler(a):
    return a * 2


def test_doubler1():
    assert doubler(10) == 20


def test_doubler2():
    assert doubler(50) == 100


def test_doubler3():
    assert doubler(30) == 50


def doubler_test1():
    assert doubler(100) == 200


def doubler_test2():
    assert doubler(10) == 10

unittest의 경우 unittest.TestCase, assertEqual, unittest.main() 같은 함수를 따로 알고있어야한다는 번거로움이 있다.

하지만 assert* 함수를 이용해 좀 더 테스트 의도를 명시적으로 드러낼 수 있다는 장점도 있다.

또한, 내장 모듈이기 때문에 따로 설치하지 않고 작성할 수 있다는 것도 장점이라면 장점이다.

참고로, unittest도 테스트 함수의 이름은 test 로 시작해야한다.

unittest 모듈의 보다 자세한 사용법은 여기 에 따로 포스팅 해두었으니, 참고하면 될 것 같다.




코딩장이

코딩장이

-장이: [접사] ‘그것과 관련된 기술을 가진 사람’의 뜻을 더하는 접미사.

rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora