Python - 13. 코드 품질과 테스팅
2025. 1. 20. 00:30ㆍ프로그래밍 언어/Python
코드 품질과 테스팅은 안정적이고 유지보수 가능한 소프트웨어를 개발하기 위한 필수적인 과정입니다. 이번 섹션에서는 Python에서 제공하는 도구와 기법을 통해 코드 품질을 높이고, 효율적으로 디버깅 및 성능을 분석하는 방법을 다룹니다.
13.1 타입 힌트와 애너테이션
타입 힌트(Type Hint)
Python은 동적 타입 언어이지만, 타입 힌트를 사용하여 변수와 함수의 타입을 명시할 수 있습니다.
기본 예제
def greet(name: str) -> str:
return f"Hello, {name}!"
name: str = "Alice"
print(greet(name))
Generic 타입
Generic 타입은 컬렉션의 요소 타입을 명시할 때 사용합니다.
from typing import List, Dict
def sum_numbers(numbers: List[int]) -> int:
return sum(numbers)
data: Dict[str, int] = {"Alice": 30, "Bob": 25}
print(sum_numbers([1, 2, 3])) # 6
Union과 Optional
- Union: 여러 타입을 허용
- Optional: 특정 타입 또는 None 허용
from typing import Union, Optional
def parse_value(value: Union[int, str]) -> str:
return str(value)
def get_name(name: Optional[str] = None) -> str:
return name if name else "Unknown"
print(parse_value(42)) # "42"
print(get_name()) # "Unknown"
TypeVar
TypeVar를 사용하여 제네릭 함수나 클래스를 정의할 수 있습니다.
from typing import TypeVar, List
T = TypeVar("T")
def get_first_element(elements: List[T]) -> T:
return elements[0]
print(get_first_element([1, 2, 3])) # 1
print(get_first_element(["a", "b", "c"])) # "a"
13.2 단위 테스트 (unittest)
unittest란?
unittest는 Python 표준 라이브러리로 제공되는 단위 테스트 프레임워크입니다.
기본 사용법
import unittest
class TestMathOperations(unittest.TestCase):
def test_addition(self):
self.assertEqual(2 + 3, 5)
def test_subtraction(self):
self.assertEqual(5 - 3, 2)
if __name__ == "__main__":
unittest.main()
실행 결과
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
13.3 pytest 활용
pytest란?
pytest는 간결하고 확장 가능한 Python 테스팅 프레임워크입니다.
설치
pip install pytest
기본 사용법
- 테스트 파일 이름은 test_로 시작하거나 _test로 끝나야 합니다.
- 테스트 함수는 test_로 시작해야 합니다.
def test_addition():
assert 2 + 3 == 5
def test_subtraction():
assert 5 - 3 == 2
pytest fixture
Fixture는 테스트 전에 필요한 환경을 설정하거나 초기 데이터를 제공합니다.
import pytest
@pytest.fixture
def sample_data():
return [1, 2, 3]
def test_sum(sample_data):
assert sum(sample_data) == 6
테스트 케이스 그룹화
class TestMathOperations:
def test_addition(self):
assert 2 + 2 == 4
def test_subtraction(self):
assert 5 - 3 == 2
Mock 활용
pytest-mock 패키지를 사용하여 모의 객체를 생성하고 동작을 테스트할 수 있습니다.
from unittest.mock import MagicMock
def test_mock_example():
mock = MagicMock(return_value=10)
assert mock() == 10
13.4 디버깅 기법
print()를 활용한 디버깅
코드 실행 중 특정 값을 출력하여 상태를 확인합니다.
pdb 모듈
Python의 기본 디버거로, 중단점 설정 및 단계별 실행을 지원합니다.
import pdb
def faulty_function(x):
pdb.set_trace()
return x + 1
faulty_function(5)
디버깅 툴
- IDE 디버거: PyCharm, VSCode 등에서 제공하는 디버깅 도구 활용
13.5 코드 최적화와 성능
코드 최적화 원칙
- 불필요한 반복 제거
- 적합한 자료구조 사용
- 효율적인 알고리즘 선택
예제: 리스트 컴프리헨션 활용
# 비효율적
result = []
for i in range(10):
result.append(i ** 2)
# 효율적
result = [i ** 2 for i in range(10)]
13.6 프로파일링과 벤치마킹
프로파일링
프로파일링은 코드의 실행 시간과 자원 사용을 분석하여 병목 지점을 파악합니다.
- cProfile 사용
import cProfile
def example():
total = 0
for i in range(100000):
total += i
return total
cProfile.run('example()')
- 메모리 프로파일링 memory_profiler를 사용하여 메모리 사용량을 분석합니다.
pip install memory_profiler
from memory_profiler import profile
@profile
def memory_intensive_function():
data = [i ** 2 for i in range(100000)]
return data
memory_intensive_function()
벤치마킹
벤치마킹은 코드의 성능을 비교하여 최적화를 평가합니다.
- timeit 모듈 사용
import timeit
setup = "nums = list(range(1000))"
stmt = "sum(nums)"
print(timeit.timeit(stmt, setup=setup, number=1000))
복잡도 분석
코드의 시간 복잡도와 공간 복잡도를 분석하여 최적화합니다.
def find_max(nums):
max_num = nums[0]
for num in nums:
if num > max_num:
max_num = num
return max_num
# O(n) 시간 복잡도
이번 섹션에서는 Python의 코드 품질 향상 및 테스팅 기법을 다뤘습니다.
'프로그래밍 언어 > Python' 카테고리의 다른 글
Python - 15. 실전 프로젝트 (0) | 2025.01.20 |
---|---|
Python - 14. 보안과 암호화 (0) | 2025.01.20 |
Python Tkinter - 2. 레이아웃 관리와 고급 이벤트 처리 (0) | 2025.01.20 |
Python - 12. 동시성과 병렬 처리 (0) | 2025.01.20 |
Python Tkinter - 1. 소개와 기본 위젯 (0) | 2025.01.20 |