Python 别再讨论平台了,大佬们来救救孩子吧

buggg · June 21, 2021 · Last by 测试开发体系 replied at June 22, 2021 · 3584 hits

pytest fixture 函数有没有办法给普通方法 (非 test 测试方法) 调用?

场景是这样的:
首先是增加了 2 个 pytest 命令行参数,env 和 project,然后定义了 一 个 fixture 函数,是获取项目环境配置的
然后 test 方法是执行 requests 请求接口,我是希望只传接口的 path,接口的域名根据我命令行的 env 和 project 去配置文件中读取出来,然后再拼接成完整的接口 url
这个拼接的过程我是想单独封装在一个 build_url 方法中,那么这个 build_url 方法要怎么能用到 pytest 的 fixture 方法呢?

或者有其他什么思路能解决我这个问题的?折磨我 2 天了
伪代码如下

import pytest
import requests


@pytest.fixture()
def env_config(request):
    """
    根据命令行参数获取配置文件数据
    :param request:
    :return:
    """
    config_path = Path(request.config.rootdir,
                       "config",
                       request.config.getoption("project"),
                       f'{request.config.getoption("environment")}.yaml')
    return Yaml(config_path).data


def request(path, method, data):
    return requests.request(method,build_url(path), json=data)


def build_url(path):
    # 这里怎么可以用到env_config这个fixture返回的数据?

    return host+path


def test_login():
    r = request('login', 'post', {'username': 'admin'})
    assert r.status_code == 200

共收到 15 条回复 时间 点赞
buggg #1 · June 21, 2021 Author

我知道在 test_login 里面传入 env_config 是可行的,但是太繁琐了,每个 test 方法都需要传,我想要在一个地方弄一次就行了。

buggg 回复

再加一个 wrapper?

fixture 在函数中也可以调用的吧

我的解决方法,用 Hook 函数 pytest_configure 接收所有自定义参数并写入 yaml 文件。后续用的时候读取一下文件即可

buggg #4 · June 22, 2021 Author
tester 回复

额 那我如果想同时运行 2 个项目,自定义参数的 project 值不一样,第二次运行的时候不是会覆盖?如果不想覆盖,就要用 project 名作为 key 去保存 yaml 了,那又绕回去了,怎么知道我当前运行的是哪个 project

buggg #5 · June 22, 2021 Author
恒温 回复

普通函数调用 fixture,要传入 request 参数,但是 request 参数又只能在运行时才有,所以就等于只能在 test 方法中才可以用。
不知道你说的再加一个 wrapper 是什么意思呢

把 build_url 也定义成 fixture,传参 env_config,再 autouse:

@pytest.fixture(autouser=True)
def build_url(env_config, path):

把你的数据保存到内存中去

buggg #8 · June 22, 2021 Author
aabbcc 回复

存到内存我取的时候,也得知道是哪个 project 额,关键是除了 fixture 外,没法知道这个变量的值

buggg 回复

存到内存为啥还要区分 project,不同的 project 用的肯定是不同的内存空间啊

buggg #10 · June 22, 2021 Author
aabbcc 回复

这样的吗,那是我理解出问题了。。。。假如先后运行 2 个 project A 和 B,相当于是 2 个进程在处理对吧,然后各自进程里面获取命令行参数就是自己开始传入的,不会后面的覆盖前面吗?

buggg 回复

不同进程用的是不同的内存块,不会影响的。

卡两天的话,不如想想这里是不是过度设计了,有必要再封装一个 request 方法吗?
用例里直接 requests.post(HOST+'login', json={}),可读性还强点
HOST 从配置文件取还是从命令行取就都比较简单了

buggg #13 · June 22, 2021 Author
MarvinWu 回复

request 还是有必要的,我们接口请求是加密的,需要预处理一层 data 加密。。我感觉这应该是个常见场景啊,或许是我的思路有问题

buggg #14 · June 22, 2021 Author

那这个 path 是怎么传递的呢

buggg 回复
@pytest.fixture(autouse=True)
def build_url(env_config):
    def host_path(path):
        return host + path
    return host_path
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up