当项目中存在多个 pytest 配置文件时,pytest 会按照特定的优先级顺序来决定使用哪个文件。配置文件格式和优先级如下:

1. **`pytest.toml`**: 这是优先级最高的配置文件,无论内容是否为空,它都会被采纳。
2. **`pytest.ini`**: 它的优先级高于 `pytest.toml` 和 `.pytest.toml`(如果存在),即使内容为空,它也会被采纳。
3. **`pyproject.toml`**: 该文件支持配置,需要包含 `[tool.pytest]` 或 `[tool.pytest.ini_options]` 表格才能被识别为配置源。
4. **`tox.ini`**: 如果它包含 `[pytest]` 部分,也可以被用作 pytest 的配置。
5. **`setup.cfg`**: 如果它包含 `[tool:pytest]` 部分,也可以被用作 pytest 的配置。

**配置文件查找的整体流程和优先级(从最高到最低):**

* **`pytest.toml`**:最高优先级。
* **`pytest.ini`**:次高优先级(在 `pytest.toml` 之后)。
* **`pyproject.toml`**:如果前两者未匹配,且包含特定表格。
* **`tox.ini`**:如果包含 `[pytest]` 部分。
* **`setup.cfg`**:如果包含 `[tool:pytest]` 部分。

**注意点:**
* 选项来自多个配置文件候选源时,**第一个匹配到的文件**的选项会胜出,选项不会被合并。
* `pytest.toml` 总是匹配并具有最高优先级。
* `pytest.ini` 总是匹配并具有高优先级(在 `pytest.toml` 之后)。

**关于 `rootdir` 的确定算法:**

`pytest` 确定 `rootdir` 的过程依赖于命令行参数(指定的测试文件或路径)和配置文件的存在情况。其算法流程如下:

1. **命令行指定 `-c` 选项**:如果命令行传入了 `-c` 选项,则使用该选项指定的路径作为配置文件,并且其所在目录被确定为 `rootdir`。
2. **基于路径参数确定共同祖先**:首先,pytest 会确定所有作为路径参数传入的、且在文件系统中存在的参数的**共同祖先目录**。如果找不到这样的路径,则默认使用当前工作目录作为共同祖先。
3. **向上查找配置文件**:在上述确定的共同祖先目录及其上级目录中,pytest 会按特定顺序查找配置文件(`pytest.toml`, `.pytest.toml`, `pytest.ini`, `.pytest.ini`, `pyproject.toml`, `tox.ini`, `setup.cfg`)。一旦匹配到配置文件,该文件的目录即被确定为 `rootdir`。
4. **查找 `setup.py`**:如果在前述步骤中没有找到配置文件,则从共同祖先目录向上查找 `setup.py` 来确定 `rootdir`。
5. **最终回退**:如果以上所有查找均失败,则使用最初确定的共同祖先目录作为 `rootdir`。如果根本没有参数传入,则从当前工作目录开始确定 `rootdir`。

**总结:**
* **配置文件优先级**:`pytest.toml` > `pytest.ini` > `pyproject.toml` (带特定表) > `tox.ini` (带 `[pytest]`) > `setup.cfg` (带 `[tool:pytest]`)。
* **`rootdir` 确定**:优先检查 `-c` 选项;否则,基于命令行参数的共同祖先目录,并向上查找配置文件或 `setup.py` 来确定最终的根目录。

(注:`--rootdir=path` 命令行选项可以强制指定 `rootdir`,但它不能与配置文件中的 `addopts` 一起使用,因为 `rootdir` 是用于查找配置文件的基础。)

信息来源