简体   繁体   中英

new class instance not being initialized

I'm writing a package, and doing my testing like a good little programmer, but here's what happens:

class TestOne(unittest.TestCase):
    def setUp(self):
        self.finder = Finder()

    def test_default_search_parts(self):
        self.assertEqual(self.finder.search_parts, [])

class TestTwo(unittest.TestCase):
    def setUp(self):
        self.finder = Finder()

    def test_add_letter(self):
        self.finder.add('a')
        self.assertNotEqual(self.finder.search_parts, [])

in this case, test_default_search_parts fails with AssertionError: ['a'] != [] , and test_add_letter passes. I don't know what's going on here. It gets really weird when I rewrite test_default_search_parts :

def test_default_search_parts(self):
    f = Finder()
    self.assertEqual(f.search_parts, [])

the same failure occurs. What am I doing wrong here with initializing my instances?

Oh, and I'm using nose to run them, if that matters.

As @samplebias mentioned, shared state, in this case with class-level attributes, can cause problems. Here is a possible situation you have:

import unittest

# bad implementation of Finder, class-level attribute
class Finder(object):
    search_parts = []

    def add(self, letter):
        self.search_parts.append(letter)


# using 'Zne' here makes sure this test is run second        
class TestZne(unittest.TestCase):
    def setUp(self):
        print 'I am run next'
        self.finder = Finder()

    def test_default_search_parts(self):
        self.assertEqual(self.finder.search_parts, [])


class TestTwo(unittest.TestCase):
    def setUp(self):
        print 'I am run first'
        self.finder = Finder()

    def test_add_letter(self):
        self.finder.add('a')
        self.assertNotEqual(self.finder.search_parts, [])

unittest.main()

Outputs

Traceback (most recent call last):
  File "test.py", line 18, in test_default_search_parts
    self.assertEqual(self.finder.search_parts, [])
AssertionError: Lists differ: ['a'] != []

The problem being that all Finder instances share this class-level attribute search_parts, and add_letter is being run before the default search test.

To resolve, use something like:

class Finder(object):
    def __init__(self):
        self.search_parts = []

This will ensure it is an instance attribute only.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM