파이썬에서 단위 테스트를 위해 전역 매개 변수를 올바르게 처리하는 방법은 무엇입니까? 구현하고 있습니다. 현재는

우리는 일반적으로 많은 공유, 공개 및 보안 관련 매개 변수를 가진 많은 알고리즘을 구현하고 있습니다.

현재는 모든 매개 변수와 두 개의 사전 정의 된 전역 객체를 보유한 클래스를 사용합니다.

class PublicParams(object):
    p = q = 0

    def __init__(self, p, q):
        self.p = p
        self.q = q

# used for tests
publicParams_test = PublicParams(15,7)

# Some 2048 bit numbers for example
publicParams_secure = PublicParams(128378947298374928374,128378947298374928374)  

그런 다음 알고리즘 PublicParams은 기본적으로 생산적인 기본 인수로 객체 를 가져 옵니다.publicParams_secure

def AlgoOne(n, publicParams = publicParams_secure):
    # do stuff with publicParams.p
    # ...
    AlgoTwo(x, publicParams)

def AlgoTwo(x, publicParams= publicParams_secure):
    # do stuff with publicParams.q

이런 식으로 우리는 더 쉬운 단위 테스트를 위해 다른 공용 매개 변수를 주입 할 수 있습니다.

class AlgoOneTest(unittest.TestCase):
    def test(self):
        # compare with manually computed result
        self.assertTrue(AlgoOne(1, publicParams_test) == 10) 

이 접근법에 대해 내가 싫어하는 것 :

  • 주는 일 publicParams몇 가지 알고리즘을 호출 할 때 기본값하는 것은 선택합니다. 그러나 AlgoTwowithin AlgoOne에서 호출 할 때 전달하는 것을 잊어 버리기 쉬워 져 테스트 오브젝트가 전달 된 경우 두 개의 다른 오브젝트가 사용됩니다.AlgoOne

단위 테스트에 덜 취약하지만 여전히 유연성을 제공하는 더 좋은 방법이 있습니까? 이것이 가장 좋은 방법입니까?



답변

구성 파일을 작성 test_config.py하고 production_config.py. 환경 변수 또는 명령 행 인수를 사용하여 그 중 하나를 선택하십시오. 가져 오거나 (또는 대신 .json/ 를 선택하면 읽기 / 파싱 ) 모듈의 전역 객체를 통해 전체 프로그램에서 결과를 사용할 수있게하여 어디에서나 가져올 수 있습니다..txt.py

이것은 전역 범위에서 파이썬을 호출하는 쉘에 이르기까지 한 단계 더 나아가는 것을 제외하고는 이미 수행중인 것과 매우 유사합니다. 이점은 더 이상 실수로 프로덕션 및 테스트 구성을 혼합 할 위험이 없다는 것입니다. 환경 변수 / 명령 줄이 하나뿐이므로 동일한 파이썬 세션에서 두 파일을 모두 읽을 수 없습니다.


답변

할 수있는 일이 많이 있습니다.

  • 글로벌 사용 중지
  • 기본값 사용 중지
  • 항상 기본값을 사용할 수없는 개인 헬퍼 메소드를 통해 테스트하십시오.

    def _AlgoOne(n, publicParams):
        return AlgoOne(n, publicParams)

이러한 옵션 중 하나가 많은 작업인지 확인하지만 이것이 문제가되지 않았는지 묻지 않을 것입니다.


답변

전역 컨텍스트와 해당 매개 변수의 처리에서 항상 값 콜렉션을 분리 할 수 ​​있습니다.

def do_the_thing():
    """Provides the public (rather untestable) context.
    _do_the_thing(global1, global2, publicParams)"""

def _do_the_thing(blah, blah, blah):
    "Actually does the thing"
    pass