Pytest로 자동화된 Python 모듈 테스트 방법

2024. 11. 12. 21:49 개발 이야기/python

APM Python 에이전트를 개발하면서 자동화된 테스트를 어떻게 구성할지 고민해 본 적 있으신가요? 특히 Auto Instrumentation 기능을 제공하는 에이전트라면 다양한 Python 모듈과 버전 호환성을 테스트하는 것이 매우 중요합니다. 이번 포스팅에서는 Pytest를 활용해 모듈의 버전별, Python 버전별 테스트를 자동화하는 방법을 소개합니다.

1. Pytest를 선택한 이유

Pytest는 그 강력한 기능과 간편한 사용법 덕분에 Python 개발자들에게 사랑받는 테스트 프레임워크입니다. 다양한 기능 확장, 뛰어난 플러그인 생태계, 직관적인 테스트 케이스 작성 등을 통해 자동화된 테스트 환경을 쉽게 구축할 수 있습니다. 특히 APM 에이전트와 같은 복잡한 프로젝트에서는 다양한 상황을 빠르고 효율적으로 테스트하는 데 적합합니다.

2. 다양한 테스트 환경 설정하기

APM 에이전트는 다양한 Python 버전 및 여러 서드파티 모듈을 지원해야 합니다. 이를 위해 Pytest와 tox를 조합하여 다양한 환경에서 테스트를 실행하는 방법을 사용합니다.

tox를 이용한 다중 파이썬 버전 테스트

tox는 여러 파이썬 버전과 의존성을 쉽게 관리하며 테스트를 실행할 수 있게 도와주는 도구입니다. 이를 통해 Python 3.6부터 3.11까지 여러 버전에서 APM 에이전트를 테스트할 수 있습니다. 아래는 간단한 tox.ini 예시입니다:

[tox]
envlist = py36, py37, py38, py39, py310, py311

[testenv]
deps =
    pytest
    requests  # 테스트할 모듈
commands =
    pytest tests/

이 설정을 통해 다양한 Python 버전에서 자동으로 테스트를 실행할 수 있습니다. 이를 통해 특정 Python 버전에서만 발생하는 이슈를 빠르게 파악하고 해결할 수 있습니다.

3. Pytest-parametrize를 활용한 모듈 버전 테스트

APM 에이전트는 여러 모듈을 자동으로 계측하기 때문에, 각 모듈의 다양한 버전을 지원해야 합니다. 이때 Pytest의 parametrize 기능을 사용하면 모듈 버전별 테스트를 간편하게 작성할 수 있습니다.

import pytest
import requests

@pytest.mark.parametrize("requests_version", ["2.23.0", "2.25.1", "2.28.0"])
def test_requests_instrumentation(requests_version):
    # 특정 버전의 requests 설치
    subprocess.run(["pip", "install", f"requests=={requests_version}"])
    
    # APM 에이전트 초기화 및 계측 테스트
    from my_apm_agent import initialize_agent
    initialize_agent()
    
    response = requests.get("https://example.com")
    assert response.status_code == 200

이 코드에서는 requests 모듈의 다양한 버전에서 APM 에이전트의 계측이 정상적으로 작동하는지 테스트합니다. 이를 통해 모듈 버전에 따른 호환성 문제를 미리 점검할 수 있습니다.

4. Pytest로 다양한 테스트 작성하기

다양한 상황에서 테스트를 수행하기 위해 Pytest를 활용한 몇 가지 예시를 추가로 소개합니다.

4.1. 예외 처리 테스트

APM 에이전트는 예외가 발생하는 경우에도 정상적으로 작동해야 합니다. Pytest를 사용하여 예외 발생 상황을 테스트할 수 있습니다.

import pytest


def test_exception_handling():
    from my_apm_agent import initialize_agent, capture_exception
    initialize_agent()
    
    try:
        1 / 0  # ZeroDivisionError 발생
    except ZeroDivisionError as e:
        capture_exception(e)
    
    # 예외가 정상적으로 캡처되었는지 확인하는 로직 추가
    assert True  # 실제로는 로그나 전송 여부를 확인하는 로직이 필요

4.2. 성능 테스트

에이전트가 애플리케이션 성능에 미치는 영향을 최소화해야 하기 때문에, 간단한 성능 테스트를 작성하여 확인할 수 있습니다.

import time


def test_agent_performance():
    from my_apm_agent import initialize_agent
    initialize_agent()
    
    start_time = time.time()
    for _ in range(1000):
        # 임의의 로직 실행 (예: HTTP 요청 모사)
        pass
    end_time = time.time()
    
    execution_time = end_time - start_time
    assert execution_time < 1  # 1000번의 반복이 1초 이내에 끝나야 함

4.3. 통합 테스트

다양한 모듈과의 통합을 테스트하여 에이전트가 전체 시스템에서 올바르게 작동하는지 확인합니다.

import pytest
from flask import Flask

@pytest.fixture
def flask_app():
    app = Flask(__name__)

    @app.route("/")
    def hello():
        return "Hello, World!"

    return app


def test_flask_integration(flask_app):
    from my_apm_agent import initialize_agent
    initialize_agent()
    
    client = flask_app.test_client()
    response = client.get("/")
    assert response.status_code == 200
    assert response.data == b"Hello, World!"

5. GitHub Actions와 연동하여 CI/CD 구축하기

테스트 자동화의 완성은 바로 CI/CD와의 연동입니다. Pytest와 tox를 설정한 후, 이를 GitHub Actions와 연결하면 코드를 커밋할 때마다 자동으로 테스트가 실행되어 문제를 빠르게 발견할 수 있습니다.

간단한 GitHub Actions 워크플로우 예시는 다음과 같습니다:

name: Python package

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.6, 3.7, 3.8, 3.9, 3.10, 3.11]
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install tox
    - name: Run tests
      run: tox

이 설정을 통해 GitHub에 코드를 푸시할 때마다 여러 Python 버전에서 자동으로 테스트가 실행됩니다. 이는 새로운 코드 변경이 기존의 기능을 깨뜨리지 않는지 보장하는 데 큰 도움을 줍니다.

6. 테스트 자동화를 통한 개발 효율성 향상

APM Python 에이전트 개발에서는 다양한 버전의 Python 및 모듈 호환성을 유지하는 것이 매우 중요합니다. 이를 위해 Pytest, tox, 그리고 GitHub Actions를 활용하면 복잡한 테스트 작업을 자동화하여 개발 효율성을 크게 향상시킬 수 있습니다. 자동화된 테스트는 단순히 코드의 품질을 높일 뿐만 아니라, 개발자가 새로운 기능에 집중할 수 있는 환경을 만들어줍니다.

마무리

APM 에이전트와 같은 복잡한 프로젝트를 개발할 때 테스트는 선택이 아닌 필수입니다. 특히 다양한 환경에서의 자동화를 통해 예상치 못한 문제들을 사전에 발견하고 해결할 수 있습니다. Pytest와 tox, 그리고 CI/CD 파이프라인을 연동해 보는 것은 어떨까요? 이를 통해 안정적이고 신뢰할 수 있는 APM 에이전트를 개발할 수 있을 것입니다.