2015-11-06 65 views
0

我正在講授使用Python進行編程課程的介紹。我正在使用py.test來爲學生的作業評分。我有一種情況,當測試函數是一個順序時,py.test報告失敗的測試用例,但是當測試函數以另一種順序時,報告通過。py.test函數的排序導致失敗

我創建了一個帶有失敗程序和測試代碼的project on Github。但這裏是測試程序的摘錄。

from exercise3 import union, intersection, difference 

########### 
# TABLES ## 
########### 
GRADUATES = [["Number", "Surname", "Age"], 
      [7274, "Robinson", 37], 
      [7432, "O'Malley", 39], 
      [9824, "Darkes", 38]] 

MANAGERS = [["Number", "Surname", "Age"], 
      [9297, "O'Malley", 56], 
      [7432, "O'Malley", 39], 
      [9824, "Darkes", 38]] 


##################### 
# HELPER FUNCTIONS ## 
##################### 
def is_equal(t1, t2): 
    return sorted(t1) == sorted(t2) 


################### 
# TEST FUNCTIONS ## 
################### 


def test_union(): 
    """ 
    Test union operation. 
    """ 

    result = [["Number", "Surname", "Age"], 
       [7274, "Robinson", 37], 
       [9297, "O'Malley", 56], 
       [7432, "O'Malley", 39], 
       [9824, "Darkes", 38]] 

    assert is_equal(result, union(GRADUATES, MANAGERS)) 


def test_intersection(): 
    """ 
    Test intersection operation. 
    """ 
    result = [["Number", "Surname", "Age"], 
       [7432, "O'Malley", 39], 
       [9824, "Darkes", 38]] 

    assert is_equal(intersection(GRADUATES, MANAGERS), result) 

如果我把test_union函數放在第一位,而test_intersection函數第二位,後者失敗。這裏是py.test的輸出。它看起來像test_intersection中的結果變量正在使用test_union函數中的值。

/Users/ses/anaconda/bin/python "/Applications/PyCharm Educational.app/Contents/helpers/pycharm/pytestrunner.py" -p pytest_teamcity /Users/ses/PycharmProjects/pytest_weirdness/test_exercise3.py 
Testing started at 1:11 PM ... 
============================= test session starts ============================== 
platform darwin -- Python 2.7.10 -- py-1.4.27 -- pytest-2.7.1 
rootdir: /Users/ses/PycharmProjects/pytest_weirdness, inifile: 
collected 3 items 

../../../../Users/ses/PycharmProjects/pytest_weirdness/test_exercise3.py .F 
def test_intersection(): 
     """ 
     Test intersection operation. 
     """ 
     result = [["Number", "Surname", "Age"], 
        [7432, "O'Malley", 39], 
        [9824, "Darkes", 38]] 

    >  assert is_equal(intersection(GRADUATES, MANAGERS), result) 
    E  assert is_equal([['Number', 'Surname', 'Age'], [7432, "O'Malley", 39], [9824, 'Darkes', 38], [9297, "O'Malley", 56]], [['Number', 'Surname', 'Age'], [7432, "O'Malley", 39], [9824, 'Darkes', 38]]) 
    E  + where [['Number', 'Surname', 'Age'], [7432, "O'Malley", 39], [9824, 'Darkes', 38], [9297, "O'Malley", 56]] = intersection([['Number', 'Surname', 'Age'], [7274, 'Robinson', 37], [7432, "O'Malley", 39], [9824, 'Darkes', 38], [9297, "O'Malley", 56]], [['Number', 'Surname', 'Age'], [9297, "O'Malley", 56], [7432, "O'Malley", 39], [9824, 'Darkes', 38]]) 

如果我顛倒了順序,兩個測試都通過了。如果我一次運行一個測試,測試用例就會通過。

這對我來說很混亂,因爲我認爲測試用例的順序並不重要。另外,我自己的代碼沒有問題。這項任務直到今晚纔到期,所以我還沒有分享解決方案,但the original repo is also available on GitHub

我使用蟒蛇2.3.0分佈和PyCharm教育版與Python 2.7.10和pytest-2.7.1

+1

如果他們的'union'或'intersection'函數實際上改變了'GRADUTES'或'MANAGERS'的值,那麼調用第二個測試用例可能會失敗,因爲預期的結果是不正確的。 –

+0

但是Python不按值調用?此外,我已經打印出表格的內容,並且它們看起來很好。奇怪的是結果表是不正確的。我會將錯誤消息添加到帖子中。 – benevolentprof

+1

取決於你傳入的是什麼類型。因爲'lists'在技術上是可變的,所以你可以用'list.sort()''' –

回答

2

的問題是,你傳遞一個list,這是可變的,但在測試功能對他們有副作用。

一個可能的解決方案是將列表的深度拷貝傳遞給測試函數。使用標準庫中的copy模塊。

E.g.

assert is_equal(result, union(copy.deepcopy(GRADUATES), copy.deepcopy(MANAGERS))) 
+0

這樣的東西進行就地更改。我花了我所有的時間盯着test_intersection代碼。這個問題可以在test_union中以你建議的方式解決,也可以通過複製輸入來聯合解決。 – benevolentprof