Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 确保py.test在sys.path中包含应用程序目录_Python_Unit Testing_Pytest - Fatal编程技术网

Python 确保py.test在sys.path中包含应用程序目录

Python 确保py.test在sys.path中包含应用程序目录,python,unit-testing,pytest,Python,Unit Testing,Pytest,我有一个项目目录结构,如下所示(我认为这是相当标准的): 我正在使用py.test作为我的测试框架,我希望在my_project目录中运行测试时能够运行py.tests。这确实有效,直到我尝试在测试中使用(例如)import mypkg导入我的应用程序代码。在这一点上,我得到了错误“没有名为mypkg的模块”。在进行一点调查后,似乎py.test使用sys.path中的测试文件目录运行测试,但不是运行py.test的目录 为了解决这个问题,我在tests目录中添加了一个conftest.py文件

我有一个项目目录结构,如下所示(我认为这是相当标准的):

我正在使用py.test作为我的测试框架,我希望在
my_project
目录中运行测试时能够运行
py.tests
。这确实有效,直到我尝试在测试中使用(例如)
import mypkg
导入我的应用程序代码。在这一点上,我得到了错误“没有名为mypkg的模块”。在进行一点调查后,似乎
py.test
使用
sys.path
中的测试文件目录运行测试,但不是运行
py.test
的目录

为了解决这个问题,我在
tests
目录中添加了一个
conftest.py
文件,其中包含以下代码:

import sys, os

# Make sure that the application source directory (this directory's parent) is
# on sys.path.

here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, here)
这似乎是可行的,但这是确保测试看到应用程序代码的好方法吗?有没有更好的方法来实现这一点,或者我的项目结构有问题吗

我看过其他一些使用
py.test
(例如,
pip
)的项目,但我看不到这样做的代码,而且运行
py.test测试似乎在那里工作。我不知道为什么,但我担心他们可能会以更简单的方式取得同样的结果


我已经查看了py.test的
documentation,但是我看不到关于这个问题的解释,也看不到处理这个问题的推荐方法。

正如您所说的那样,py.test基本上假设您正确设置了PYTHONPATH。有几种方法可以实现这一点:

  • 为您的项目提供一个setup.py,并在此项目的虚拟环境中使用
    pip install-e.
    。这可能是标准方法

  • 如果您有一个virtualenv但没有setup.py,则使用venv的工具在sys.path上添加项目目录,例如,如果您使用pew,则使用pew add.
;如果您使用virtualenv和VirtualEnvrapper的扩展,则使用
add2virtualenv.

  • 如果您总是喜欢sys.path上的当前工作目录,您只需在shell中导出
    PYTHONPATH='
    。这就是确保sys.path上的空字符串,python将其解释为当前工作目录。但这可能会造成安全隐患

  • 我自己最喜欢的黑客,滥用py.test加载conftest文件的方式:在项目的顶级目录中放置一个空的
    conftest.py


  • py.test以这种方式运行的原因是,可以很容易地针对安装的包在签出的tests/目录中运行测试。如果它将无条件地将项目目录添加到PYTHONPATH,那么这将不再可能了。

    答案实际上要简单得多,如图所示

    您所需要做的就是向测试目录及其每个子目录添加一个
    \uuuu init\uuuu.py
    ,如下所示

    tests/__init__.py
    tests/functional/__init__.py
    tests/unit/__init__.py
    

    简单的方法是,在terminal/cmd中将目录更改为父目录所在的位置(例如,在本例中,
    cd C:/…/my_project

    然后运行:
    python-mpytest--cov=mypkg测试

    无需处理
    PYTHONPATH
    环境变量。 通过使用
    python-m pytest运行,它会自动将当前目录添加到引用单个/多个包的
    sys.path

    运行pytest 一包

    PYTHONPATH=$(pwd)/mypkg/python3-m pytest
    #或
    PYTHONPATH=$(pwd)/mypkg/python3-m pytest路径/to/tests
    
    适用于2个包装(pkg1 pkg2)


    只是补充一点:如果你没有virtualenv,你可以使用“python setup.py develope”来达到同样的效果。conftest.py hack是个好主意!!!太糟糕了,这是一种虐待,看来它可能会消失:(安装一些东西来运行测试???使用更多的工具只是为了让测试运行程序工作???操纵Python路径,这是从来不推荐的,并且在项目中移动某些东西时必须再次进行更改???--不!添加一个空文件似乎是最简单的解决方案!我不知道为什么它能工作,但我很高兴它能工作。其他选项似乎完全错了,直到有人向我解释为什么我需要安装一些东西来测试它,而我已经有了所有的代码。@PascalVKooten最近讨论了为什么这个
    conftest.py
    hack“有效”,以及为什么
    pytest
    不“撤销”这是导入后的
    sys.path
    修改。@Zelphir至于为什么要先安装一些东西来测试它,那么,你可以把它看作也是测试安装程序本身的一种方法。没有这一步,完全有可能有一个通过测试的套件,却有一个坏掉的安装程序(最终您意外地发布了一个损坏的包)。这实际上是在包中添加了测试。这可能并不总是需要的。-1因为在@BrianBruggeman中明确不鼓励这样做,我认为
    packages=find_包(exclude=['contrib','docs','tests'])
    在setup.py中解决了这个问题?@wim,doc现在提供了两种方案-在应用程序包内部或外部进行测试,所以我认为这现在是一个有效的选项,在实践中,@alensijak仍然鼓励使用
    /tests
    ,并且不鼓励在代码结构中使用
    tests
    文件夹。仍然存在不一致的问题使用pytest的一些插件(我主要使用coverage、isort和flake8)执行ent行为.这就是说,我已经开始将单元测试放在代码库的
    tests
    文件夹中,将集成/系统级测试放在top/tests文件夹中,这对我来说很好。+1这是一个合法且有文档记录的功能,而不仅仅是一个意外。请参阅
    tests/__init__.py
    tests/functional/__init__.py
    tests/unit/__init__.py
    
    # Use ; as a separator in windows
    PYTHONPATH=/path/to/pkg1/:/path/to/pkg2/ python3 -m pytest tests