Python Unittest and object initialization

Question:

My Python version is 3.5.1

I have a simple code (tests.py):

import unittest

class SimpleObject(object):
    array = []

class SimpleTestCase(unittest.TestCase):

    def test_first(self):
        simple_object = SimpleObject()
        simple_object.array.append(1)

        self.assertEqual(len(simple_object.array), 1)

    def test_second(self):
        simple_object = SimpleObject()
        simple_object.array.append(1)

        self.assertEqual(len(simple_object.array), 1)

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

If I run it with command ‘python tests.py’ I will get the results:

.F
======================================================================
FAIL: test_second (__main__.SimpleTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests.py", line 105, in test_second
    self.assertEqual(len(simple_object.array), 1)
AssertionError: 2 != 1

----------------------------------------------------------------------
Ran 2 tests in 0.003s

FAILED (failures=1)

Why it is happening? And how to fix it. I expect that each tests run will be independent (each test should pass), but it is not as we can see.

Asked By: Tom

||

Answers:

The array is shared by all instances of the class. If you want the array to be unique to an instance you need to put it in the class initializer:

class SimpleObject(object):
    def __init__(self):
        self.array = []

For more information take a look at this question: class variables is shared across all instances in python?

Answered By: Bryan Oakley

This can also be accomplished directly in unittest if you prefer to use only 1 class. Implement the setUp class. setUp runs before any of the tests are run as the class is instantiated. It is similar to init but conforms to the unittest library. Note the opposite is tearDown which is executed at the end of the test class if you need to build and deprecate objects. Example:

class SimpleObject(unitest.TestCase):
    def setUp(self):
        # I run first
        self.array = []

    def some_test(self):
        self.assertTrue(self.array == [])
        <some test code here>

    def tearDown(self):
        # I run last
        self.array = []. # or whatever teardown code you need

enjoy!

Answered By: RandallShanePhD