Pytest测试配置管理及读取

环境相关的配置信息应放置到config文件夹中,比如host,数据库信息,测试账号等。很多时候,我们会有不同的测试环境,如test环境、dev环境、prod环境等。我们可以在config文件夹下面创建子目录来区分不同的测试环境。因此config文件夹,应该是类似这样的结构:

Pytest测试配置管理及读取

在config.yaml中存放不同环境的配置信息,以前面《pytest接口测试轻松入门》的天气查询接口测试为例,存放天气查询host应该是这样:

host:
  api: http://wthrcdn.etouch.cn

将测试配置信息从脚本中拆分出来,就需要有一种机制将其读取到,才能在测试脚本中使用。Pytest提供了fixture机制,通过它可以在测试执行前执行一些操作,在这里我们利用fixture提前读取到配置信息。
在之前,安装yaml文件支持,使用pip命令安装:

pip install pyyaml

在自动化测试项目testcase/目录中创建一个文件conftest.py,定义一个fixture函数env:

# 存储参数化数据和函数,模块下的用例执行时,会自动读取conftest.py文件中的数据
import os
import pytest
import yaml

#加载读取配置文件config.yaml
@pytest.fixture(scope="session")
def env(request):
    config_path = os.path.join(request.config.rootdir,
                               "config",
                               "test",
                               "config.yaml")
    with open(config_path) as f:
        env_config = yaml.load(f.read(), Loader=yaml.SafeLoader)
    return env_config

conftest.py文件是一个plugin文件,里面可以实现Pytest提供的Hook函数或者自定义的fixture函数,这些函数只在conftest.py所在目录及其子目录中生效。scope="session" 表示这个fixture函数的作用域是session级别的,在整个测试活动中开始前执行,并且只会被执行一次。(scope参数可以是session, module,class,function;默认为function。具体用法关注该 小酋 后续该专辑文章)
env函数中有一个参数request其实request也是一个fixture函数。在这里用到了它的request.config.rootdir属性,这个属性表示的是pytest.ini这个配置文件所在的目录,因为我们的测试项目中pytest.ini处于项目的根目录,所以config_path的完整路径就是:
D:/PYTEST/config/test/config.yaml
注意:当根目录下没有pytest.ini配置文件时,会默认指向conftest.py所在目录;此时要指向项目根目录,则在项目目录下新建一个 pytest.ini 空文件即可。
写一个简单的用例 test_simple.py,获取到对应的host并打印出来:

class TestMine(object):
    def testMyInfo(self,env):
        host = env["host"]["api"]
        print("
天气api的host地址:"+host)

pytest执行结果:

============================== 1 passed in 0.03s ==============================

Process finished with exit code 0
PASSED                              [100%]
天气api的host地址:http://wthrcdn.etouch.cn

说明:根据执行结果,成功获取到了配置文件中的天气api的host地址。

改写前面在《pytest接口测试轻松入门》的接口测试用例:

@allure.feature("测试Dome")
class TestSimple(object):
    @allure.story("天气查询")
    @allure.description('一个免费的天气查询接口测试')
    @allure.severity('critical')
    def testWatcher(self,env):
        host = env["host"]["api"]
        url = host + "/weather_mini?city=成都"
        with allure.step("查询天气"):
            r = requests.get(url)
            assert r.status_code == 200
            d = r.json()
            print(d)
            if ('wendu' not in d['data'].keys()):
                pytest.xfail('返回结果不正确,wendu=NULL')

执行结果:

============================== 1 passed in 0.25s ==============================

Process finished with exit code 0
PASSED                           [100%]{'data': {'yesterday': {'date': '6日星期三', 'high': '高温 29℃', 'fx': '无持续风向', 'low': '低温 21℃', 'fl': '<![CDATA[<3级]]>', 'type': '多云'}, 'city': '成都', 'aqi': '32', 'forecast': [{'date': '7日星期四', 'high': '高温 27℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 18℃', 'fengxiang': '无持续风向', 'type': '中雨'}, {'date': '8日星期五', 'high': '高温 26℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 16℃', 'fengxiang': '无持续风向', 'type': '阴'}, {'date': '9日星期六', 'high': '高温 26℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 15℃', 'fengxiang': '无持续风向', 'type': '阴'}, {'date': '10日星期天', 'high': '高温 29℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 17℃', 'fengxiang': '无持续风向', 'type': '多云'}, {'date': '11日星期一', 'high': '高温 26℃', 'fengli': '<![CDATA[<3级]]>', 'low': '低温 16℃', 'fengxiang': '无持续风向', 'type': '多云'}], 'ganmao': '各项气象条件适宜,无明显降温过程,发生感冒机率较低。', 'wendu': '22'}, 'status': 1000, 'desc': 'OK'}

这样就达到了测试配置文件与测试脚本相互分离的效果,如果需要修改host,只需要修改配置文件即可,测试脚本文件就不用修改了。修改完成后执行测试的方法不变。



留言