自定义命令行参数是必用的功能,对一些测试环境的配置,比如你在测试中需要用SSH连接某台服务器, 那么就需要提供地址和用户名密码,当然你可以把这些信息写在配置文件中,但这不得不额外维护一份表, 在一些场景中会显得不够灵活。好的方法则是直接通过命令行参数传递变量。pytest使用hook函数 pytest_addoption自定义命令行参数,被调用于初始化阶段,用法非常像Python的optpaser模块。
conftest.py
def pytest_addoption(parser):
parser.addoption("--ip_type", action="store", default="loopback",
help="ip type includes loopback, domain and local_network")
test_ping.py
import os
import re
import pytest
import time
def get_ping_response(ip_addr):
pid = os.popen("ping " + ip_addr)
prompt = pid.read()
m = re.search(r"Sent = (d+), Received = (d+), Lost = (d+) ((d+)% loss)", prompt)
sent_num = int(m.group(1))
recv_num = int(m.group(2))
lost_num = int(m.group(3))
lost_rate = int(m.group(4))
return sent_num, recv_num, lost_num, lost_rate
def test_case(request):
ip_type = request.config.getoption("ip_type")
if ip_type == "loopback":
assert get_ping_response("127.0.0.1")[3] == 0
elif ip_type == "local":
assert get_ping_response("192.168.1.1")[3] == 0
else:
raise Exception("failure")
在conftest中 我们在钩子函数pytest_addoption加入命令行参数ip_type, 然后我们测试函数test_case里利用内置fixture request,获取命令行参数值,实现测试逻辑。
运行结果
C:UsersthinkPycharmProjectslearnpytestping_test>pytest -s --ip_type loopback test_ping.py::test
_case
Test session starts (platform: win32, Python 3.7.0, pytest 5.1.3, pytest-sugar 0.9.2)
rootdir: C:UsersthinkPycharmProjectslearnpytestping_test, inifile: pytest.ini
plugins: allure-pytest-2.8.11, assume-2.2.0, html-2.0.0, metadata-1.8.0, sugar-0.9.2
collecting ...
test_ping.py √ 100% ██████████
Results (3.06s):
1 passed
C:UsersthinkPycharmProjectslearnpytestping_test>pytest -s --ip_type unknown test_ping.py::test_
case
Test session starts (platform: win32, Python 3.7.0, pytest 5.1.3, pytest-sugar 0.9.2)
rootdir: C:UsersthinkPycharmProjectslearnpytestping_test, inifile: pytest.ini
plugins: allure-pytest-2.8.11, assume-2.2.0, html-2.0.0, metadata-1.8.0, sugar-0.9.2
collecting ...
???????????????????????????????????????????? test_case ????????????????????????????????????????????
request = <FixtureRequest for <Function test_case>>
def test_case(request):
ip_type = request.config.getoption("ip_type")
if ip_type == "loopback":
assert get_ping_response("127.0.0.1")[3] == 0
elif ip_type == "local":
assert get_ping_response("192.168.1.1")[3] == 0
else:
> raise Exception("failure")
E Exception: failure
test_ping.py:24: Exception
test_ping.py ? 100% ██████████
failure in call step...capture log
Results (0.10s):
1 failed
- test_ping.py:17 test_case