【问题标题】:pytest requires different import statement than python shell sometimespytest 有时需要与 python shell 不同的导入语句
【发布时间】:2017-07-15 21:24:33
【问题描述】:

我对编程有点陌生,到目前为止,我的大多数程序都是单目录事务,但现在我想尝试更大的东西,但我在导入工作时遇到了麻烦。我使用 pytest 创建我的单元测试,并且我一直在我的 test_foo.py 文件中的单元测试定义之后放置独立的测试脚本。这工作正常,直到我添加一个 __init__.py 文件。

文件排列1

StackOverflow
 | card.py
 | test_card.py

其中 test_card.py 使用 import card as crd 导入卡片。

结果:以下命令都没有遇到 ImportError

$ python3 test_card.py
$ pytest

文件排列2

StackOverflow
 | __init__.py
 | card.py
 | test_card.py

结果:如果我保持导入语句不变,$ python3 test_card.py 仍然有效,但 $ pytest 遇到 ImportError。

如果我改用import StackOverflow.card as crd,pytest 将再次开始工作,但由于 ImportError,我无法将其作为脚本运行。

我意识到在这个例子中我不需要__init__.py 文件,但是它只是一个更大程序的一部分。也有人指出,第二个 import 语句是完全错误的。那么如何让 pytest 使用原始的 import 语句呢?

card.py 全文:

#Created by Patrick Cunfer
#2017-07-15


class Card(object):
    def __init__(self, value, suit):
        '''
        Sets the card's value and suit
        param value: An integer from 1 to 13
        param suit: A character representing a suit
        '''
        self.value = value
        self.suit = suit


    def __str__(self):
        return str(self.value) + " of " + str(self.suit)

test_card.py 全文

#Created by Patrick Cunfer
#2017-07-15


# First one breaks pytest, second one breaks shell
# import card as crd
# import StackOverflow.card as crd


def test_Card():
    test = crd.Card(5, 'S')
    assert test.value == 5
    assert test.suit == 'S'
    assert str(test) == "5 of S"
    del test


if __name__ == "__main__":
    #Unit test found a bug? Lets isolate it!

    print("Test 1")
    test = crd.Card(5, 'S')

    print(test.suit)
    print("Expect 'S'")
    print()

    #etc.

【问题讨论】:

    标签: python unit-testing pytest


    【解决方案1】:

    如果您想在您的情况下使用__init__.py,则必须将父目录的StackOverflow 路径附加到sys,如下所示:

    import sys
    project_dir = 'path to the parent dir of StackOverflow'
    sys.path.append(project_dir)
    

    然后你就可以使用import StackOverflow.card as crd


    您当前的import StackOverflow.card as crd 语句意味着您在StackOverflow 目录本身中有另一个名为StackOverflow 的目录;导入语句假设您的目录结构如下所示(不是您的情况):

    StackOverflow
        | test_card.py
        | StackOverflow
            | __init__.py
            | card.py
    

    无论如何,在您的情况下,您不需要使用__init__.py,因为您正在从同一目录中导入另一个脚本。 __init__.py 通常用于在目录外导入脚本。

    在此link 中,您将找到有关如何使用__init__.py 文件的文档。

    【讨论】:

    • 我知道我不需要这个例子的初始化文件,但对于我的真实程序,我需要。
    • 部分地,它消除了我对应该如何使用 import 语句的困惑,但它没有解决 pytest 在以这种方式使用时不起作用的事实。我的文件结构看起来不像你的答案描述的(我重新检查了)。
    • 我不是说你的文件结构看起来那样,我的意思是你的 import 语句假设还有另一个 StackOverflow 目录,事实并非如此,也是错误背后的原因。
    • 您希望我添加一个在您的情况下如何使用__init__.py 的示例吗?
    • 但我不想知道如何让import StackOverflow.card as crd 工作,我想知道为什么import card as crd 不工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 2016-12-11
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多