InfoGrab DocsInfoGrab Docs

Python 스타일 가이드

요약

GitLab에서의 테스트는 Python 코드베이스를 포함하여 사후에 추가되는 것이 아닌 핵심 우선순위입니다. Python 테스트에는 Pytest를 사용하세요. Five Factor Testing: 테스트가 필요한 이유는 무엇인가?

테스트#

개요#

GitLab에서의 테스트는 Python 코드베이스를 포함하여 사후에 추가되는 것이 아닌 핵심 우선순위입니다. 따라서 기능 설계와 함께 처음부터 테스트 설계 품질을 고려하는 것이 중요합니다.

Python 테스트에는 Pytest를 사용하세요.

권장 읽기 자료#

테스트 수준#

테스트를 작성하기 전에 다양한 테스트 수준을 이해하고 변경 사항에 적합한 수준을 결정하세요.

다양한 테스트 수준과 변경 사항을 어느 수준에서 테스트해야 하는지 결정하는 방법에 대해 자세히 알아보세요.

권장 사항#

테스트 파일 이름을 테스트 대상 파일과 동일하게 지정하기#

단위 테스트의 경우, 테스트 파일을 test_{테스트할_파일명}.py로 명명하고 동일한 디렉터리 구조에 배치하면 나중에 테스트를 찾기가 쉬워집니다. 또한 이름은 같지만 모듈이 다른 파일 간의 혼동을 방지할 수 있습니다.

File: /foo/bar/cool_feature.py

# Bad

Test file: /tests/my_cool_feature.py

# Good

Test file: /tests/foo/bar/test_cool_feature.py

NamedTuple을 사용하여 파라미터화 테스트 케이스 정의하기#

Pytest 파라미터화 테스트는 코드 반복을 효과적으로 줄여주지만, Ruby의 더 읽기 쉬운 문법과 달리 테스트 케이스 정의에 튜플을 사용합니다. 파라미터나 테스트 케이스가 많아질수록 이 튜플 기반 테스트는 이해하고 유지 관리하기 어려워집니다.

대신 Python의 NamedTuple을 사용하면 다음과 같은 이점이 있습니다:

  • 이름이 지정된 필드로 더 명확한 구성을 강제할 수 있습니다.

  • 테스트를 더 자체 문서화하기 쉽게 만들 수 있습니다.

  • 파라미터의 기본값을 쉽게 정의할 수 있습니다.

  • 복잡한 테스트 시나리오에서 가독성을 향상시킬 수 있습니다.

# Good: Short examples, with small numbers of arguments. Easy to map what each value maps to each argument

@pytest.mark.parametrize(
    (
        "argument1",
        "argument2",
        "expected_result",
    ),
    [
        # description of case 1,
        ("value1", "value2", 200),
        # description of case 2,
        ...,
    ],
)
def test_get_product_price(argument1, argument2, expected_result):
    assert get_product_price(value1, value2) == expected_cost

# Bad: difficult to map a value to an argument, and to add or remove arguments when updating test cases

@pytest.mark.parametrize(
    (
        "argument1",
        "argument2",
        "argument3",
        "expected_response",
    ),
    [
      # Test case 1:
      (
        "value1",
        {
          ...
        },
        ...
      ),
      # Test case 2:
      ...
    ]
)

def test_my_function(argument1, argument2, argument3, expected_response):
   ...

# Good: NamedTuples improve readability for larger test scenarios.

from typing import NamedTuple

class TestMyFunction:
  class Case(NamedTuple):
      argument1: str
      argument2: int = 3
      argument3: dict
      expected_response: int

  TEST_CASE_1 = Case(
      argument1="my argument",
      argument3={
          "key": "value"
      },
      expected_response=2
  )

  TEST_CASE_2 = Case(
      ...
  )
  @pytest.mark.parametrize(
      "test_case", [TEST_CASE_1, TEST_CASE_2]
  )
  def test_my_function(test_case):
      assert my_function(case.argument1, case.argument2, case.argument3) == case.expected_response

모킹#

  • unittest.mock 라이브러리를 사용하세요.

  • 예를 들어 메서드 호출 경계와 같이 적절한 수준에서 모킹하세요.

  • 외부 서비스와 API를 모킹하세요.

코드 스타일#

코드 품질과 보안을 보장하기 위해 자동화된 도구를 사용하는 것을 권장합니다. 로컬에서뿐만 아니라 CI 파이프라인에서도 다음 도구들을 실행하는 것을 고려하세요:

포맷팅 도구#

  • Black: 일관된 스타일을 강제하는 코드 포맷터

  • isort: import 문을 정렬하고 구성

린팅 도구#

  • flake8: PEP-8 준수 여부 및 일반적인 오류 검사

  • pylint: 코드 품질을 위한 더 포괄적인 린터

  • mypy: Python용 정적 타입 검사기

테스트 도구#

  • pytest: 커버리지 리포팅이 포함된 테스트 프레임워크

보안 도구#

  • 종속성 스캐닝: 의존성의 취약점 검사

  • 시크릿 탐지: 리포지터리에 시크릿이 커밋되지 않도록 보장

  • SAST (semgrep): 정적 애플리케이션 보안 테스트

Python 스타일 가이드

GitLab v19.1
원문 보기
요약

GitLab에서의 테스트는 Python 코드베이스를 포함하여 사후에 추가되는 것이 아닌 핵심 우선순위입니다. Python 테스트에는 Pytest를 사용하세요. Five Factor Testing: 테스트가 필요한 이유는 무엇인가?

테스트#

개요#

GitLab에서의 테스트는 Python 코드베이스를 포함하여 사후에 추가되는 것이 아닌 핵심 우선순위입니다. 따라서 기능 설계와 함께 처음부터 테스트 설계 품질을 고려하는 것이 중요합니다.

Python 테스트에는 Pytest를 사용하세요.

권장 읽기 자료#

테스트 수준#

테스트를 작성하기 전에 다양한 테스트 수준을 이해하고 변경 사항에 적합한 수준을 결정하세요.

다양한 테스트 수준과 변경 사항을 어느 수준에서 테스트해야 하는지 결정하는 방법에 대해 자세히 알아보세요.

권장 사항#

테스트 파일 이름을 테스트 대상 파일과 동일하게 지정하기#

단위 테스트의 경우, 테스트 파일을 test_{테스트할_파일명}.py로 명명하고 동일한 디렉터리 구조에 배치하면 나중에 테스트를 찾기가 쉬워집니다. 또한 이름은 같지만 모듈이 다른 파일 간의 혼동을 방지할 수 있습니다.

File: /foo/bar/cool_feature.py

# Bad

Test file: /tests/my_cool_feature.py

# Good

Test file: /tests/foo/bar/test_cool_feature.py

NamedTuple을 사용하여 파라미터화 테스트 케이스 정의하기#

Pytest 파라미터화 테스트는 코드 반복을 효과적으로 줄여주지만, Ruby의 더 읽기 쉬운 문법과 달리 테스트 케이스 정의에 튜플을 사용합니다. 파라미터나 테스트 케이스가 많아질수록 이 튜플 기반 테스트는 이해하고 유지 관리하기 어려워집니다.

대신 Python의 NamedTuple을 사용하면 다음과 같은 이점이 있습니다:

  • 이름이 지정된 필드로 더 명확한 구성을 강제할 수 있습니다.

  • 테스트를 더 자체 문서화하기 쉽게 만들 수 있습니다.

  • 파라미터의 기본값을 쉽게 정의할 수 있습니다.

  • 복잡한 테스트 시나리오에서 가독성을 향상시킬 수 있습니다.

# Good: Short examples, with small numbers of arguments. Easy to map what each value maps to each argument

@pytest.mark.parametrize(
    (
        "argument1",
        "argument2",
        "expected_result",
    ),
    [
        # description of case 1,
        ("value1", "value2", 200),
        # description of case 2,
        ...,
    ],
)
def test_get_product_price(argument1, argument2, expected_result):
    assert get_product_price(value1, value2) == expected_cost

# Bad: difficult to map a value to an argument, and to add or remove arguments when updating test cases

@pytest.mark.parametrize(
    (
        "argument1",
        "argument2",
        "argument3",
        "expected_response",
    ),
    [
      # Test case 1:
      (
        "value1",
        {
          ...
        },
        ...
      ),
      # Test case 2:
      ...
    ]
)

def test_my_function(argument1, argument2, argument3, expected_response):
   ...

# Good: NamedTuples improve readability for larger test scenarios.

from typing import NamedTuple

class TestMyFunction:
  class Case(NamedTuple):
      argument1: str
      argument2: int = 3
      argument3: dict
      expected_response: int

  TEST_CASE_1 = Case(
      argument1="my argument",
      argument3={
          "key": "value"
      },
      expected_response=2
  )

  TEST_CASE_2 = Case(
      ...
  )
  @pytest.mark.parametrize(
      "test_case", [TEST_CASE_1, TEST_CASE_2]
  )
  def test_my_function(test_case):
      assert my_function(case.argument1, case.argument2, case.argument3) == case.expected_response

모킹#

  • unittest.mock 라이브러리를 사용하세요.

  • 예를 들어 메서드 호출 경계와 같이 적절한 수준에서 모킹하세요.

  • 외부 서비스와 API를 모킹하세요.

코드 스타일#

코드 품질과 보안을 보장하기 위해 자동화된 도구를 사용하는 것을 권장합니다. 로컬에서뿐만 아니라 CI 파이프라인에서도 다음 도구들을 실행하는 것을 고려하세요:

포맷팅 도구#

  • Black: 일관된 스타일을 강제하는 코드 포맷터

  • isort: import 문을 정렬하고 구성

린팅 도구#

  • flake8: PEP-8 준수 여부 및 일반적인 오류 검사

  • pylint: 코드 품질을 위한 더 포괄적인 린터

  • mypy: Python용 정적 타입 검사기

테스트 도구#

  • pytest: 커버리지 리포팅이 포함된 테스트 프레임워크

보안 도구#

  • 종속성 스캐닝: 의존성의 취약점 검사

  • 시크릿 탐지: 리포지터리에 시크릿이 커밋되지 않도록 보장

  • SAST (semgrep): 정적 애플리케이션 보안 테스트