自动化接口测试-pytest模块
自动化接口测试-pytest模块
一、pytest简介:
1. pytest是一个非常成熟的python的单元测试框架,比unittest更灵活,容易上手。作用是测试执行的框架。
2.pytest可以和selenium,requests,appium结合实现web的自动化,接口自动化,app自动化
3.pytest可以实现测试用例的跳过以及returns失败用例重试
4.pytest可以和allure生成非常美观的测试报告
5.pytest可以和jenkins持续集成。
6.pytest有很多非常强大的插件,并且这些插件能够实现很多实用的操作。
- pytest-html:生成html格式的自动化测试报告
安装:pip3 install pytest-html
在配置文件pytest中的命令行参数中增加 --html-用户路径/报告.html
addopts = -s
--html=./report/report.html
- pytest-xdist:测试用例分布执行,多CPU分发
- pytest-ordering:用于改变测试用例的顺序
场景:现实生活中,如果想下单,必须先登录,我们可以通过插件形式来控制函数执行顺序。
安装:pip3 install pytest-ordering
使用:
1. 标记于被测函数,@pytest.mark.run(order=x)
2. 根据order传入的参数来解决运行顺序
3. order值全为正数或全为负数时,运行顺序,值越小,优先级越高
4. 正数和负数同时存在,正数优先级高
5. 对测试类同样有效
- allure-pytest:用于生成美观的测试报告。
- pytest-rerunfailures:失败重试
场景: 自动化测试脚本可能会使用到网络,如果网络不好可能最终会使脚本不通过。像这种情况可能并不是脚本本身的问题,仅仅是因为网络忽快忽慢,那么我们可以使用失败重试插件,当失败后尝试再次运行。一般情况下最终成功可以视为成功,但最好排查是否是脚本问题。
安装:pip3 install pytest-rerunfailures
使用:在配置文件中的命令行参数中增加 --reruns n # n 表示重试的次数
pytest.ini:
addopts = -s --reruns 3 #重试3次 ,正式脚本一般设置不超过3次,测试脚本设置一次即可。

二、基本使用方法:
1. 函数名需要以test开头
def test_func():
print("我是测试函数")
2. 类名需要以Test开头,类中的方法需要以test开头
类中不能有构造方法。
class TestDemo(object):
def test_method1(self):
print("测试方法1")
def test_method2(self):
print("测试方法2")
3. 使用assert进行断言
4.脚本名需要以test_开头或者_test结尾
三、pytest测试用例的运行方式
3.1 主函数模式
if __name__ == '__main__':
pytest.main(["-s", "./mytest/pytest_basic_02.py"])
3.2 命令行模式
参数详解:
-s:表示输出调试信息,包括print打印的信息
-v:显示更详细的信息
-vs:两个参数一起使用
-n:支持多线程或者分布式进行测试用例(需要安装pytest-xdist插件)
如:pytest.main(['-vs', "./testcase/test_login.py", "-n=2"])
代表两个线程跑用例
--reruns NUM :失败重跑次数
--html ./report/report.html:生成html的测试报告(依赖插件pytest-html)
pytest -s pytest_basic_01.py
3.通过读取pytest.ini配置文件运行
应用场景:使用配置文件可以快速的使用配置的项来选择执行哪些测试模块
使用方式
- 项目下新建scripts模块
- 将测试脚本文件放到scripts中
- pytest的配置文件放在自动化项目目录下
- 名称为pytest.ini
- 命令行运行时会使用该配置文件中的配置
- 第一行内容为[pytest]
[pytest]
addopts = -vs #命令行参数
testpaths = ./testcase #路径
python_files = test_*py #文件
python_classes = Test* #类
python_functions = test* #方法
markers = #分组
smoke:冒烟用例
pytest.ini这个文件它是pytest单元测试框架的核心配置文件。
1. 位置:一般放在项目的根目录
2. 在windows系统下,pytest配置文件中,不允许写注释信息
3. 一个工程内只需要一个pytest配置文件,并且需要保证文件名正确
4.文件编码:必须是ANSI,可以使用nodepadd++修改编码格式
5.作用改变pytest默认的行为
6.运行的规则:不管是主函数的模式运行,命令行模式的运行,都会去读取这个配置文件。
7.如果只按配置批量运行,那么主函数模式下只需要调用pytest.main()
四、如何分组执行(冒烟、分模块执行、分接口和WEB执行)
smoke: 冒烟用例,分布在各个模块里面
pytest -m "smoke"
五、pytest跳过测试用例
(1)无条件跳过
@pytest.mark.skip(reason="跳过不执行")
(2)有条件跳过
@pytest.mark.skipif(age>=18,reason="未成年")
六、参数化
场景:登录功能都是输入用户名、输入密码、点击登录,但登录的用户名和密码如果想测试多个值是没有办法用普通的操作实现的,数据参数化可以帮我我实现这样的效果
方法:
import pytest
import requests
cases = [('正确账户密码', 'machuanang', 'Ss081720ma'),
('错误密码', 'machuanang', 'S081720ma'),
('密码为空', 'machuanang', ''),
('错误账户正确密码', 'machuanang23', 'Ss081720ma')]
#cases类型可以是列表或元祖,parametrize参数化,循环执行四次
@pytest.mark.parametrize('case',cases)
def test_login(case):
url = 'http://itsp.orientsec.com.cn/dfzq-sign/login.do?xcase=doLogin'
print(case[0])
login_data = {'userName': case[1], 'password': case[2]}
r = requests.post(url, login_data)
print(r.text)
七、前置后置
7.1 函数级别前置后置
setup在每个类中执行每个用例前都执行方法setup():比如打开浏览器
teardown在每个类中执行每个用例后都执行方法teardown():比如关闭浏览器
class Test:
def setup(self):
print("函数级别的前置")
def teardown(self):
print("函数级别的后置")
@pytest.mark.parametrize('num',[1,2,3])
def test(self,num):
print(num)
#--------执行结果----------
test_setup.py::Test::test[1] 函数级别的前置
1
PASSED函数级别的后置
test_setup.py::Test::test[2] 函数级别的前置
2
PASSED函数级别的后置
test_setup.py::Test::test[3] 函数级别的前置
3
PASSED函数级别的后置
============================== 3 passed in 0.07s ==============================
7.2 类级别的前后置
setup_class 在每个类中执行所有用例前只执行一次:比如创建日志对象,创建数据库的链接,创建接口的请求对象
teardown_class 在每个类中执行所有用例后只执行一次
class Test:
def setup_class(self):
print("类级别的前置")
def teardown_class(self):
print("类级别的后置")
@pytest.mark.parametrize('num',[1,2,3])
def test(self,num):
print(num)
------------测试结果--------
test_setup.py::Test::test[1] 类级别的前置
1
PASSED
test_setup.py::Test::test[2] 2
PASSED
test_setup.py::Test::test[3] 3
PASSED类级别的后置
setup_module 在每个模块中执行所有用例前只执行一次
teardown_module 在每个模块中执行所有用例后只执行一次
八、使用@pytest.fixture()装饰器来实现部分用例的前后置
@pytest.fixture(scope="",params="",autouse="",ids="",name="")
(1)scope表示的是被@pytest.fixture()标记的方法的作用域。function(默认),class,module,package/session
@pytest.fixture(scope="function")
def my_fixture():
print("这是前置的方法,可以实现部分用例的前置")
yield #前置方法和后置方法以yield分开
print("这是后置的方法,可以实现部分用例的后置")
在类的成员函数中使用
def test_01_horse(self,my_fixture):
(2)params:参数化,支持列表[],元祖(),字典列表,元祖列表
@pytest.fixture(scope="function", params=['苏州','上海 ','北京'])
def my_fixture(request):
print("这是前置的方法,可以实现部分用例的前置")
yield request.param #return和yiel都可以返回值,yield返回后还可以执行
print("这是后置的方法,可以实现部分用例的后置")
class TestLogin:
def test_01_horse(self,my_fixture):
print('测试小红马,登陆城市:'+my_fixture)
(3)autouse=True:自动执行,默认false,为true时可以执行所有的用例
@pytest.fixture(scope="function",autouse=True)
def my_fixture():
print("这是前置的方法,可以实现部分用例的前置")
yield
print("这是后置的方法,可以实现部分用例的后置")
class TestLogin:
def test_01_horse(self):
print('测试小红马')
def test_02_cat(self):
print('测试cat')
(4)ids:当使用params参数化时,给每一个值设置一个变量名,意义不大
(5)name:给表示的是被@pytest.fixture()标记的方法去一个别名。
更多推荐


所有评论(0)