py.test函数的排序会导致失败

时间:2015-11-06 18:46:17

标签: python unit-testing pytest

我正在使用Python教授编程课程的介绍。我正在使用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

我使用Anaconda 2.3.0发行版和PyCharm教育版使用Python 2.7.10和pytest-2.7.1

1 个答案:

答案 0 :(得分:2)

问题是你传递的list是可变的,但是被测试的函数对它们有副作用。

一种可能的解决方案是将列表的 deepcopy 传递给测试函数。使用标准库中的copy模块。

E.g。

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