Inheriting a base class for nose tests
Question: I'm trying to implement an integration test framework using nose. At the core,
I'd like a base class that all test classes inherit. I'd like to have a class
setup function that is called as well as the per test setup function. When I
use `nosetests a_file.py -vs` where *a_file.py* looks like this:

    
    
        from nose import tools
    
        class BaseClass(object):
            def __init__(self):
                print 'Initialize Base Class'
    
            def setup(self):
                print "\nBase Setup"
    
            def teardown(self):
                print "Base Teardown"
    
            @tools.nottest
            def a_test(self):
                return 'This is a test.'
    
            @tools.nottest
            def another_test(self):
                return 'This is another test'
    
        class TestSomeStuff(BaseClass):
            def __init__(self):
                BaseClass.__init__(self)
                print 'Initialize Inherited Class'
    
            def setup(self):
                BaseClass.setup(self)
                print "Inherited Setup"
    
            def teardown(self):
                BaseClass.teardown(self)
                print 'Inherited Teardown'
    
            def test1(self):
                print self.a_test()
    
            def test2(self):
                print self.another_test()
    

Outputs this:

    
    
    Initialize Base Class
    Initialize Inherited Class
    Initialize Base Class
    Initialize Inherited Class
    cases.nose.class_super.TestSomeStuff.test1 ... 
    Base Setup
    Inherited Setup
    This is a test.
    Base Teardown
    Inherited Teardown
    ok
    cases.nose.class_super.TestSomeStuff.test2 ... 
    Base Setup
    Inherited Setup
    This is another test
    Base Teardown
    Inherited Teardown
    ok
    
    ----------------------------------------------------------------------
    Ran 2 tests in 0.001s
    
    OK
    

How do I make the `__init__`, `setup`, and `teardown` functions class methods?
When I attempt this:

    
    
    from nose import tools
    
    class BaseClass(object):
        def __init__(self):
            print 'Initialize Base Class'
    
        @classmethod
        def setup_class(self):
            print "\nBase Setup"
    
        @classmethod
        def teardown_class(self):
            print "Base Teardown"
    
        @tools.nottest
        def a_test(self):
            return 'This is a test.'
    
        @tools.nottest
        def another_test(self):
            return 'This is another test'
    
    class TestSomeStuff(BaseClass):
        def __init__(self):
            BaseClass.__init__(self)
            print 'Initialize Inherited Class'
    
        @classmethod
        def setup_class(self):
            BaseClass.setup_class(self)
            print "Inherited Setup"
    
        @classmethod
        def teardown_class(self):
            BaseClass.teardown_class(self)
            print 'Inherited Teardown'
    
        def test1(self):
            print self.a_test()
    
        def test2(self):
            print self.another_test()
    

I get this:

    
    
    Initialize Base Class
    Initialize Inherited Class
    Initialize Base Class
    Initialize Inherited Class
    ERROR
    
    ======================================================================
    ERROR: test suite for <class 'cases.nose.class_super.TestSomeStuff'>
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 208, in run
        self.setUp()
      File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 291, in setUp
        self.setupContext(ancestor)
      File "/usr/lib/python2.7/dist-packages/nose/suite.py", line 314, in setupContext
        try_run(context, names)
      File "/usr/lib/python2.7/dist-packages/nose/util.py", line 478, in try_run
        return func()
      File "/home/ryan/project/python_testbed/cases/nose/class_super.py", line 30, in setup_class
        BaseClass.setup_class(self)
    TypeError: setup_class() takes exactly 1 argument (2 given)
    
    ----------------------------------------------------------------------
    Ran 0 tests in 0.001s
    
    FAILED (errors=1)
    

Removing the `self` from the super class calls (`BaseClass.setup_class(self)`
-> `BaseClass.setup_class()`) seems to fix it...which I don't understand:

    
    
    Initialize Base Class
    Initialize Inherited Class
    Initialize Base Class
    Initialize Inherited Class
    
    Base Setup
    Inherited Setup
    cases.nose.class_super.TestSomeStuff.test1 ... This is a test.
    ok
    cases.nose.class_super.TestSomeStuff.test2 ... This is another test
    ok
    Base Teardown
    Inherited Teardown
    
    ----------------------------------------------------------------------
    Ran 2 tests in 0.001s
    
    OK
    

However, this doesn't help with the `__init__` function. How can I make this a
class method? Why does passing in `self` to the super class fail. Does anyone
have some info on this?


Answer: Class methods take a single implicit argument, (called `cls` by convention,
although you have called it `self` too), like instance methods take `self`.

When you call

    
    
    BaseClass.setup_class(self)
    

It's really more like

    
    
    BaseClass.setup_class(BaseClass, self)
    

hence the warning over two arguments. Therefore it's fixed when you ditch
`self`; as a reminder, change the definitions:

    
    
    @classmethod
    def setup_class(cls):
    

Oh, and `__init__` makes no sense as a `@classmethod`; it's for setting up
instances.

