【问题标题】:Python ModuleNotFoundError Testsuite (Import Error)Python ModuleNotFoundError 测试套件(导入错误)
【发布时间】:2024-01-30 16:40:02
【问题描述】:

当我运行包含一些测试的文件(例如 python test_website_loads.py)时,测试运行完美并且没有问题,但是当我尝试测试套件时(例如 python test_suite .py),出现下一个错误:

    from special_module.special_module_file import Special_Class
ModuleNotFoundError: No module named 'specialmodule'

我的目录如下:

test_suite.py
tests/
  __init__.py
  test_website_loads.py
  special_module/
    __init__.py
    special_module_file.py

在我的 special_module_file 中,我有一个名为 Special_Class 的类,我在 test_website_loads.py 中将此类目录导入为:

from special_module.special_module_file import Special_Class

我的 test_suite.py 代码是:

import unittest
import HtmlTestRunner
from tests.test_website_loads import Test_Website_Loads

init_tests = unittest.TestLoader().loadTestsFromTestCase(Test_Website_Loads)

test_suite = unittest.TestSuite([
    init_tests
])

runner = HtmlTestRunner.HTMLTestRunner(output='reports', report_title='Test Report')
runner.run(test_suite) 

而我的 test_website_loads.py 代码是:

import unittest
import HtmlTestRunner
from special_module.special_module import Special_Class

class Test_Website_Loads(unittest.TestCase):

    def setUp(self):
        special = Special_Class()

    def ...():
        ...

    def tearDown():
        ...

if __name__ == "__main__":

    unittest.main(
        testRunner=HtmlTestRunner.HTMLTestRunner(output='init')
    )

总之有 3 个文件(A、B、C)。 A调用B,B调用C。当我运行B时,它正确导入了C。但是在运行A时,B抛出ModuleNotFoundError。

【问题讨论】:

    标签: python python-import


    【解决方案1】:

    这是因为它位于tests 目录中,但您是从tests 的父目录运行test_suite.py。当您运行test_website_loads.py 时它起作用的原因是因为您是从tests 目录中运行它的。在解析导入时,Python 解释器会检查模块的一系列位置,从当前目录开始,然后移动到其他位置,例如 PYTHONPATH 环境变量中的位置,以及 Python 安装位置中的 site-packages 目录。

    我在我的系统上复制了这个,但将导入语句更改为 tests.special_module.special_module_file 并且它起作用了。如果您不喜欢此解决方案,则需要更改special_module 目录或add it to your PYTHONPATH 或类似目录的位置。

    编辑:针对您在下面的评论,我假设您的 test_suite.py 文件如下所示:

    from tests.test_website_loads import some_function, some_class
    
    result = some_function()
    obj = some_class()
    

    这仍然会遇到上述问题,因为 Python 解释器仍在*目录中运行。当它搜索模块时,它会搜索当前目录,它只找到test_suite.pytests/。然后它会检查您的 PYTHONPATH 环境变量。如果仍然没有找到,它将检查依赖于安装的默认位置(例如site-packages 目录),如果没有找到这样的模块,则抛出异常。我认为最好的解决方案是将special_module 添加到 PYTHONPATH 环境变量中,如我上面包含的链接中所述。否则,您可以使用ln -s tests/special_module special_module 在*目录中创建指向模块的符号链接,假设您在类UNIX 系统上运行。但是,这不会被视为最佳做法;首选第一种方法。

    【讨论】:

    • 你说的没错,我没有写重要的部分,我没有在test_suite.py中导入特殊模块,我是从test_website_loads.py中调用它(总而言之, test_suite.py 调用 test_website_loads.py 和 test_website_loads 调用特殊模块但失败
    • 好的,这确实有帮助。您能否编辑您的原始问题以包含此信息?此外,如果您可以从 test_suite.py 中添加用于调用 test_website_loads.py 的代码,那也会有所帮助。
    • 我相信主要问题仍然是我在回答中描述的问题,因为即使 test_website_loads.py 与 special_module 目录位于同一目录中,Python 解释器仍在从父目录,所以它仍然不知道在哪里可以找到 special_module 目录;现在只需要找到解决方案即可。
    • @ArturoAviles 我编辑了我的原始答案以反映您的更正。它应该可以解决您的问题。如果没有,请告诉我。