2012-05-30 109 views
1

我試圖測試使用Python單元測試類,但測試套件似乎被修改的基類奇怪的對象實例行爲的單元測試

這裏的一些僞代碼來演示該問題:

的類

// 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) 

夾具來填充實例,可能是文件或數據庫查詢

//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' 
} 
] 
的輸出個

測試

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) 
''' 

編輯:發佈真實片斷

第一測試通過,但是當第二測試被實現隨後將失敗。儘管看起來是新鮮的實例,但好像有一個對測試方法共享的類的引用。

我只在Python中完成了一小部分工作,這是我沒有意識到某種語言特性的結果嗎?

+1

removeOne方法中的self.collection.pop()? – cval

+0

退後一步。你確定你的'removeOne'做了它應該做的?你在這裏發佈的代碼不會。用你在這裏發佈的代碼*不能共享列表或MyClass對象*。也許你在簡化它的時候犯了一個錯誤? – delnan

+0

抱歉,更新了代碼段。奇怪的是,第一次測試通過,但後來的測試使它無效 - 它似乎修改了同一個類實例。 – sunwukung

回答

1

看到這個代碼

>>> 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 

你開始你都用deck = cards.deck(src)測試,但我不知道那src的來源。如果它不是作爲新對象在你的setUp方法中創建的,那麼它可能會在測試用例之間共享。

+0

我在想這也是問題 - 我試圖使用包含在單獨文件中的列表作爲夾具,所以我猜測在課堂上參考是全球性的,並且每次都進行修改。 – sunwukung

相關問題