0
import unittest

class TestTemplate(unittest.TestCase):

    @classmethod
    def setUpClass(self):
        self.result = 'error'
        print "setUpClass"

    @classmethod
    def tearDownClass(self):
        print "The value of result is, ",self.result
        if self.result == 'ok':
            print "it is working"
        print "The value of cls result is : ", self.result
        print "TearDownClass"


class MyTest(TestTemplate):

    def test_method_one(self):
        self.result = 'ok'
        print self.result


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

In the tearDownClass the value of self.result is error, but rather it should be okay because I changed it in the method? Is there any resolve to this?

2 Answers 2

8

You are changing a class attribute in the setUp method, and reading it again in the tearDown, because both are class methods. In your test however, you are setting an instance attribute.

You'd have to set it on the class directly instead:

type(self).result = 'ok'

or

MyTest.result = 'ok'

The latter ties it to the current test class, the first option lets it work even in subclasses.

Demo:

>>> import unittest
>>> class TestTemplate(unittest.TestCase):
...     @classmethod
...     def setUpClass(self):
...         self.result = 'error'
...         print "setUpClass"
...     @classmethod
...     def tearDownClass(self):
...         print "The value of result is, ",self.result
...         if self.result == 'ok':
...             print "it is working"
...         print "The value of cls result is : ", self.result
...         print "TearDownClass"
...
>>> class MyTest(TestTemplate):
...     def test_method_one(self):
...         type(self).result = 'ok'
...         print self.result
...
>>> unittest.main(exit=False)
setUpClass
ok
.The value of result is,  ok
it is working
The value of cls result is :  ok
TearDownClass

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
<unittest.main.TestProgram object at 0x103945090>

However, you generally want to avoid changing the test class state during individual tests. Use the existing test runner facilities to track test results instead; all

The setUpClass and tearDownClass methods can apply to multiple tests (depending on how the tests are run), so the state is shared.

Sign up to request clarification or add additional context in comments.

6 Comments

Makes a lot of sense. But is it a good practice in python to change test class state? I am trying to store the the result of each test, whether it has passed or failed.@Martjin Pieters
@HarshdeepSingh: class state is just as dynamic as instance state; if you need to share state between instances then doing so on the class is fine. Why do you need to store the result of each test on the test class however? The test runner already tracks the state for you.
@HarshdeepSingh you should examine docs.python.org/2/library/unittest.html#unittest.TestResult as Martijn says instead of trying to collect results on your own.
I didn't down vote him, but yes I can use wasSuccessful, I will give it a try, thanks!
@MartijnPieters wasSuccessful works when class methods are not used, so when setUp and tearDown is used, can't they work with setUpClass and tearDownClass?
|
0

Try using self.__class__.result = "ok".

The reason it doesn't work is that setUpClass() is a class method (because of the @classmethod decorator), so the self parameter there is actually a class. Thus self.result = 'error' changes the class attribute.

1 Comment

type(self) is preferable over self.__class__, generally. Only use self.__class__ for old-style Python classes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.