Python测试脚本在使用-munittest时有效,但在直接运行时由于ModuleNotFoundError而失败

时间:2017-07-07 08:20:27

标签: python

我有一个从我的应用程序导入模块的测试脚本。这与python -munittest一起运行时有效,但如果我只使用ModuleNotFoundError,则会失败python tests/test_app.py

这个项目中的其他脚本也不会发生单元测试。

$ python tests/test_app.py
Traceback (most recent call last):
  File "tests/test_app.py", line 2, in <module>
    import myapp
ModuleNotFoundError: No module named 'myapp'

$ python -munittest tests.test_app
....
----------------------------------------------------------------------
Ran 4 tests in 0.119s

OK

正如您从跟踪中看到的那样,它在文件的最开头,在我使用import myapp的导入中失败。

项目结构:

/project
  /myapp
    __init__.py
    models.py
  /otherapp
  /anotherapp
  /tests
    test_app.py
  /scripts
    a_script.py

unittest模块为加载脚本做了什么魔术?

如何直接执行我的脚本?

1 个答案:

答案 0 :(得分:0)

失败了,因为当您使用python tests/test_app.py运行时,您的python会在相对于myapptest_app.py的本地文件夹中查找PYTHONPATH,但无法找到它。而unittest将从项目根文件夹开始处理导入包。

此python文档链接解释了import语句的工作原理

  

导入名为spam的模块时,解释程序首先进行搜索   对于具有该名称的内置模块。如果没有找到,则搜索   对于由。给出的目录列表中名为spam.py的文件   变量sys.pathsys.path已从以下位置初始化:

     
      
  • 包含输入脚本(或当前目录)的目录。
  •   
  • PYTHONPATH(目录名列表,语法与   shell变量PATH)。
  •   
  • 依赖于安装的默认值。
  •   
     

初始化后,Python程序可以修改sys.path。目录   包含正在运行的脚本放在。的开头   搜索路径,在标准库路径之前。这意味着   将加载该目录中的脚本而不是加载的模块   库目录中的相同名称。这是一个错误,除非   打算替换。有关更多信息,请参见标准模块   信息。

因此,要使脚本直接可执行,您需要告诉python使用文档中描述的方法之一找到“myapp”。这是另一个SO question讨论如何使用导入(通过快速搜索可以找到更多)。