Python의 unittest(Python Document)는 단위 테스트(unit test)를 지원하는 표준 라이브러리입니다. 단위 테스트는 코드가 예상대로 작동하는지 확인하는 테스트 하는 방식으로 테스트 작성, 실행, 검증에 필요한 기능을 제공합니다.

  • 표준화된 구조: 테스트 작성에 일관된 클래스를 사용하여 테스트의 유지보수가 용이합니다.
  • 테스트 자동화: 작성된 테스트를 한 번에 실행해 결과를 확인할 수 있습니다.
  • 테스트 결과 보고: 성공, 실패, 에러 등의 결과를 명확히 출력합니다.
  • 모듈성: 특정 테스트만 실행하거나 그룹으로 테스트를 실행할 수 있습니다.

다만 이 함수만 이용하면 모든 단위 테스트를 하기가 힘듭니다. 그래서 다음 포스트에는 고급기능 중 하나인 Mock에 대해서 좀 작성해 보겠습니다.

Unit Test Code

#pip install unittest

import unittest

class Calculator:
    def add(self, a, b):
        return a + b

    def subtract(self, a, b):
        return a - b

    def multiply(self, a, b):
        return a * b

    def divide(self, a, b):
        if b == 0:
            raise ValueError("Cannot divide by zero")
        return a / b

class PlusTest(unittest.TestCase):
    def setUp(self):
        self.calc = Calculator()

    def test_add(self):
        self.assertEqual(self.calc.add(1, 1), 2)
        self.assertNotEqual(self.calc.add(-1, 1), 1)

    def test_subtract(self):
        self.assertEqual(self.calc.subtract(10, 5), 5)

    def test_multiply(self):
        self.assertEqual(self.calc.multiply(3, 7), 21)

    def test_divide(self):
        self.assertEqual(self.calc.divide(10, 2), 5)
        with self.assertRaises(ValueError):
            self.calc.divide(10, 0)


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

"""
assertEqual(a, b) : a is b
assertNotEqual(a, b): a is not b
assertTure(x): x is true
assertIs(a, b): object a in b
assertIn(a, b): b in a
"""

주요 메서드

  • assertEqual(a, b): a == b인지 확인.
  • assertNotEqual(a, b): a != b인지 확인.
  • assertTrue(x): x가 참인지 확인.
  • assertFalse(x): x가 거짓인지 확인.
  • assertIs(a, b): a is b인지 확인.
  • assertIsNot(a, b): a is not b인지 확인.
  • assertRaises(exception, callable, ...): 예외가 발생하는지 확인.

setUp / tearDown

각 테스트 전후에 실행되는 메서드입니다. 이는 반복적으로 사용하는 리소스를 초기화하거나 정리할 때 유용합니다.

Output

....
----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK

TDD(Test Driven Development)에 대해서 개발자 분들은 대부분 동의하지만, 적극적으로 개발에 포함하시는 분은 많지는 않은 것 같습니다. 이유는 개발 속도와 효과를 체험한 사람이 많지 않아서가 아닐까 싶습니다.

시니어 또는 주니어와 같은 경험이나 지식의 문제는 아닙니다. 유지보수 앞에서 미리 계획 하느냐? 상황에 맞춰 대응 하는게 좋냐?는 개발 이외 상황과 시간등이 소요되기 때문에 쉽게 결정하기 어렵지만 대부분의 회사는 미리 계획하지는 않습니다.

이슈는 이 프로젝트가 잘될찌 잘 안될찌 예상하는 것 보다 빠르게 시장에 내놓고 반응을 보는게 정확하기 때문입니다.

짧게 제 경험을 이야기 해보겠습니다.

기능이 60개 정도 되는 30만 라인 쯤 되는 작은 제품을 개발 하고 있었습니다. 이 제품을 릴리즈 할때 한개의 기능 추가에 대해서 2주 정도의 포팅시간이 걸렸습니다. 그리고 너무 스파게티 코드로 함수명이 a_b_1 이와 같은 형태도 있었습니다.

똑같은 언어로 같은 기능을 구조 부터 모두 리뉴얼 하는데 4명의 개발자가 1년 2개월 정도의 시간이 걸렸습니다.

리뉴얼 한 제품은 코드로는 15만 라인으로 줄었고, 12,000여개의 단위 테스트를 했습니다. 그랬더니 하나의 기능 릴리즈에 대해서 포팅하는데 1~2일로 줄어들었습니다. 물론 사이드 이펙트도 모두 없었고요.

근데 개발회사에서 개발자에게 1년의 시간을 생산성없이 보내는 시간을 줄까요?

왠만한 회사에서는 경험하기 힘든 일입니다. 사실 저도 12명의 팀을 두개로 나눠서 8명의 한팀은 계속 제품을 유지하고, 나머지 4명이 회사를 설득해 진행했던 프로젝트였습니다.

아이러니 하게 유지보수가 쉬워지고 빨라지니… 이 팀에 속해 있던 대부분의 개발자는 다른팀으로 강제 전출 되었습니다. 그래도 개개인의 실력이 엄청나게 좋아져서 왜 오픈 소스 프로젝트 하는 사람이 실력이 좋은지 알게 됬습니다. (한번 개발 했던 것을 개선할 기회와 개인의 시간을 갈아넣으니 그런거겠죠?)

By Mark

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다