8、Fixture带返回值
在fixture
中我们可以使用yield
或者return
来返回我们需要的东西,如测试数据,数据库连接对象,文件对象等。
- 没有后置处理
直接采用return
的方式返回数据(yield
也可以)
import pytest
@pytest.fixture()
def data_fixture():
return ["a", "b", "c"]
def test_case(data_fixture):
print(f"测试数据为:{data_fixture}")
"""
执行结果
fixture/yield_data.py::test_case 测试数据为:['a', 'b', 'c']
PASSED
"""
- 有后置处理
- 使用
yield
返回数据,在yield
下面添加后置处理
import pytest
@pytest.fixture()
def data_fixture():
print("【前置】")
yield ["a", "b", "c"]
print("【后置】")
def test_case(data_fixture):
print(f"测试数据为:{data_fixture}")
"""
执行结果
fixture/yield_data.py::test_case 【前置】
测试数据为:['a', 'b', 'c']
PASSED【后置】
"""
- 使用
return
返回数据,通过addfinalizer
注册后置处理
import pytest
@pytest.fixture()
def data_fixture(request):
print("【前置】")
def addfinalizer_demo():
print("【后置】")
request.addfinalizer(addfinalizer_demo)
return ["a", "b", "c"]
def test_case(data_fixture):
print(f"测试数据为:{data_fixture}")
"""
执行结果
fixture/return_data.py::test_case 【前置】
测试数据为:['a', 'b', 'c']
PASSED【后置】
"""
9、Fixture实现参数化
可以通过fixture
的params
参数来实现参数化。(有更好的参数化方式,故此方法不常用)
示例1:
import pytest
data = [("张三","男"), ("李四","女")]
@pytest.fixture(params=data)
def fixture_data(request):
print("【前置】")
def addfinalizer_demo():
print("【后置】")
request.addfinalizer(addfinalizer_demo)
return request.param
def test_case(fixture_data):
print(fixture_data[0], fixture_data[1])
"""
执行结果
fixture/fixture_params.py::test_case[fixture_data0] 【前置】
张三 男
PASSED【后置】
fixture/fixture_params.py::test_case[fixture_data1] 【前置】
李四 女
PASSED【后置】
"""
示例2:通过ids
参数为每个用例取别名
import pytest
data = [("张三","男"), ("李四","女")]
@pytest.fixture(params=data,ids=["Developer", "Tester"])
def fixture_data(request):
print("【前置】")
def addfinalizer_demo():
print("【后置】")
request.addfinalizer(addfinalizer_demo)
return request.param
def test_case(fixture_data):
print(fixture_data[0], fixture_data[1])
"""
执行结果
fixture/fixture_params_ids.py::test_case[Developer] 【前置】
张三 男
PASSED【后置】
fixture/fixture_params_ids.py::test_case[Tester] 【前置】
李四 女
PASSED【后置】
"""
总结:
- 通过
params
参数实现参数化需要用到request
关键字,通过return request.param
将测试数据返回。 params
中有多少数据,ids
就必须对应多少参数,脱离使用params
实现参数化,ids
将毫无意义。params
支持的参数格式:- 列表
[]
- 元祖
()
- 元祖列表
[(),(),()]
- 字典列表
[{},{},{}]
- 字典元祖
({},{},{})
- 列表
10、可靠的Fixture写法
假如,我们有一个登录页面,需要进行登录测试。为了方便测试,我们还有一个管理员的api,可以直接调用来生成测试用户。那么,这个测试场景通常会这样去构建:
- 通过管理API创建一个用户
- 使用Selenium启动浏览器
- 进入我们网站的登录页面
- 使用创建好的用户进行登录
- 断言登录后的用户名出现在登录页的页眉中
(一)一个不可靠Fixture的例子
说明:该例子不可执行,仅做示例
import pytest
from selenium import webdriver
import AdminApiClent
import LoginPage
import IndexPage
from urllib.parse import urljoin
base_url = "https:xxx.com"
username = "xxx"
@pytest.fixture()
def setup_fixture():
# 【前置处理】
# 1、通过AdminApiClent创建一个用户
client = AdminApiClent()
client.create_user(username)
# 2、获取驱动对象
driver = webdriver.Chrome()
# 3、打开登录页
driver.(urljoin(base_url,"/login"))
# 4、执行登录操作
login_page = LoginPage(driver)
login_page.login(username)
yield username
# 【后置处理】
# 1、关闭浏览器
driver.quit()
# 2、删除用户
client.del_user(username)
# 3、退出AdminApiClent
client.quit()
def test_login_success(setup_fixture):
# 断言登录后用户名是否出现在首页
assert setup_fixture == IndexPage.username
上面例子存在的问题:
- 在
setup_fixture
这一个fixture
函数中做的事情太多,很多步骤不容易重用。 - 假设
setup_fixture
中yield
之前出现异常,后置处理不会执行。(虽然可以使用addfinalizer
,但是不易维护和重用)
(二)修改成可靠Fixture的例子
说明:该例子不可执行,仅做展示
import pytest
from selenium import webdriver
import AdminApiClent
import LoginPage
import IndexPage
from urllib.parse import urljoin
base_url = "https:xxx.com"
username = "xxx"
# 处理AdminApiClient
@pytest.fixture(name="client")
def AdminApiClient_fixture():
client = AdminApiClent()
yield client
client.quit()
# 处理用户
@pytest.fixture()
def user_fixture(client):
client.create_user(username)
yield username
client.del_user(username)
# 处理驱动
@pytest.fixture()
def driver_fixture():
driver = selenium.Chrome()
yield driver
driver.quit()
# 处理登录
@pytest.fixture()
def login_fixture(driver_fixture, user_fixture):
driver_fixture.get(urljoin(base_url, "/login"))
login_page = LoginPage(driver_fixture)
login_page.login(user_fixture)
# 处理首页
@pytest.fixture()
def index_fixture(driver_fixture):
return IndexPage(driver_fixture)
# 断言
def test_login_success(login_fixture,index_fixture,user_fixture):
assert user_fixture == index_fixture.username
这么改造的优点:
- 每一步都单独进行了封装,提高了复用性
- 假设运行中
user_fixture
报错了,那么不影响driver_fixture
关闭浏览器 - 假设运行中
driver_fixture
报错了,那么根本就不会执行user_fixture
参考
https://www.cnblogs.com/liuyuelinfighting/p/15999810.html
https://zhuanlan.zhihu.com/p/359125816
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Pytest框架 — 08、Pytest的Fixture(部分前后置)(三) - Python技术站