Python中pytest命令行实现环境切换
作者:知识的宝藏
前言
在自动化测试过程中经常需要在不同的环境下进行测试验证,所以写自动化测试代码时需要考虑不同环境切换的情况。pytest钩子函数pytest_addoption可以很好帮我们解决这个痛点。
pytest_addoption(parser, pluginmanager)
注册argparse样式选项和ini样式配置值,在测试运行开始时调用一次。
注意:
由于pytest在启动过程中如何发现插件,因此该函数只能在位于测试根目录的插件或conftest.py文件中实现。
参数
parser(pytest.parser)–若要添加命令行选项,请调用parser.addoption(…)。若要添加ini文件值,请调用解析器.addini(…)。
pluginmanager(pytest.PytestPluginManager)–pytest插件管理器,可用于安装hookspec()或hookpimpl(),并允许一个插件调用另一个插件的钩子来更改命令行选项的添加方式。
以后可以分别通过配置对象访问选项:
config.getoption(name)来检索命令行选项的值。
config.getini(name)来检索从ini样式文件中读取的值。
config对象通过.config属性在许多内部对象上传递,或者可以作为pytestconfig fixture检索。
在conftest.py文件中定义命令行参数
def pytest_addoption(parser): """ 添加命令行参数 parser.addoption为固定写法 default 设置一个默认值,此处设置默认值为sit choices 参数范围,传入其他值无效 help 帮助信息 """ parser.addoption( "--env", default="sit", choices=["dev", "sit", "uat"], help="环境参数" )
我们定义了不同环境下的命令参数:dev、sit、uat,我们怎么获取运行的命令行参数呢?
获取命令行参数
@pytest.fixture(scope="session") def get_env(request): return request.config.getoption("--env")
设置不同环境的全局变量
在不同的测试环境下,URL、用户信息等数据都是不一样的,建议在conftest中给全局变量赋值可以减少代码冗余。
先定义一个数据文件,data_util.py分别获取用户信息和URL信息
def get_env(): env = { 'sit': 'www.baidu.com', 'uat': 'www.hao123.com' } return env def get_user(): users = { 'sit': ['user1', 'pwd1'], 'uat': ['user2', 'pwd2'] } return users
然后在conftest中根据环境设置全局变量值
# 设置不同环境下的全局变量 @pytest.fixture(scope="session") def set_env(get_env): if get_env == 'sit': env_url = data_util.get_env()['sit'] user = data_util.get_user()['sit'] if get_env == 'uat': env_url = data_util.get_env()['uat'] user = data_util.get_user()['uat'] return {'env_url': env_url, 'user': user}
注意fixture的使用范围为整个测试会话。
以下是完整的conftest
import pytest import data_util def pytest_addoption(parser): """ 添加命令行参数 parser.addoption为固定写法 default 设置一个默认值,此处设置默认值为sit choices 参数范围,传入其他值无效 help 帮助信息 """ parser.addoption( "--env", default="sit", choices=["dev", "sit", "uat"], help="环境参数" ) @pytest.fixture(scope="session") def get_env(request): return request.config.getoption("--env") # 设置不同环境下的全局变量 @pytest.fixture(scope="session") def set_env(get_env): if get_env == 'sit': env_url = data_util.get_env()['sit'] user = data_util.get_user()['sit'] if get_env == 'uat': env_url = data_util.get_env()['uat'] user = data_util.get_user()['uat'] return {'env_url': env_url, 'user': user}
定义测试类及测试方法
注意fixture不能在x-unit风格下的setup\teardown中引用,因此需要使用fixture定义setup、teardown方法才能引用到conftest里的fixture,一般我们在setup方法中初始化环境变量具体如下:
@pytest.fixture() def class_fixture(set_env): print('setup_class') url = set_env.get('env_url') user = set_env.get('user') print(url, user) yield print('teardown class')
这样我们就在测试前把环境信息设置OK了。
测试验证
以下是测试方法
import pytest pytestmark = pytest.mark.usefixtures("module_fixture") @pytest.fixture(scope="module", params=["test_fixture"]) def module_fixture(request): param = request.param print(" SETUP module", param) yield param print(" TEARDOWN module", param) @pytest.fixture() def class_fixture(set_env): print('setup_class') url = set_env.get('env_url') user = set_env.get('user') print(url, user) yield print('teardown class') @pytest.fixture(scope="function", params=[1, 2]) def function_fixture(request): param = request.param print(" SETUP function", param) yield param print(" TEARDOWN function", param) @pytest.mark.usefixtures('class_fixture') class TestFixture: def test_0(self, function_fixture): print(" RUN test0 with function_fixture", function_fixture) def test_1(self, module_fixture): print(" RUN test1 with module_fixture", module_fixture) def test_2(self, function_fixture, module_fixture): print(f" RUN test2 with function_fixture {function_fixture} and module_fixture {module_fixture}") def test_env(self, get_env): print(f"The current environment is: get_env") if __name__ == '__main__': pytest.main(['-v', '-s','--env=uat', 'test_fixture.py::TestFixture::test_0'])
我们首先填的uat命令运行,查看输出:
可以看出输出是正确的,我们再切换成sit试试:
if __name__ == '__main__': pytest.main(['-v', '-s','--env=uat', 'test_fixture.py::TestFixture::test_0'])
可以看出在不同的命令下获得的测试数据也不一样,这样我们就达到了环境切换的目的了~
到此这篇关于Python中pytest命令行实现环境切换的文章就介绍到这了,更多相关pytest 环境切换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!