2016-11-29 1 views
1
def register_processor2(processor_name='SomeProcessor'): 
    def decorator(func): 
     class SomeProcessor(GenericPaymentProcessor, TriggeredProcessorMixin): 
      name = processor_name 
      transaction_class = Transaction 

      @staticmethod 
      def setup(data=None): 
       pass 

     @wraps(func) 
     def func_wrapper(*args, **kwargs): 
      PaymentProcessorManager.register(SomeProcessor) 
      result = func(*args, **kwargs) 
      PaymentProcessorManager.unregister(SomeProcessor) 
      return result 

     return func_wrapper 
    return decorator 


def register_processor(func): 
    class SomeProcessor(GenericPaymentProcessor, TriggeredProcessorMixin): 
     name = 'SomeProcessor' 
     transaction_class = Transaction 

     @staticmethod 
     def setup(data=None): 
      pass 

    @wraps(func) 
    def func_wrapper(*args, **kwargs): 
     PaymentProcessorManager.register(SomeProcessor) 
     result = func(*args, **kwargs) 
     PaymentProcessorManager.unregister(SomeProcessor) 
     return result 

    return func_wrapper 


class TestPaymentMethodEndpoints(APITestCase): 
    @register_processor 
    def test_put_detail_cannot_change_processor(self): 
     self.assertEqual(True, False) 

Ok 그래서 장식 자 register_processor은 예상대로 작동합니다. 그리고 테스트는 실패하지만 내부 클래스의 이름을 사용자 정의 가능하게 만들고 싶어서 대신 데코레이터 팩토리 구현을 위해갔습니다.unittest 메서드의 장식 도구 팩토리

나는 다음과 같은 얻을 register_processor2 장식 테스트를 실행할 때 일입니다 바인딩 방법은 여기 TestPaymentMethodEndpoints의 인스턴스 func이며, 왜 안

AttributeError: 'TestPaymentMethodEndpoints' object has no attribute '__name__'

@wraps(func)에서, 내 질문입니다 ?

또한 @wraps 데코레이터를 제거하면 테스트를 실행하고을 전달합니다. func_wrappertest_*으로 시작하지 않으며 발견 되더라도 테스트가 발견되지 않을 것으로 예상됩니다.

어떤 일이 벌어지고 있는지에 대한 통찰력이 있으며 어떻게해야할까요?

편집은 그래서 장식 공장은 여전히 ​​그것을 호출 할 때 ()을 배치해야 기본 값이 인수를 경우에도 그것을 알아 냈다.

그러나 처음에는 통과/발견 된 테스트의 경우에 대한 설명을 듣는 것을 좋아합니다.

class TestPaymentMethodEndpoints(APITestCase): 
    @register_processor() 
    def test_put_detail_cannot_change_processor(self): 
     self.assertEqual(True, False) 

나는 이제 생각해 보았습니다. D, 어머, 너는 매일 새로운 것을 배웠다.

답변

1

이제는 "unittest 모듈이 시작되지 않는 함수로 랩핑 된 테스트 사례를 찾을 수 있습니까?"라고 묻는 것 같아요. test? unittest 실행 방법을 찾을 수있는 기능의 이름를 사용하지 않기 때문에

그에 대한 대답은, 그것은 그들을 찾기 위해 속성 이름을 테스트 케이스 클래스의을 사용합니다.

그래서 다음 코드를 실행 해보십시오 :

Attributes of MyTestCase: ['__call__', ...lots of things..., 'test_something'] 

하지만, 그 속성의 값이 포장 기능 wrap_with_fixture입니다 :

from unittest import TestCase 

def apply_fixture(func): 

    def wrap_with_fixture(self): 
     print('setting up fixture...') 
     try: 
      func(self) 
     finally: 
      print('tearing down fixture') 

    return wrap_with_fixture 


class MyTestCase(TestCase): 

    @apply_fixture 
    def test_something(self): 
     print('run test') 


print('Attributes of MyTestCase: %s' % dir(MyTestCase)) 
print('test_something method: %s' % MyTestCase.test_something) 

mtc = MyTestCase() 
mtc.test_something() 

당신은 dir의 출력이 이름 test_something 포함되어 있음을 볼 것이다 :

test_something method: <function apply_fixture.<locals>.wrap_with_fixture at 0x10d90aea0> 

이것은 함수를 만들 때 제공된 이름과 동일한 이름을 가진 지역 변수를 가진 함수를 생성하고 장식 자 @은 구문적인 설탕이라는 점을 고려할 때 다음과 같은 식으로 생각할 수 있습니다. 테스트 케이스 클래스를 만드는 데 더 오래 동안 바람을 피웠음에도 불구하고 똑같이 유효합니다.

class MyTestCase(TestCase): 

    def test_something(self): 
     print('run test') 
    # Overwrite existing 'local' (or 'class' variable in this context) 
    # with a new value. We haven't deleted the test_something function 
    # which still exists but now is owned by the function we've created. 
    test_something = apply_fixture(test_something) 
+0

처음에는 테스트가 성공한 이유는 무엇입니까? D. 나는 그렇게해서는 안된다는 뜻입니다. – Krotz

+1

데코레이터 팩토리 뒤에 괄호를 넣지 않을시기에 대해 혼동을 일으킬 가능성이 있습니까? 실제로는 데코레이터 함수 인 테스트 케이스를 만들 수 있습니다. 'decorator_factory (* args, ** kwargs) : ... 리턴 데코레이터',''@decorator_factory def test_method (self) : self.assertEqual (True, False)'이므로 데코레이터 팩토리는'test_method' 테스트 케이스로 사용되는 데코레이터를 반환하지만 테스트를 래핑하고 실제로 테스트를 실행하지 않는 새로운 함수를 작성하므로 통과하는 것처럼 보입니다. – daphtdazz

+0

테스트를 실행할 때 또는 테스트를 수행 할 때 어설 션 오류를 catch하고 dict에없는 테스트 함수 __name__에 따라 실패한 테스트를 일종의 사전에 저장하므로 무시합니다. 어쨌든 나는 본질적으로 그것의 요지를 가지고있다. 고마워. – Krotz