自动化工具 pytest 接口自动化-用多个 conftest.py 时会报错:in _importconftest return self._conftestpath2mod [conftestpath] KeyError: local ('D:\\conftest.py')

王子夜 · 2020年11月02日 · 最后由 王子夜 回复于 2020年11月16日 · 3115 次阅读

各位大神,最近使用 pytest 框架做接口自动化,但是遇到一个问题,当使用多个 conftest.py 的时候就会报如下错误,请各位大神帮忙看看:

[2020-11-02 00:02:19,100][read_data.py 36][INFO]: 加载 D:\RwglinkApiTest\config\setting.ini 文件......
Traceback (most recent call last):
  File "C:\Python\Python36\lib\site-packages\_pytest\config\__init__.py", line 415, in _importconftest
    return self._conftestpath2mod[conftestpath]
KeyError: local('D:\\testcase\\scenario_test\\conftest.py')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python\Python36\lib\site-packages\pymysql\connections.py", line 571, in connect
    **kwargs)
  File "C:\Python\Python36\lib\socket.py", line 724, in create_connection

目录结构如下图:

test case 的 package 下的 conftest.py,我做了 yaml 文件数据的读取,如下面的代码和图:

import pytest
import os
from common.read_data import data_reader

BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

def get_data(yaml_file_name):
    try:
        data_file_path = os.path.join(BASE_PATH, "data", yaml_file_name)
        yaml_data = data_reader.load_yaml(data_file_path)
    except Exception as ex:
        pytest.skip(str(ex))
    else:
        return yaml_data


base_data = get_data("base_data.yml")
api_data = get_data("api_test_data.yml")

test case 中 scenario_test 的 package 中的 conftest.py, 我引用了外层的 conftest.py 中的读取数据方法,然后做了一个@pytest.fixture(scope="session") 函数做数据的初始化和删除,如下图:

同样,test case 中 basic_func_project 的 package 中的 conftest.py, 我也引用了外层的 conftest.py 中读取的方法,然后做了一个@pytest.fixture(scope="session") 函数做数据的初始化和删除,如下图:

但是当我选中某个 test case 的方法在 pycharm 中 RUN 的时候就会报错:

共收到 13 条回复 时间 点赞

请各位 python 大神帮忙看看,究竟这里是什么问题,非常感谢

有 python 自动化的大神,有看到的,请帮小弟一下,被这个问题困扰了 2 天了,头疼啊

conftest 之间不要相互引用,pytest 会找不到路径。

好,谢谢,我试一下看看

conftest 不支持 import 引用,需要使用@pytest.mark.usefixtures('需要引用的 conftest 里面的方法'),你可以找下这个资料看下

conftest 是用来写前置后后置的吧?你外层 conftest 中的 get_data 函数不用 fixture 的话你放到别的 py 文件里面,你如果用 fixture 的话你的 get_data 方法加个 pytest.fixture 的装饰器,然后你二层 conftest 直接用 get_data 就行了,不用导入,

# 外层conftest
@pytest.fixture(scope="xx")
def get_data():
    pass

# 内层conftest
@pytest.fixture(scope="xx")  # 这里scpoe的级别要小于等于外层的级别
def xxxx(get_data):
    pass

# 要注意这里fixture的调用顺序是 get_data 前置--> xxx 前置 --> xxx后置 --> get_data 后置

如有不对,请指正😵 😵

确定不能引用吗? 我这边写的像这样的结构,basic_func_project 可以引用 test case 下的 conftest;
但是如果是 conftest 还引用了其他的包(AAA),然后 test_xxx.py 也引用了对应的包 (AAA),这样似乎就会有问题。

测试新手 回复

确定,我在官方英文教程上面看到过这句话,原文一时找不到了。

原文?
If you have conftest.py files which do not reside in a python package directory (i.e. one containing an init.py) then “import conftest” can be ambiguous because there might be other conftest.py files as well on your PYTHONPATH or sys.path.
It is thus good practise for projects to either put conftest.py under a package scope or to never import anything from a conftest.py file.

测试新手 回复

fixture 本身就会自动查找到的,from conftest import some_fixture,我觉得是没有必要的。把 conftest.py 中的函数都定义成 fixture,就能避免这些问题。

感谢各位大神呀,受益良多

还是按照官网文档来把,最好不要互相引用

王子夜 关闭了讨论 11月16日 10:42
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册