pytest框架
一、pytest安装与入门
1、介绍
- 简单灵活,
- 容易上手,
- 文档丰富
- 支持参数化,能够支持简单的单元测试和复杂的功能测试
- 具有很多第三方插件,并且可以自定义扩展
- 可以很好的和Jenkins工具结合
2、安装pytest
(1)命令行执行以下命令
$ pip3 install -U pytest
(2) 检查版本
$ pytest --version
3、创建你的第一个测试用例
(1)创建一个简单的测试方法
#test_sample.py def func(x): return x + 1 def test_a(): print("---test_a----") assert func(3) == 5 #断言失败 def test_b(): print("---test_b---") assert 1 #断言成功
(2) 执行一下
命令行下执行
$ pytest -s test_sample.py
主函数模式下增加主函数:
if __name__ == '__main__': pytest.main(["-s", "test_sample.py"])
#-s 表示支持控制台打印,如果不加,print 不会出现任何内容 #-q 安静模式,不打印信息
结果说明:
. 表示成功
如果需要更多信息,可以使用-v或--verbose
F 表示失败
二、Pytest 基础使用
1、函数级别方法
运行于测试方法的始末,运行一次测试函数会运行一次 setup 和 teardown。
(1)示例代码
import pytest class TestLogin: # 函数级开始 def setup(self): print("------->setup_method") # 函数级结束 def teardown(self): print("------->teardown_method") def test_a(self): print("------->test_a") def test_b(self): print("------->test_b")
(2)执行结果
scripts/test_login.py ------->setup_method # 第一次 setup()
------->test_a
.------->teardown_method # 第一次 teardown()
------->setup_method # 第二次 setup()
------->test_b
.------->teardown_method # 第二次 teardown()
2、类级别方法
运行于测试类的始末,在一个测试内只运行一次 setup_class 和 teardown_class,不关心测试类内有多少个测试函 数。
(1)示例代码
class TestLogin: # 测试类级开始 def setup_class(self): print("------->setup_class") # 测试类级结束 def teardown_class(self): print("------->teardown_class") def test_a(self): print("------->test_a") def test_b(self): print("------->test_b")
(2)执行结果
scripts/test_login.py
------->setup_class # 第一次 setup_class()
------->test_a
.------->test_b
.------->teardown_class # 第一次 teardown_class()
三、Pytest 常用插件
插件列表网址:https://plugincompat.herokuapp.com 包含很多插件包,大家可依据工作的需求选择使用。
1、测试报告
(1)应用场景
自动化测试脚本最终执行是通过还是不通过,需要通过测试报告进行体现。
(2)安装
$ pip3 install pytest-html
(3)使用
在配置文件中的命令行参数中增加 --html=用户路径/report.html
(4)示例
pytest.ini
addopts = -s --html=report/report.html
(5)结果
在项目目录下会对一个 report 文件夹,里面有个 report.html 即为测试报告
2、失败重试
(1)应用场景
自动化测试脚本可能会使用到网络,如果网络不好可能最终会使脚本不通过。像这种情况可能并不是脚本本身 的问题,仅仅是因为网络忽快忽慢,那么我们可以使用失败重试的插件,当失败后尝试再次运行。一般情况最 终成功可以视为成功,但最好进行进行排查时候是脚本问题。
(2)安装
pip3 install pytest-rerunfailures
(3)使用
在配置文件中的命令行参数中增加 --reruns n
(4)示例
pytest.ini addopts = -s --reruns 3 test_login.py class TestLogin: def test_a(self): # test开头的测试函数 print("------->test_a") assert 1 # 断言成功 def test_b(self): print("------->test_b") assert 0 # 断言失败
(5)结果
scripts/test_login.py
------->test_a
.------->test_b
R------->test_b
R------->test_b
R------->test_b
F
(6)说明
R 表示重试
重试时,如果脚本通过,那么后续不再重试
如果你期望加上出错重试的等待时间,请使用如下命令(reruns-delay是等待时间):
pytest --reruns 5 --reruns-delay 1
如果你只想对某几个测试用例应用重试策略,你可以使用装饰器:
@pytest.mark.flaky(reruns=5, reruns_delay=2)
例如:
@pytest.mark.flaky(reruns=5, reruns_delay=2) def test_example(): import random assert random.choice([True, False])
四、Pytest 数据参数化
1.应用场景
登录功能都是输入用户名,输入密码,点击登录。但登录的用户名和密码如果想测试多个值是没有办法用普通 的操作实现的。数据参数化可以帮我实现这样的效果。
2、方法名
pytest.mark.parametrize
# 数据参数化
# 参数:
# argnames:参数名
# argvalues:参数对应值,类型必须为可迭代类型,一般使用list
@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
3、一个参数使用方式
- 1. argnames 为字符串类型,根据需求决定合适的参数名
- 2. argvalues 为列表类型,根据需求决定列表元素中的内容
- 3. 在测试脚本中,参数,名字与 argnames 保持一致
- 4. 在测试脚本中正常使用
(1)示例
import pytest class TestLogin: @pytest.mark.parametrize("name", ["xiaoming", "xiaohong"]) def test_a(self, name): print(name) assert 1
(2)结果
scripts/test_login.py xiaoming
.xiaohong
.
4、多个参数使用方式
(1)示例
import pytest class TestLogin: @pytest.mark.parametrize(("username", "password"), [("zhangsan", "zhangsan123"), ("xiaoming", "xiaoming123")]) def test_a(self, username, password): print(username) print(password) assert 1
(2)结果
scripts/test_login.py
zhangsan zhangsan123 .
xiaoming xiaoming123 .
多个参数还可以将装饰器写成 @pytest.mark.parametrize("username,password", [("zhangsan", "zhangsan123"), ("xiaoming", "xiaoming123")]) 效果是一样的。
五、Pytest 应用接口用例
1、运行原则
- 在不指定运行目录,运行文件,运行函数等参数的默认情况下,pytest会执行当前目录下的所有以test 为前缀(test.py)或以_test为后缀(test.py)的文件中以test为前缀的函数
- pytest会找当前以及递归查找子文件夹下面所有的test.py或test.py的文件,把其当作测试文件
- 在这些文件里,pytest会收集下面的一些函数或方法, 当作测试用例
- 不在类定义中的以test开头的函数或方法 在以Test开头的类中(不能包含init方法),以test 开头的方法
2、如何执行多条测试?
- pytest会执行当前目录及子目录下所有test_*.py及*_test.py格式的文件
- 可以设置pytest.ini配置文件,自定义执行文件格式
addopts = -s
# 当前目录下的scripts文件夹 -可自定义
testpaths = testcase
# 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件 -可自定义
python_files = test_*.py
# 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件中,以Test_开头的类 -可自定义
python_classes = Test_*
# 当前目录下的scripts文件夹下,以test_开头,以.py结尾的所有文件中,以Test_开头的类内,以test_ 开头的方法 -可自定义
python_functions = test_*
3、登录用例脚本
url = "http://211.103.136.242:8064/authorizations/" data = [{"username":"python", "password":"12345678"}, {"username":"python1", "password":"test123"}, ] @pytest.mark.parametrize("login", data) def test_login(login): res= requests.post(url,json=login) print(res.json()) if __name__ =="__main__": pytest.main(["-s"])
结果:
{"user_id":1,"username":"python","token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiO jE1NjUzNDA5NTcsInVzZXJfaWQiOjEsImVtYWlsIjoiOTUyNjczNjM4QHFxLmNvbSIsInVzZXJuYW1lIjoicHl0a G9uIn0.K0Kx8lKkeX0CjNTuWZ0cA67FU33nkNYBfl_s-5LxNP8"} .{"non_field_errors":["无法使用提供的认证信息登录。"]}