代码之家  ›  专栏  ›  技术社区  ›  vy32

在python模块的py.test测试目录中,导入模块的文件

  •  1
  • vy32  · 技术社区  · 6 年前

    我在一个目录中安排了一个python模块。叫它吧 foo .

    以下是文件布局:

    caller.py
    foo/__init__.py
    foo/bar.py
    foo/test/bar_test.py
    

    也就是说,模块被调用 以及密码 foo/__init__.py import foo 陈述 caller.py 开始跑步。

    foo/uuu初始版本 ,我希望访问 bar.py . 这是用来做的 import foo.bar .

    我的问题出现在编写运行在 foo/test/bar_test.py . 如果这个文件只是 foo/bar_test.py ,那么它也可以使用 导入foo.bar 导入的内容 foo.bar.py . 不幸的是,我们有一个编码标准,规定单元测试放在名为 tests .

    考虑到编码标准,我们如何导入bar.py?

    这不起作用:

    # foo/test/bar_test.py
    import foo.bar
    def test_return5():
       assert bar.return5() == 5
    

    它给了我:

    $ py.test
    ================================================== test session starts ==================================================
    platform linux -- Python 3.6.3, pytest-3.2.1, py-1.4.34, pluggy-0.4.0
    rootdir: /home/hadoop/xxx/foo, inifile:
    collected 0 items / 1 errors
    
    ======================================================== ERRORS =========================================================
    ___________________________________________ ERROR collecting test/bar_test.py ___________________________________________
    ImportError while importing test module '/home/hadoop/xxx/foo/test/bar_test.py'.
    Hint: make sure your test modules/packages have valid Python names.
    Traceback:
    test/bar_test.py:3: in <module>
        import foo.bar
    E   ModuleNotFoundError: No module named 'foo'
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ================================================ 1 error in 0.10 seconds ================================================
    

    这是可行的,但很恶心:

    # foo/test/bar_test.py
    
    import os
    import sys
    
    sys.path.append( os.path.join(os.path.dirname(__file__), "../.."))
    
    import foo.bar
    
    def test_return5():
       assert foo.bar.return5() == 5
    

    这不起作用:

    # foo/test/bar_test.py
    
    import os
    import sys
    
    sys.path.append( os.path.join(os.path.dirname(__file__), ".."))
    
    import bar
    
    def test_return5():
       assert bar.return5() == 5
    

    因为:

    $ py.test
    ================================================== test session starts ==================================================
    platform linux -- Python 3.6.3, pytest-3.2.1, py-1.4.34, pluggy-0.4.0
    rootdir: /home/hadoop/xxx/foo, inifile:
    collected 0 items / 1 errors
    
    ======================================================== ERRORS =========================================================
    ___________________________________________ ERROR collecting test/bar_test.py ___________________________________________
    ImportError while importing test module '/home/hadoop/xxx/foo/test/bar_test.py'.
    Hint: make sure your test modules/packages have valid Python names.
    Traceback:
    test/bar_test.py:8: in <module>
        import bar
    bar.py:3: in <module>
        import foo
    E   ModuleNotFoundError: No module named 'foo'
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ================================================ 1 error in 0.10 seconds ================================================
    

    因为bar.py有:

    # foo/bar.py
    
    import foo
    
    def return5():
        return 5
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   christian    6 年前
    import foo.bar as bar
    

    那应该管用 bar_test.py 如果您从父目录运行pytest(至少,它现在对我有效)。

    你不能用 import bar 在python 3中(我假设这就是您所使用的),因为它是不明确的-请参见 PEP-404 a more in depth stackoverflow answer 了解更多详细信息。

    编辑:看看扩展的例子,问题是 Bar_测试.py 不属于 foo 包装(因为 test 目录不是包)。如果您添加 __init__.py 文件发送至 测试 目录,pytest将很高兴地运行测试::

    $ pytest foo/test/bar_test.py 
    ===================================================================== test session starts ======================================================================
    platform linux -- Python 3.5.3, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
    rootdir: /home/xxxx/tmp/blank, inifile:
    collected 1 item                                                                                                                                                
    
    foo/test/bar_test.py .                                                                                                                                   [100%]
    
    =================================================================== 1 passed in 0.03 seconds ===================================================================
    $ ls -lh foo/test/
    total 12K
    -rw-rw-r-- 1 xxxx xxxx   95 Jul 26 14:44 bar_test.py
    -rw-rw-r-- 1 xxxx xxxx    0 Jul 27 16:38 __init__.py
    -rw-rw-r-- 1 xxxx xxxx  132 Jul 27 16:38 __init__.pyc
    drwxrwsr-x 2 xxxx xxxx 4.0K Jul 27 16:38 __pycache__
    

    注意我必须删除 __pycache__ 添加后 _初始版本 .

    查看 pytest docs 更多信息。