The difference manifests itself when you have more than one test method in your class. setUpClass and tearDownClass are run once for the whole class; setUp and tearDown are run before and after each test method.
For example:
class Example(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("setUpClass")
def setUp(self):
print("setUp")
def test1(self):
print("test1")
def test2(self):
print("test2")
def tearDown(self):
print("tearDown")
@classmethod
def tearDownClass(cls):
print("tearDownClass")
When you run this test, it prints:
setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass
(The dots (.) are unittest's default output when a test passes.) Observe that setUp and tearDown appear before and after test1 and test2, whereas setUpClass and tearDownClass appear only once, at the beginning and end of the whole test case.
The difference manifests itself when you have more than one test method in your class. setUpClass and tearDownClass are run once for the whole class; setUp and tearDown are run before and after each test method.
For example:
class Example(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("setUpClass")
def setUp(self):
print("setUp")
def test1(self):
print("test1")
def test2(self):
print("test2")
def tearDown(self):
print("tearDown")
@classmethod
def tearDownClass(cls):
print("tearDownClass")
When you run this test, it prints:
setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass
(The dots (.) are unittest's default output when a test passes.) Observe that setUp and tearDown appear before and after test1 and test2, whereas setUpClass and tearDownClass appear only once, at the beginning and end of the whole test case.
What is the difference between setUp() and setUpClass() in the Python unittest framework?
The main difference (as noted in the answer by Benjamin Hodgson) is that setUpClass is called only once and that is before all the tests, while setUp is called immediately before each and every test. (NB: The same applies to the equivalent methods in other xUnit test frameworks, not just Python's unittest.)
From the unittest documentation:
setUpClass()A class method called before tests in an individual class are run. setUpClass is called with the class as the only argument and must be decorated as a classmethod():
@classmethod
def setUpClass(cls):
...
and:
setUp()Method called to prepare the test fixture. This is called immediately before calling the test method; other than AssertionError or SkipTest, any exception raised by this method will be considered an error rather than a test failure. The default implementation does nothing.
Why would setup be handled in one method over the other?
This part of the question has not been answered yet. As per my comment in response to the answer by Gearon, the setUp method is meant for elements of the fixture that are common to all tests (to avoid duplicating that code in each test). I find this is often useful as removing duplication (usually) improves readability and reduces the maintenance burden.
The setUpClass method is for expensive elements that you would rather only have to do once, such as opening a database connection, opening a temporary file on the filesystem, loading a shared library for testing, etc. Doing such things before each test would slow down the test suite too much, so we just do it once before all the tests. This is a slight degradation in the independence of the tests but a necessary optimization in some situations. Arguably, one should not be doing such things in unit tests as it is usually possible to mock the database / filesystem / library / whatever without using the real thing. As such, I find that setUpClass is rarely needed. However, it is useful when testing the above examples (or similar) becomes necessary.
The problem is that setUpClass is executed earlier than classSetup fixture, hence the AttributeError.
One workaround might be to manually allow this method to be executed once, something like:
def setUp(self):
if getattr(self, 'navigated'):
return
self.sf.navigateToCCForms("img")
self.navigated = True
I would also try the setup_class() method supported by pytest, though I suspect you would get the same issue as with setUpClass.
You need to use setupClass to have something run once in the test class , setUp is run between each test. You don't use self in setupClass you use cls and need to bring it into the method. You also need to add the decorator to make it a class method not an instance method.
@classmethod
def setupClass(cls):
cls.sf = SendForms(self.driver)
cls.ts = TestStatus(self.driver)
cls.sf.navigateToSendforms("img")
In your test methods you can now access the global class atribute _mine through self. So you can do something like this:
def test_something(self):
self.assertEqual(self._mine.attribute, 'myAttribute')
If you're using Django 1.8+, you should use the setUpTestData method instead.
You can then set any attributes on the cls object, and access them via the individual test methods on the self object.
More information is in the Django docs.
As of 2.7 (per the documentation) you get setUpClass and tearDownClass which execute before and after the tests in a given class are run, respectively. Alternatively, if you have a group of them in one file, you can use setUpModule and tearDownModule (documentation).
EDIT: Note that setUpClass and tearDownClass must be declared using @classmethod. Another answer to this question includes sample code.
Otherwise your best bet is probably going to be to create your own derived TestSuite and override run(). All other calls would be handled by the parent, and run would call your setup and teardown code around a call up to the parent's run method.
I have the same scenario, for me setUpClass and tearDownClass methods works perfectly
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
@classmethod
def tearDownClass(cls):
cls._connection.destroy()