2012-09-13 1 views
0

저는 테스트중인 특정 반복에 대해 사용자 정의 된 설명이 코의 생성기에서 생성 된 테스트를 얻는 방법을 연구하고 있습니다. 내 발전기 대상 메서드가 내 발전기 클래스에서 self에 액세스하려고 시도하지 않는 한 작동하는 무언가가 있습니다. 코가 생성기에서 실행되는 각 테스트에 대해 테스트 클래스의 일회용 인스턴스를 생성하는 동안 모든 제네레이터 대상 인스턴스에는 공통 테스트 클래스 인스턴스가있는 것을보고 있습니다. 이것은 setUp이 생성되는 각 테스트 인스턴스에서 실행되지만, 생성기 타겟이 바인딩 된 인스턴스에서 실행되지는 않습니다. (물론 실제 문제는 코 생성 인스턴스를 해당 인스턴스에 바인딩하는 방법을 볼 수 없다는 것입니다. 발전기 목표). 다음은이 모든 것을 알아 내기 위해 사용하는 코드입니다 (예, 데코레이터는 호출 가능 클래스로는 더 좋지만 코는 적어도 1.2.1 버전에서는 명시 적으로 테스트가 함수인지 확인합니다.테스트 테스트 인스턴스의 테스트 클래스 인스턴스를 데코 레이팅 된 생성기 타겟의 인스턴스와 동기화하도록

코를 통해 실행
import inspect 

def labelable_yielded_case(case): 

    argspec = inspect.getargspec(case) 
    if argspec.defaults is not None: 
     defaults_list = [''] * (len(argspec.args) - len(argspec.defaults)) + argspec.defaults 
    else: 
     defaults_list = [''] * len(argspec.args) 
    argument_defaults_list = zip(argspec.args, defaults_list) 
    case_wrappers = [] 

    def add_description(wrapper_id, argument_dict): 

     case_wrappers[wrapper_id].description = case.__doc__.format(**argument_dict) 

    def case_factory(*factory_args, **factory_kwargs): 

     def case_wrapper_wrapper(): 

      wrapper_id = len(case_wrappers) 

      def case_wrapper(*args, **kwargs): 

       args = factory_args + args 
       argument_list = [] 
       for argument in argument_defaults_list: 
        argument_list.append(list(argument)) 
       for index, value in enumerate(args): 
        argument_list[index][1] = value 
       argument_dict = dict(argument_list) 
       argument_dict.update(factory_kwargs) 
       argument_dict.update(kwargs) 
       add_description(wrapper_id, argument_dict) 
       return case(*args, **kwargs) 

      case_wrappers.append(case_wrapper) 
      case_wrapper.__name__ = case.__name__ 
      return case_wrapper 

     return case_wrapper_wrapper() 

    return case_factory 


class TestTest(object): 

    def __init__(self): 

     self.data = None 

    def setUp(self): 

     print 'setup', self 
     self.data = (1,2,3) 

    def test_all(self): 

     for index, value in enumerate((1,2,3)): 
      yield self.validate_equality(), index, value 

    def test_all_again(self): 

     for index, value in enumerate((1,2,3)): 
      yield self.validate_equality_again, index, value 

    @labelable_yielded_case 
    def validate_equality(self, index, value): 
     '''element {index} equals {value}''' 

     print 'test', self 
     assert self.data[index] == value, 'expected %d got %d' % (value, self.data[index]) 

    def validate_equality_again(self, index, value): 

     print 'test', self 
     assert self.data[index] == value, 'expected %d got %d' % (value, self.data[index]) 

    validate_equality_again.description = 'again' 

에서, again 테스트가 잘 작동하지만, 장식 발전기 타겟을 사용하여 테스트 세트는 모든 self.data is None 때문에 (때문에 실패 : 또는 방법은, 그래서 호출 클래스는) 전혀 실행되지 않습니다 클로저에 저장된 TestTest의 인스턴스가 nose가 실행하는 인스턴스가 아니기 때문에 setUp이 실행되지 않습니다. 데코레이터를 TestTest에 대한 기본 클래스의 인스턴스 멤버로 만들려고 시도했지만 코가 너무 적어서 (self) 언 바운드 labelable_yielded_case에 전달 된 인수가 거의 없다는 오류가 발생했습니다. 이 작업을 할 수있는 방법이 있습니까 (해킹 코가 부족합니다), 아니면 yield 멤버가 인스턴스 멤버가 될 수 없거나 각 테스트를 위해 테스트별로 레이블을 지정하지 못하는 것 중에서 선택해야합니까?

답변

0

고정되어 있습니다. (적어도 모든 경우에있어 생각합니다.) case_wrapper_wrappercase_wrapper을 가지고 바이어스를해야만 팩토리가 올바른 클래스에 첨부 된 랩 케이스를 반환하지만 주어진 인스턴스에 어떤 방식 으로든 바인딩되지 않았습니다. 래퍼 래퍼에서 인수를 작성했기 때문에 또 다른 코드 문제가 발생했지만이를 케이스로 전달하지 않았습니다. 작업 코드 :

import inspect 

def labelable_yielded_case(case): 

    argspec = inspect.getargspec(case) 
    if argspec.defaults is not None: 
     defaults_list = [''] * (len(argspec.args) - len(argspec.defaults)) + argspec.defaults 
    else: 
     defaults_list = [''] * len(argspec.args) 
    argument_defaults_list = zip(argspec.args, defaults_list) 
    case_wrappers = [] 

    def add_description(wrapper_id, argument_dict): 

     case_wrappers[wrapper_id].description = case.__doc__.format(**argument_dict) 

    def case_factory(*factory_args, **factory_kwargs): 

     def case_wrapper_wrapper(): 

      wrapper_id = len(case_wrappers) 

      def case_wrapper(*args, **kwargs): 

       argument_list = [] 
       for argument in argument_defaults_list: 
        argument_list.append(list(argument)) 
       for index, value in enumerate(args): 
        argument_list[index][1] = value 
       argument_dict = dict(argument_list) 
       argument_dict.update(kwargs) 
       add_description(wrapper_id, argument_dict) 
       return case(**argument_dict) 

      case_wrappers.append(case_wrapper) 
      case_name = case.__name__ + str(wrapper_id) 
      case_wrapper.__name__ = case_name 
      if factory_args: 
       setattr(factory_args[0].__class__, case_name, case_wrapper) 
       return getattr(factory_args[0].__class__, case_name) 
      else: 
       return case_wrapper 

     return case_wrapper_wrapper() 

    return case_factory 


class TestTest(object): 

    def __init__(self): 

     self.data = None 

    def setUp(self): 

     self.data = (1,2,3) 

    def test_all(self): 

     for index, value in enumerate((1,2,3)): 
      yield self.validate_equality(), index, value 

    @labelable_yielded_case 
    def validate_equality(self, index, value): 
     '''element {index} equals {value}''' 

     assert self.data[index] == value, 'expected %d got %d' % (value, self.data[index])