2015-11-06 67 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