一、引言:
1)setup和teardown:实现全部用例的前后置;但实际应用中,我们需要更为灵活的配置部分用例的前后置;
2)fixture():fixture固件,或者夹具,能实现部分或者全部用例的前后置; fixture是个装饰器,可以用来装饰函数,类等
- fixture命名规则较灵活,可以随意命名
- fixture的前后置通过关键字yield进行区分,yield前的代码为前置操作,yield后的代码为后置操作
- 前后置操作可单独存在:即可以只有前置操作,也可以只有后置操作
二、fixture的应用:
- 定义一个函数
- 通过装饰器的方法将其变成fixture
@pytest.fixture()
def exe_database_sql():
print(“执行SQL查询语句”) - 需要对应前后置的用例,将fixture的名称通过传参的形式进行调用
def test_tangseng(self,exe_database_sql):
print(“0130类测试登录成功-唐僧”)
import pytest
@pytest.fixture()
def exe_database_sql():
print("执行SQL查询语句")
class TestLoginA():
def test_tangseng(self,exe_database_sql):
print("0130类测试登录成功-唐僧")
def test_sunwukong(self):
print("0130测试登录成功-孙悟空")
def test_zhubajie(self):
print("0130测试登录成功-猪八戒")
def test_shaheshang(self):
print("0130测试登录成功-沙和尚")
三、fixture的5个参数详解,其一:scope(作用域)
scope:控制fixture的作用范围:session>module>class>function,fixture默认的scope是function;
(1)function:在函数或方法之前和之后都会调用
1.手动调用的方式:在测试用例的参数中加入fixture的名称
2.如果fixture通过return或者yield存在返回值时,可以将对应的值传递到测试用例当中,值是通过fixture的名字传递的–数据驱动,用例的参数化
import pytest
#作用域为function
@pytest.fixture(scope="function")
def my_fixture():
print("这是前置的方法,可以实现部分以及全部用例的前后置")
yield
print("这是后置的方法,可以实现部分以及全部用例的前后置")
class TestLogin:
def test_login_01(self):
print("\n测试01号登录成功")
# my_fixture函数可以当参数,传入来调用
def test_login_02(self,my_fixture):
print("\n测试02号登录成功")
def test_login_03(self):
print("\n测试03号登录成功")
def test_login_04(self):
print("\n测试04号登录成功")
def test_login_05(self):
print("\n测试05号登录成功")
(2)class:在每一个类之前和之后执行(一个类中可以有多个方法)
1.手动调用的方式:在类的上面加上@pytest.mark.usefixtures(“exe_database_sql”)装饰器,进行调用
import pytest
from common.common_util import CommonUtil
@pytest.fixture(scope="class",autouse=False)
def exe_database_sql():
print("执行SQL查询语句")
return ":success"
@pytest.mark.usefixtures("exe_database_sql")
class TestLoginA(CommonUtil):
def test_tangseng(self):
print("0130类测试登录成功-唐僧")
def test_sunwukong(self):
print("0130测试登录成功-孙悟空")
(3)module:每一个.py文件调用一次,该文件内又有多个function和class
(4)session:在整个项目会话之前和之后执行,是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module
一般会结合conftest.py文件来实现
三、fixture的5个参数详解,其二:autouse(自动调用)
autouse:控制fixture是否自动被调用,自动执行,默认是False
-False:默认是 Fasle 没开启的,需要主动调用,才会执行该前后置
-True:设置为True 开启,则自动调用:即不用再手动传参就可以自动调用fixture运行该前后置
三、【重要】fixture的5个参数详解,其三:params(参数化)
params:用来实现参数化,用于做数据驱动
- 通过request参数,用来接收fixture的返回结果,并通过request.param返回结果内容----是固定用法(request.param这里是不用带s,一个一个读取list中的参数)
- list中有N组参数数据,用例就会执行N次
- 所有的数据驱动,都要用list格式[‘张三’,‘李四’,‘王五’]
import pytest
@pytest.fixture(scope="function",params=['张三','李四','王五'])
def my_fixture(request):
print("这是前置的方法,可以实现部分以及全部用例的前后置")
yield request.param
print("这是后置的方法,可以实现部分以及全部用例的前后置")
class TestLogin:
def test_login_01(self):
print("\n测试01号登录成功")
# 函数可以当参数,传入来调用
def test_login_02(self,my_fixture):
print("\n测试02号登录成功",str(my_fixture))
print('------------------\n'+str(my_fixture))
def test_login_03(self):
print("\n测试03号登录成功")
def test_login_04(self):
print("\n测试04号登录成功")
def test_login_05(self):
print("\n测试05号登录成功")
注意:
@pytest.fixture(scope=“function”,params=[‘张三’,‘李四’,‘王五’]),是参数名,有s
yield request.param,是属性名,没有s,是固定写法。
三、fixture的5个参数详解,其四:ids(参数别名)
ids:不能单独使用,必须和params一起使用,作用是:对参数化的内容加标识,对参数起别名
对参数化的内容起别名,让别人知道这个传入的参数是什么意思
默认是:传参数内容
作用不大
三、fixture的5个参数详解,其五:name(对fixture重命名)
name:表示对fixture的名称进行重命名
- 一旦重命名后,只能用别名
- 原fixture的名称就不能再用,直接调用原fixture会报错
- 得用双引号括起来,如:name=“db”
@pytest.fixture(scope="function",params=reader,ids=['A','B','C'],name="db")
四、【重要】fixture结合conftest.py文件使用:
—fixture可以放在conftest中使用。
conftest.py配置需要注意以下点:
- conftest.py:名称固定,不能改名称;是专门用于存放fixture的配置文件;
- 不需要import导入conftest.py,pytest用例会自动查找;
- conftest.py与运行的用例最好在同一个pakage下,作用域:只对当前包起作用;
- conftest.py文件可以有多个,并且多个conftest.py文件里面的多个fixture可以被同一个用例调用;
- scope=“session” 实现多个.py跨文件使用一个session来完成多个用例。
# Time:2022 2022/2/23 13:42
# -*- coding: utf-8 -*-
import pytest
import uiautomator2 as u2
import time
@pytest.fixture(scope="session", autouse=True)
def device():
d = u2.connect()
d.unlock()
time.sleep(1)
pkg_name = 'com.taobao.taobao'
currentApp = d.app_list_running()
if pkg_name in currentApp:
d.app_stop(pkg_name)
d.app_start(pkg_name, wait=True)
print("\n----------APP starts----------")
print(d.info)
time.sleep(10)
yield d
print("\n----------APP ends----------")
五、conftest和setup/teardown优先级
-
fixture(session)>fixture(class)>setup_class>fixture(function)>setup_function
-
会话级别:fixture的session,优先级最高
-
类:fixture的class级别优先级次之;
-
类:setup_class优先级低于fixture;
-
函数:fixture的function级别优先级再次之;
-
函数:setup_function优先级低于fixture(function)。