我使用easy_install在Mac上安装pytest,并开始为一个具有如下文件结构的项目编写测试:

repo/
   |--app.py
   |--settings.py
   |--models.py
   |--tests/
          |--test_app.py

py运行。在repo目录中进行测试,一切都如您所料。

但是当我在Linux或Windows上尝试同样的事情时(两者都有pytest 2.2.3),每当它第一次从我的应用程序路径导入某些东西时,它就会发出吠叫。例如,from app import some_def_in_app。

我需要编辑我的PATH来运行py。测试这些系统?


当前回答

我不确定为什么是py。test不会在PYTHONPATH本身中添加当前目录,但这里有一个变通方法(从存储库的根目录执行):

python -m pytest tests/

它能工作是因为Python为你在PYTHONPATH中添加了当前目录。

其他回答

我开始得到奇怪的ConftestImportFailure: ImportError('没有模块命名…错误时,我不小心添加__init__.py文件到我的src目录(这不是一个Python包,只是一个容器的所有源代码)。

如果这个pytest错误不是出现在您自己的包上,而是出现在包的requirements.txt中的git安装包上,解决方案是切换到可编辑的安装模式。

例如,假设你的包的requirements.txt有如下一行:

git+https://github.com/foo/bar.git

您可以将其替换为以下内容:

-e git+https://github.com/foo/bar.git#egg=bar

我通过删除源文件父文件夹中的顶层__init__.py来解决这个问题。

此外,如果在虚拟环境中运行pytest,请确保在虚拟环境中安装了pytest模块。激活虚拟环境并运行pip install pytest。

pytest>=7的推荐方法:使用pythonpath设置

最近,pytest增加了一个新的核心插件,该插件支持sys。通过pythonpath配置值修改路径。因此,现在的解决方案要简单得多,不再需要任何变通:

pyproject。toml例子:

[tool.pytest.ini_options]
pythonpath = [
  "."
]

pytest.ini例子:

[pytest]
pythonpath = .

路径条目是相对于根目录计算的,因此。将repo目录添加到sys。路径。

多个路径条目也被允许:对于一个布局

repo/
├── src/
|   └── lib.py
├── app.py
└── tests
     ├── test_app.py
     └── test_lib.py

配置

[tool.pytest.ini_options]
pythonpath = [
  ".", "src",
]

or

[pytest]
pythonpath = . src

将app和lib模块都添加到sys。路径,所以

import app
import lib

都可以。

原始答案(不建议用于最新的pytest版本;仅用于pytest<7): conftest解决方案

侵入性最小的解决方案是在repo/目录中添加一个名为conftest.py的空文件:

$ touch repo/conftest.py

就是这样。不需要编写自定义代码来破坏系统。path,或者记得拖拽PYTHONPATH,或者把__init__.py放到不属于它的dirs中(在Apteryx的回答中建议使用python -m pytest是一个很好的解决方案!)

之后的项目目录:

repo
├── conftest.py
├── app.py
├── settings.py
├── models.py
└── tests
     └── test_app.py

解释

Pytest在测试集合中寻找conftest模块来收集自定义钩子和fixture,为了从它们导入自定义对象,Pytest将conftest.py的父目录添加到sys. py目录中。路径(在本例中为repo目录)。

其他项目结构

如果你有其他的项目结构,将conftest.py放在包的根目录下(包含包但本身不是包,所以不包含__init__.py),例如:

repo
├── conftest.py
├── spam
│   ├── __init__.py
│   ├── bacon.py
│   └── egg.py
├── eggs
│   ├── __init__.py
│   └── sausage.py
└── tests
     ├── test_bacon.py
     └── test_egg.py

src布局

虽然这种方法可以用于src布局(将conftest.py放在src dir中):

repo
├── src
│   ├── conftest.py
│   ├── spam
│   │   ├── __init__.py
│   │   ├── bacon.py
│   │   └── egg.py
│   └── eggs 
│       ├── __init__.py
│       └── sausage.py
└── tests
     ├── test_bacon.py
     └── test_egg.py

注意,将src添加到PYTHONPATH会降低src布局的意义和好处!您最终将测试来自存储库的代码,而不是安装的包。如果你需要这样做,也许你根本不需要src目录。

从这里往哪里走

当然,conftest模块不仅仅是一些帮助发现源代码的文件;pytest框架的所有特定于项目的增强和测试套件的定制都发生在这里。Pytest有很多关于conftest模块的信息,分散在它们的文档中;从conftest.py开始:本地每个目录的插件

另外,SO有一个关于conftest模块的很好的问题:在py中。测试,conftest。py文件有什么用?