今天和大家分享pytest测试框架进阶篇,也可以称之为pytest测试框架核心,主要核心有:
- 掌握pytest.fixture
- 掌握pytest.mark
目录
一、掌握pytest.fixture
fixture是pytest中特殊的一部分,其功能十分强大。fixture也可以称之为测试的装置、夹具、脚手架。其作用和目的在于:
在测试执行之前,自动化准备相关的测试环境
在测试执行之后,将相关的内容进行销毁
思考: 重复性的代码,能不能偷懒重用?哪些是属于测试用例的内容,哪些是不属于测试用例的内容?
结论:
对于测试用例的准备性工作,应该挪出测试用例代码
对于重复性的代码,我们将使用函数进行重用
这样的工作就应该给fixture完成
从而引出我们今天的主要核心内容,fixture
1.1 创建fixture
有过python基础的应该知道在python里面有一个用法叫做装饰器,目的在于不改变源代码的情况下,给予此段代码添加新的功能。创建fixture也运用了同样的方法;
给一个函数加上pytest.fixture的装饰器,即可创建一个夹具:
@pytest.fixture
def start_chrom():
return webdriver.Chrome()
以上代码就是我们创建好的一个夹具,其功能是启动谷歌浏览器。再下面的测试用例中,如果需要用到启动浏览器这一功能的话,即可在测试用例的参数列表中,填写创建的fixture夹具名称,pytest就会自动调用。如下图:
import pytest
from selenium import webdriver
@pytest.fixture()
def browser():
return webdriver.Chrome()
def test_baidu(browser):
"""
- 打开浏览器
- 输入https://baidu.com
- 获取标题
- 断言“百度”出现在标题中
:return
"""
browser.get("https://baidu.com")
title = browser.title
assert "百度" in title
测试结果:
思考:浏览器启动时间太长,如果让测试用例共用同一个浏览器是否可以减少测试时长。(共用同一个fixture),不同的用例如何共用同一个fixture。
从而引出不同的用例如何共用一个fixture
1.2 不同用例共用一个fixture
在同一范围内容,用例可以共享fixture
范围:在定义fixture时,可以通过参数scope,指定范围
@pytest.fixture(scope="session")
这个fixture的范围是session,在session范围内的测试用例,共享fixture
重点:
function 同一个函数中的测试用例 --- 函数
class 同一个类中的测试用例 --- 类
module 同一个模块中的测试用例 --- 文件
package 同一个包中的测试用例 --- 文件夹
session 整个测试活动,最大
思考:不同文件如何共享fixture?
1.3 不同文件共享一个fixture
pytest在启动的时候会自动的加载的文件:
-
pytest.ini
-
conftest.py
conftest.py,有两个特点:
-
比测试用例先执行
-
这里定义的fixture可以被任何一个用例使用
所以我们可以把fixture定义在conftest.py文件中,在测试用例前执行
扩展:
问题:
fixture不定义在conftest.py可不可以?
可以,可以定义在xx.py,然后手动import
其他的代码定义在conftest.py 可不可以?
还有什么应该定义在conftest.py里面?
setup /teardown
常量
初始化
pytest的配置
pytest的插件
测试代码可以共享吗?
数据驱动 = 数据管理 + 参数化测试
1.4 参数化测试
参数化测试:一份代码,传递参数,执行多个测试用例
fixture支持参数,于是可以进行参数化测试
可以不必修改已有fixture,免得其他使用该fixture用例收到影响
-
params:表示的所有数据
-
param:本次测试用到的数据
import pytest
from selenium import webdriver
@pytest.fixture(scope="session")
def browser():
return webdriver.Chrome()
@pytest.fixture(params=[
("https://baidu.com","百度"),
("https://aliyun.com","阿里"),
("https://qq.com","腾讯"),
])
def _test_code(request):
return request.param
def test_baidu(browser,_test_code):
"""
- 打开浏览器
- 输入https://baidu.com
- 获取标题
- 断言“百度”出现在标题中
:return:
"""
url,title = _test_code
browser.get(url)
title_all = browser.title
assert title in title_all
1.5 内置fixture
夹具 | 作用 |
---|---|
capfd | 文件描述符1和2的内容捕获为字符串 |
capfdbinary | 文件描述符1和2的内容捕获为字节 |
capsys | sys.stdout和sys.stderr内容捕获为字符串 |
capsysbinary | sys.stdout和sys.stderr内容捕获为字节 |
caplog | 控制日志记录和访问日志内容 |
cache | pytest的内容存储接口,保存在.pytest_case目录 |
pytestconfig | pytest配置信息、插件信息 |
request | 当前测试用例的相关信息,比如用例名、夹具 |
tmpdir | 申请一个测试结束后自动删除的临时目录 |
二、掌握pytest.mark
mark:标记用例
2.1 内置mark
mark是给测试用例使用的,可以改变用例的一些行为:
不执行用例 skip,skipif
报错是通过,不报错是失败 xfail
自动使用夹具 usefixtures('夹具')
参数化测试 parametrize
问题:
基于fixtures的参数化和基于mark的参数化有什么区别?
fixtures参数化可用于多个用例
mark参数化只用于单个用例
2.2 自定义mark
mark要先注册,再使用,作用于对用例的筛选。
在我们的pytest.ini文件中先注册
使用:
-
选择 pytest -m jj
-
不选择 pytest -m “not jj”
代码演示:
import pytest
@pytest.mark.skip
def test_jiujiang(request):
print("当前测试用例:",request.node)
print("当前测试用例使用的夹具:",request.fixturenames)
print("生成的HTML报告的路径是:",request.config.getoption("htmlpath"))
@pytest.mark.parametrize("n",[i for i in range(10)])
def test_print(n):
print("x")
@pytest.mark.jj
def test_xxx():
print("x")
三、结束语
在这里,pytest测试框架的进阶篇就分享结束了,有些细节的地方需要动手操作后才能明白。感兴趣的朋友收藏关注哦。