2016-04-13 7 views
0

unittest.TestCaseを使用してクラス階層を作成しようとしています。これらは、厳密にはユニットテスト私はここで実行している、私はいくつかのパラメータ(たとえば、顧客名と欠損値)に依存する文字列解析機能の束をテストしようとしています。一般的な考え方はunittestの便利さの一部を単純に活用し、DRYを維持することです。unittest.TestCaseをサブクラス化し、 `super()__ init __()`にキーワードargsを渡し、 `__init__に予期しないキーワード引数がありました。

import unittest 
import parsingfunc as i 

class CustomerTestCase(unittest.TestCase): 
    """Base class, most general functionality and test cases""" 

    def __init__(self, testname): 
     super(CustomerTestCase, self).__init__(testname) 

    # helpers 

    def mess_with_spaces(): 
     ... 

    def mess_with_case(): 
     ... 

    # tests 

    def test_case(self, value): 
     """ 
     Test that parsing function produces the same 
     value regardless of case of input 
     """ 
     self.assertEqual(self.func(value, missing=self.missing, customer=self.name), 
         self.func(self.mess_with_case(value), missing=self.missing, customer=self.name))) 
     ... 

    def test_spaces(self, value): 
     """ 
     Test that parsing function produces the same 
     value regardless of spacing present in input 
     """ 
     ... 


class AisleValues(CustomerTestCase): 
    """Base class for testing aisle values""" 

    def __init__(self, testname, customername=None, missing=None): 
     super(CustomerTestCase, self).__init__(testname) 
     self.name = customername 
     self.missing = missing 
     self.func = i.aisle_to_num 

    ... 

class PeacockAisles(AisleValues): 
    """Peacock aisle parsing test cases""" 

    def __init__(self, testname): 
     super(AisleValues, self).__init__(testname, customername='peacock', missing='nan') 

    ... 

そして今、これらのクラス

In [6]: a = i.CustomerTestCase('space_test') 

In [7]: a.__dict__ 
Out[7]: 
{'_cleanups': [], 
'_resultForDoCleanups': None, 
'_testMethodDoc': '\n  Test that parsing function produces the same\n  value regardless of spacing present in input\n  ', 
'_testMethodName': 'test_spaces', 
'_type_equality_funcs': {list: 'assertListEqual', 
    dict: 'assertDictEqual', 
    set: 'assertSetEqual', 
    frozenset: 'assertSetEqual', 
    tuple: 'assertTupleEqual', 
    unicode: 'assertMultiLineEqual'}} 

In [8]: b = i.AisleValues('test_spaces') 

In [9]: b.__dict__ 
Out[9]: 
{'_cleanups': [], 
'_resultForDoCleanups': None, 
'_testMethodDoc': '\n  Test that parsing function produces the same\n  value regardless of spacing present in input\n  ', 
'_testMethodName': 'test_spaces', 
'_type_equality_funcs': {list: 'assertListEqual', 
    dict: 'assertDictEqual', 
    set: 'assertSetEqual', 
    frozenset: 'assertSetEqual', 
    tuple: 'assertTupleEqual', 
    unicode: 'assertMultiLineEqual'}, 
'func': <function integration.aisle_to_num>, 
'missing': None, 
'name': None} 

In [10]: b = i.AisleValues('test_spaces', customername='peacock', missing='nan') 

In [11]: b.__dict__ 
Out[12]: 
{'_cleanups': [], 
'_resultForDoCleanups': None, 
'_testMethodDoc': '\n  Test that parsing function produces the same\n  value regardless of spacing present in input\n  ', 
'_testMethodName': 'test_spaces', 
'_type_equality_funcs': {list: 'assertListEqual', 
    dict: 'assertDictEqual', 
    set: 'assertSetEqual', 
    frozenset: 'assertSetEqual', 
    tuple: 'assertTupleEqual', 
    unicode: 'assertMultiLineEqual'}, 
'func': <function integration.aisle_to_num>, 
'missing': 'nan', 
'name': 'peacock'} 

In [13]: c = i.PeacockAisles('test_spaces') 

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-12-d4bba181b94e> in <module>() 
----> 1 c = i.PeacockAisles('test_spaces') 

/path/to/python.py in __init__(self, testname) 
    89 
    90  def __init__(self, testname): 
---> 91   super(AisleValues, self).__init__(testname, customername='peacock', missing='nan') 
    92   pprint(self.__dict__) 
    93 

TypeError: __init__() got an unexpected keyword argument 'customername' 

のインスタンスを作成しようとするので、契約は何ですか?ありがとう!

答えて

1

あなたはsuperに正しく電話していません。 superコールでクラスに名前を付けるときは、の現在のクラスである必要があります。実際に何をしているのかわからない場合や、ベースクラスの実装をスキップしたい場合は、「祖父母"クラス)。

現在のコードはAisleValues.__init__で、CustomerTestCase.__init__をバイパスしてunittest.TestCase.__init__と呼び出しています。 CustomerTestCase.__init__は何も役に立たないので(効果なしで削除することもできます)、それはうまくいくのですが、それは単なる運がいいのです。 PeacockAisles.__init__CustomerTestCase.__init__AisleValues.__init__を迂回)を呼び出すと、祖父母クラスがその子と同じ引数をすべて許可しないため、失敗します。

あなたが欲しい:

class AisleValues(CustomerTestCase): 
    """Base class for testing aisle values""" 

    def __init__(self, testname, customername=None, missing=None): 
     super(AisleValues, self).__init__(testname)   # change the class named here 
     ... 

そして:

class PeacockAisles(AisleValues): 
    """Peacock aisle parsing test cases""" 

    def __init__(self, testname): 
     super(PeacockAisles, self).__init__(testname, customername='peacock', missing='nan') 
     ...            # and on the previous line 
+0

をはいああそれは完璧な理にかなって、私はそれは、単純な何かを知っていました。それは今働く。ありがとう! –

関連する問題