Reputation: 2815
I'm trying to test a class using Python unittest, but the test suite seems to be modifying the base class
here's some pseudo code to demonstrate the problem:
the class
// module cards...
class deck():
def __init__(self, cards):
self.__cards = cards
def __len__(self):
return len(self.__cards)
def draw(self, n = 1):
'''
remove and return n cards
from internal card list
n -- integer
@return list removed
'''
removed = self.__cards[0:n]
remaining = self.__cards[n:]
self.__cards = remaining
return removed
def addOne(self, card):
'''
add single card to the deck
'''
self.__cards.append(card)
def addMany(self, cards):
'''
add many cards to the deck
'''
self.__cards.extend(cards)
a fixture to populate the instance, will probably be the output of a file or DB query
//source
src = [
{
'id' : 1,
'name' : 'one',
'description' : 'this is one'
},
{
'id' : 2,
'name' : 'two',
'description' : 'this is two'
},
{
'id' : 3,
'name' : 'three',
'description' : 'this is three'
},
{
'id' : 4,
'name' : 'four',
'description' : 'this is four'
},
{
'id' : 5,
'name' : 'five',
'description' : 'this is five'
}
]
the tests
from source import src
import cards
def test_drawRemovesOne(self):
deck = cards.deck(src)
self.assertTrue(callable(deck.draw))
# single card
deckSize = len(deck)
drawnCard = deck.draw(1)
self.assertEqual(drawnCard[0]['id'], 1)
self.assertEqual(4, len(deck))
self.assertEqual(len(drawnCard), 1)
def test_drawRemovesMany(self):
deck = cards.deck(src)
deckSize = len(deck)
drawnCards = deck.draw(3)
self.assertEqual(drawnCards[0]['id'], 1)
self.assertEqual(drawnCards[1]['id'], 2)
self.assertEqual(drawnCards[2]['id'], 3)
self.assertEqual(len(deck), 2)
self.assertEqual(len(drawnCards), 3)
'''
INVALIDATES PREVIOUS TESTS...
def test_addOne(self):
deck = cards.deck(src)
card = {
'id' : 9,
'name' : 'nine',
'description' : 'this is nine'
}
deckSize = len(deck)
deck.addOne(card)
newDeckSize = len(deck)
self.assertTrue(newDeckSize == deckSize + 1)
'''
EDIT: posted real snippet
the first test passes, but then subsequently fails when second test is implemented. It seems as if there is one reference to the class being shared by the test methods, despite appearing to be fresh instances.
I've only done a nominal bit of work in Python, is this the result of some language peculiarity I'm unaware of?
Upvotes: 1
Views: 153
Reputation: 10605
See this code
>>> class Deck:
... def __init__(self, cards):
... self.cards = cards
>>> l0 = [1, 2, 3]
>>> d1 = Deck(l0)
>>> d2 = Deck(l0)
>>> d1.cards
0: [1, 2, 3]
>>> d2.cards
1: [1, 2, 3]
>>> d1.cards.append(4)
>>> d2.cards
2: [1, 2, 3, 4] # d1 and d2 share the same list for cards
You start both your tests with deck = cards.deck(src)
but I don't know where that src
is coming from. If it isn't created in your setUp method as a new object then it could be being shared between the test cases.
Upvotes: 1