pytest+allure学习笔记
1、Addfinalizer和yield后置操作,在前面代码抛出异常之后都不会执行了
import pytest
@pytest.fixture(scope="module")
def test_addfinalizer(request):
# 前置操作setup
print("==再次打开浏览器==")
test = "test_addfinalizer"
raise ValueError
yield
print("==再次关闭浏览器==")
# def fin():
# # 后置操作teardown
# print("==再次关闭浏览器==")
#
# request.addfinalizer(fin)
# 返回前置操作的变量
return test
def test_anthor(test_addfinalizer):
print("==最新用例==", test_addfinalizer)
2、Fixures需要返回值的情况只能用方法入参的方式调用,不能用pytest.usefixure方式会拿不到返回值
3、Fixure实列化顺序是优先级大的先实列化,被依赖的先实列化
4、unittest只有setup、teardown、setup_calss,teardown_class, pytest有十种,setup,setup_class,setup_moudle,setup_method,setup_function,针对整个脚本生效
5、Conftest的fixure在同一个包的用列有效,顶层conftest一般写全局的通用操作
6、Pytest.ording可以定义用列顺序,但是不推荐,因为我们的用列最好是随时随地可独立执行
7、Pytest的执行结果,用列语法错误或者调用的fixure报错执行结果是error,测试用列的代码抛出异常或者断言失败执行结果是fail,error越多测试脚本质量越撇
8、跳过执行pytest.mark.skip
pytest.mark.skip(reasion=‘不执行,因为没开发完’),可以加在class或者method上
pytest.mark.skipif(sys.platform == 'win32', reason="不能在window上运行啦啦啦=====")
pytest.importorskip("pexpect", minversion="0.3")
9 、自定义标记:@pytest.mark.web
pytest -s -m web xx.py
pytest -s -m ‘web or app’ xx.py
pytest -s -m ‘not app’ xx.py
10、参数化
@pytest.mark.parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None)
argnames可以是str,tuple,list格式,比如’input, except’ / (‘input’,’except’) / [‘input’,’except’]
argvalues必须是list或者tuple,但是list里面可以是str、tuple、dict,比如[(‘3+5', 8), ('6+7', 13)] / [‘1’,’2’] / [{‘name’:’admin’},{‘password’:’123’}] ,一个参数用str,两个参数用dict,多个参数用tuple
indirect=True表示参数以函数方式运行,拿返回值作为参数
Ids是为了增加可读性提供的一个list描述
多个parametrize装饰器作用一个method或class,最终的参数组数是多个parametrize参数组数的乘积
import pytest
@pytest.fixture(scope='function')
def get_user(request):
return type(request.param)
@pytest.fixture(scope='function')
def get_pwd(request):
return type(request.param)
@pytest.mark.parametrize(['get_user', 'get_pwd'], [('admin1', 'pwd1'), ('admin2', 'pwd2')])
def test_multfixure(get_user, get_pwd):
print(get_user + get_pwd)
# 最终的参数组数是 2*2
@pytest.mark.parametrize('get_user', ['admin1', 'pwd1'], indirect=True)
@pytest.mark.parametrize('get_pwd', ['admin2', 'pwd2'], indirect=True)
def test_multparam(get_user, get_pwd):
print(get_user + get_pwd)
@pytest.fixture()
def logins(request):
return type(request.param)
data = [
{"username": "name1", "pwd": "pwd1"},
{"username": "name2", "pwd": "pwd2"},
]
@pytest.mark.parametrize("logins", data, indirect=True)
@pytest.mark.flaky(reruns=5, reruns_delay=2)
def test_name_pwd(logins):
assert False
11、统一加前缀简写
data=['jim','san']
names=[f'name:{name}' for name in data]
@pytest.mark.parametrize("login", data, ids=ids, indirect=True)
12、装饰器实现
def logger(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper
@logger
def test_fun():
print('test')
13、es和mysql对应关系
Table--->index
Row——>doc
Cols——->filed
14、param+fixures使用
@pytest.mark.parametrize("login", data, ids=ids, indirect=True)
Login这里是一个fixure, 添加 indirect=True 参数是为了把 login 当成一个函数去执行,而不是一个参数,并且将data当做参数传入fixure,在fixure用request.param承接的就是这里的data
15、失败重新运行(fixure和setup失败的也重新运行)
重试次数:—return n
重试延时:—return-delay n
全局:Pytetst —return 5 --return-delay 10
单个用列:@pytest.mark.flaky(reruns=5,reruns_delay=2)
优先级:单个>全局
15、重复运行:pytest-repeat(复现偶现的bug,相同参数重复运行直到失败,不稳定的case连续多跑几次)
全局:pytest -s --count 5 -x xx.py
单个:@pytest.mark.repeat(5)
16、pytest.ini(定义pytest的默认行为)
[pytest]
#自定义标签
markers =
app: app
web: web
#选项
addopts = -v
#用列收集忽略路径
norecursedirs = .* build dist CVS _darcs {arch} *.egg venv src resources log report uti
#用列收集规则
python_files = test_* *_test test*
python_classes = Test* test*
python_functions = test_* test*
17、Assume多重断言(前面的断言失败了后面的断言还是可以执行)
pytest.assume(1 + 4 == 5)
pytest.assume(1 + 3 == 3) #这里失败了后面还是会执行
pytest.assume(2 + 5 == 7)
pytest.assume(2 + 5 == 9)
print("测试完成")
18、分布式运行xdist
前置条件:用列可独立、无顺序、可重复的运行
可以自动检测到系统的CPU核数为分布式进程个数:pytest -s -n auto
分布式共用一个session
# web ui自动化, 声明一个driver,再返回
# 接口自动化,发起一个登录请求,将token返回都可以这样写
@pytest.fixture(scope="session")
def login():
with FileLock("session.lock"):
return s
19、allure报告
环境显示:在allure报告路径生成environment.properties
Browser=Chrome
Browser.Version=81.0.4044.92
Stand=Production
ApiUrl=127.0.0.1/login
python.Version=3.7.2
分类自定义:在allure报告路径生成categories.json
[
{
"name": "通过的用例数",
"matchedStatuses": [
"passed"
]
},
{
"name": "实际结果与期望不符",
"matchedStatuses": ["failed"], #运行结果
"traceRegex": ".*AssertionError.*", #正则匹配堆栈信息
"flaky": true #标记为闪烁,失败了下次还可以运行
}
]
标记测试step
@allure.step("第一步")
def passing_step():
pass
标记附件
allure.attach(file, title,filetype)
浙公网安备 33010602011771号