Python unitest - Use variables defined in module and class level setup functions, in tests

Amey picture Amey · Oct 2, 2013 · Viewed 16.9k times · Source

I am doing Python unit testing using nosetests to experiment with Python class and module fixtures, to have minimal setup across my tests.

The problem is I am not sure how to use any variables defined in the setupUpModule and the setUpClass functions in my tests (example: test_1).

This is what I am using to try out:

import unittest

def setUpModule():
    a = "Setup Module variable"
    print "Setup Module"

def tearDownModule():
    print "Closing Module"

class TrialTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print a #<======
        b = "Setup Class variable"

    @classmethod
    def tearDownClass(cls):
        print "Closing Setup Class"

    def test_1(self):
        print "in test 1"
        print a #<======
        print b #<======

    def test_2(self):
        print "in test 2"

    def test_3(self):
        print "in test 3"

    def test_4(self):
        print "in test 4"

    def test_5(self):
        print "in test 5"

if __name__ == "__main__":
    unittest.main()

The error I get is:

Setup Module
ERROR
Closing Module

======================================================================
ERROR: test suite for <class 'one_setup.TrialTest'>
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/nose/suite.py", line 208, in run
    self.setUp()
  File "/Library/Python/2.7/site-packages/nose/suite.py", line 291, in setUp
    self.setupContext(ancestor)
  File "/Library/Python/2.7/site-packages/nose/suite.py", line 314, in setupContext
    try_run(context, names)
  File "/Library/Python/2.7/site-packages/nose/util.py", line 469, in try_run
    return func()
  File "/Users/patila14/Desktop/experimental short scripts/one_setup.py", line 13, in setUpClass
    print a
NameError: global name 'a' is not defined

----------------------------------------------------------------------

Of course, if I do gloabl a and global b, it will work. Is there a better way?

Answer

nofinator picture nofinator · Oct 3, 2013

For the string variable a, the only solution is global a. If you look at the Python 2 and Python 3 source code, setupModule() doesn't appear to do anything magical, so all the usual namespace rules apply.

If a were a mutable variable, like a list, you could define it at global scope and then append to it within setupModule.

Variable b is easier to work with because it is defined within a class. Try this:

@classmethod
def setUpClass(cls):
    cls.b = "Setup Class variable"

def test_1(self):
    print self.b