IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 测试学习笔记(2)---pytest测试框架详解 -> 正文阅读

[开发测试]测试学习笔记(2)---pytest测试框架详解

一、pytest介绍

pytest是一个非常成熟的全功能的Python测试框架,主要特点有以下几点:
1、简单灵活,容易上手,文档丰富;
2、支持参数化,可以细粒度地控制要测试的测试用例;
3、能够支持简单的单元测试和复杂的功能测试,还可以用来做;selenium/appnium等自动化测试、接口自动化测试pytest+requests;
4、pytest具有很多第三方插件,并且可以自定义扩展;

二、用例默认编写规则

  • 测试文件默认以test_开头(以_test结尾也可以);
  • 测试类默认以Test开头,并且不能带有 init 方法;
  • 测试函数默认以test_开头;
  • 断言使用基本的assert即可;

三、用例分类

  • 通过自带的装饰器@pytest.mark来标记测试用例;
  • 执行的时候带上参数"-m"即可只运行标记的类和方法;

3.1、标记步骤

3.1.1、注册标签名

通过 pytest.ini 配置文件注册,在文件当中的添加如下
[pytest]
markers=
? ? ? ? ? ? ? ? 标记:标记说明
? ? ? ? ? ? ? ? …

在这里插入图片描述

3.1.2、给用例打标记

注意:pytestmark是固定的

  • 可以标记文件,文件下的所有用例都会打上标记
    在文件下全局变量处打上标记pytestmark = [pytest.mark.标签1,pytest.mark.标签2]
    在这里插入图片描述

  • 可以标记测试类,类型的所有用例都会打上标记
    1、可以在类前使用装饰器@pytest.mark.xxx;
    2、也可以在类下使用pytestmark = [pytest.mark.标签1];

  • 可以直接标记测试用例
    在用例前使用装饰器@pytest.mark.xxx给用例打上标记
    在这里插入图片描述

3.1.3、运行标记用例

调用 pytest.main()函数带上命令参数["-m 标签名"]即可,支持and与or关系运算;

  • 运行单个标记如pytest.main(["-m 标签1"]);
  • 运行多个标记如pytest.main(["-m 标签1 and 标签2"])或者pytest.main(["-m 标签1 or 标签2"]);

3.2、标记总结

  • 一条用例可以有多个标记;
  • 可以同时运行符合多个条件的标签,-m “标签1 and 标签2”;
  • 取消警告信息,需要结合pytest.ini文件来使用;
  • 可以使用pytest.mark来标记类、模块、方法;
  • 可以以装饰器的方式标记,也可以使用关键变量pytestmark标记;

四、用例前置和后置

Pytest处理前置后置有两种方式可以处理:
1、第一种是通过setup和teardown这样的方法去处理;
2、第二种是通过fixture来实现的;

4.1 通过setup和teardown

1、模块级(setup_module/teardown_module),开始于模块始末,作用于全局(总用各执行一次);
用法:函数放在类外面才能生效;
2、函数级(setup_function/teardown_function),仅对函数用例生效(即不在类中,每个函数执行一次);
用法:函数放在类外面才能生效;
3、类级(setup_class/teardown_class),只在类中前后运行一次;
用法:函数放在类里面才能生效;
4、方法级(setup_method/teardown_method),开始于方法始末(在类中,每个方法执行一次);
用法:函数放在类里面才能生效;
5、类里面的(setup/teardown),运行在调用方法的前后(每个方法执行一次);
用法:函数放在类里面才能生效;

类级、方法级、类里面的前后置处理顺序:
A、setup_class是在所有用例执行前运行的,teardown_class是在所有用例执行完成后运行的。
B、setup_method是在每一条用例执行前,且在setup执行前运行的,teardown_method是在每一条用例执行完成后,且在teardown执行完成后运行的。
C、setup是在每条用例执行前运行,teardown是在每条用例执行完成后运行。
所以,他们的顺序是:
setup_class-
setup_method-setup-用例1-teardown-teardown_method-
setup_method-setup-用例2-teardown-teardown_method-
setup_method-setup-用例n-teardown-teardown_method-
……
teardown_class

4.2 通过fixture

pytest.fixture():作用于模块内的所有用例,但需要传递装饰函数为参数,可置于class内或class外;
1、fixture 可以作为一个函数的参数被调用
在这里插入图片描述
2、fixture可以在一个类、或者一个模块、或者整个session中被共享,加上范围scope参数即可,如@pytest.fixture(scope=‘module’)

  • 会话级别: session,整个测试执行会话全部用例开始前执行/全部用例执行完后执行(是多个文件调用一次)
  • 模块级别: module,只对模块级别生效,全部用例开始前执行/全部用例执行完后执行(每个.py文件调用一次)
  • 类级别: class,只对类级别生效,整个测试类全部用例开始前执行/全部用例执行完后执行(每一个类调用一次)
  • 函数级别: function,只对函数级别生效,每个用例开始前和结束后执行一次(每一个函数或方法都会调用)

3、fixture也可以单独存放
有的时候为了方便配置和访问,共享 fixture 函数,也可以将这样的fixture放到conftest.py文件中单独存放;conftest.py 文件中的 fixture 函数不需要在测试函数中导入,可以被 pytest 自动识别,查找顺序从测试类开始,然后是测试模块,然后是 conftest.py 文件,最后是内置插件和第三方插件。
4、同一个模块里出现多个范围的装饰
当出现多个范围装饰则优先实例化范围优先级高的,也就是优先级从大到小:session–>module–>class–>function;
6、yield方法实现setup/teardown的功能
在yield关键字之前的代码在case之前执行,yield之后的代码在case运行结束后执行

@pytest.fixture()
def login():
    print(\"登录\")
    yield
    print(\"退出登录\")

7、addfinalizer方法实现setup/teardown的功能
addfinalizer也可以实现环境的清理,实现与yield方法相同的效果,跟yield不同的是需要注册作为终结器使用的函数

例如:
@pytest.fixture()
def login(request):
    print(\"登录\")
    def demo_finalizer():
        print(\"退出登录\")
    # 注册demo_finalizer为终结函数
    request.addfinalizer(demo_finalizer)

注意request是固定的,不能随便写的

8、fixture中的参数 autouse
默认是False, autouse设置为True时,自动调用fixture功能。由于默认作用域为function,不指定scope则每个方法都会调用fixture方法。

9、fixture函数参数化
如果多条用例都需要调用相同参数,可以将fixture函数参数化。fixture 函数将执行每个参数值,fixture通过固定参数request传递。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import pytest

@pytest.fixture(scope="module", params=['测试1','测试2','测试3'])
def data(request):
    yield request.param

class Test_Demo():
    def test_case1(self, data):
        print('测试用例01')
        print(data)

if __name__ == "__main__":
    pytest.main(["-sv", "test.py"])

运行结果如下:
test.py::Test_Demo::test_case1[\\u6d4b\\u8bd51] 测试用例01
测试1
PASSED
test.py::Test_Demo::test_case1[\\u6d4b\\u8bd52] 测试用例01
测试2
PASSED
test.py::Test_Demo::test_case1[\\u6d4b\\u8bd53] 测试用例01
测试3
PASSED

10、pytest.mark.usefixtures的使用
@pytest.mark.usefixtures的使用,usefixtures达到的效果和setup和teardown一样

11、 当case里需要传入多个 fixture 或者 yield 怎么办呢? 先后执行的顺序是什么?
(“before”表示执行在case前,“yield”表示执行在case后)

  • def test_1(before, yield) 与 def test_1(yield,before)
    结论:不管你顺序如何,依旧会先执行case前的before,case结束后执行yield
  • def test_2(before1, before2, yield)
    结论:这样有多个before,会依次按传参顺序先后执行。
  • def test_3(before, yield1, yield2)
    结论:这样有多个yield的,会依次从后往前执行,这里先执行yield2,再执行yield1。

五、pytest命令参数

在这里插入图片描述

  • pytest test/: 执行test目录下所有文件
  • pytest.main([’-s’,’-v’]): 写在代码中执行测试用例,默认执行当前目录及子目录下的所有文件,可以指定执行文件
  • py.test -x : 首次失败后停止执行
  • py.test --maxfail=2 : 两次失败之后停止执行
  • py.test -k answer1 -v: 运行所有名字中含有的answer1的方法,-k 用来匹配名字中包含表达式的方法, -v 增加显示详细信息
  • py.test -m : 运行通过marked的用例,-m 标记的名字
  • @pytest.mark.xfail: Xfail标记的测试将会执行,但是不会被记入失败或成功中,如果失败了,也不会有任何追踪的信息
  • @pytest.mark.skip: Skip 则意味着直接跳过,不会执行

六、生成HTML报告

  • 首先安装插件:pip install pytest-html
  • 运行命令:py.test -v -s --html=reportName.html
  • 你将会在文件目录下生成reportName.html,用浏览器打开
  • 上面生成的报告,css是独立的,分享报告的时候样式会丢失,为了更好的分享发邮件展示报告,可以把css样式合并到html里
    pytest --html=report.html --self-contained-html
  • 在python中执行命令
    pytest.main(['--html=./report.html', 'test_testing_topic.py'])

七、运行测试用例方式

1.、Pytest Marker 机制
可以在每一个测试用例加一个marker,比如pytest运行的时就只运行带有该marker的测试用例,比如下面的pytest.main(["-m test"]);

2、选择运行特定的某个测试用例
你可以按照某个测试用例的的模块,类或函数来选择你要运行的case,比如下面的方式就适合一开始在调试单个测试用例的时候;
pytest -v test_pytest_markers.py::TestClass::test_method

3、选择运行特定的某个类
pytest -v test_pytest_markers.py::TestClass

4、用-k进行关键字匹配来运行测试用例名字子串
pytest -v -k http test_pytest_markers.py

5、重跑失败的用例,使用pytest-rerunfailures
python3 -m pytest -reruns 重跑次数

6、多进程运行
安装pytest-xdist:pip install -U pytest-xdist
如何使用:使用参数"-n"
py.test test_pyexample.py -n NUM
其中NUM填写并发的进程数。

八、断言

pytest里面的断言实际上就是python里面assert的断言方法,常用以下几种:

  • assert xx 判断xx为真
  • assert not xx 判断xx不为真
  • assert a in b 判断b包含a
  • assert a == b 判断a等于b
  • assert a != b 判断a不等于b

九、数据驱动

pytest数据驱动,就是参数化,使用@pytest.mark.parametrize
在测试用例的前面加上:

  • @pytest.mark.parametrize(“参数名”,列表数据)
    参数名:用来接收每一项数据,并作为测试用例的参数。
    列表数据:一组测试数据。
  • @pytest.mark.parametrize(“参数1,参数2”,[(数据1,数据2),(数据1,数据2)])

十、常用的第三方库

  • pytest-sugar
    测试进度可视化
    用法:不需要配置操作

  • pytest-parallel
    pytest-parallel在Windows下只支持多线程,不支持多进程,在Linux和mac下即支持多进程又支持多线程

参数值配置:
--workers=n           多进程运行需要加此参数,n是进程数。默认为1  【注:在windows系统中只能为1】
--tests-per-worker=n  多线程运行需要加此参数,n是线程数。
如果两个参数都配置了,就是进程并行,每个进程最多n个线程,总线程数:进程数*线程数
pytest-parallel的workers参数在windows系统下永远是1,在linux和mac下可以取不同值。
  • pytest-xdist
    多进程并行与分布式执行,只支持多进程不支持多线程;
    用法:使用参数"-n",如py.test test_pyexample.py -n NUM
    注意:使用的前提是用例之间都是独立的,没有先后顺序,随机都能执行,可重复运行不影响其他用例

  • pytest-rerunfailures
    支持用例失败重试功能
    运行时指定:pytest -v -s 文件名.py -reruns 5 --reruns-delay 1 每次等1秒 重试5次
    测试方法上指定:@pytest.mark.flaky(reruns=5,reruns-delay=1) 每次等1秒 重试5次

  • pytest-picked
    插件可以实现只运行未提交到git仓库的代码

  --picked=[{only,first}]           Run the tests related to the changed files either on their own, or first
  --mode=PICKED_MODE                Options: unstaged, branch
  
使用示例:
pytest --picked              所有测试都将从已修改但尚未提交的文件和文件夹中运行
pytest --picked=first        首先运行修改后的测试文件中的测试,然后运行所有未修改的测试
pytest --picked --mode=branch      运行分支上已经被暂存但尚未提交的代码
pytest --picked --mode=unstaged  # default    会默认执行所有的 Untracked 文件和 not staged 文件
  • pytest-ordering
    指定用例的执行顺序
    装饰器用法:@pytest.mark.run(order=xx)

  • pytest-cov
    在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况;
    运行用例的时候加上 --cov 参数
    生成html的报告,pytest --cov --cov-report=html
    指定被测代码,可以通过--cov=模块 来运行

  • pytest-instafail
    可以在运行用例的时候,实时查看用例报错内容
    用法: --instafail 方便实时查看报错内容,结合--tb=line参数,看起来更直观

  • pytest-tldr
    pytest-tldr 将默认输出限制为失败测试的回溯信息,并忽略了一些令人讨厌的颜色编码。添加 -v 标志会为喜欢它的人返回更详细的输出;

  • pytest-django
    pytest-django 引入了使用 pytest fixture 测试 Django 项目的能力,而省略了导入 unittest 和复制/粘贴其他样板测试代码的需要,并且比标准的 Django 测试套件运行得更快;

  • pytest-html
    pytest用于生成测试结果的HTML报告
    用法:pytest --html=report.html --self-contained-html

  • allure-pytest
    生成Allure报告,Allure框架是一个灵活的轻量级多语言测试报告工具,它不仅以web的方式展示了简介的测试结果,而且允许参与开发过程的每个人从日常执行的测试中最大限度的提取有用信息;

用法:pytest.main(['-s', '-q', '--alluredir', './report/xml'])
-q 的意思是减少报告多余
--alluredir 的意思是生成allure报告的数据的目标目录,即测试目录运行后的结果,是生成xml的数据集合
生成Allure报告,在cmd下运行==> allure generate --clean ./report/xml/ -o ./results/html/

Allure学习参考:https://www.cnblogs.com/linuxchao/p/linuxchao-pytest-allure.html

  • pytest-assume
    前面的断言失败了后继续执行
    用法:pytest.assume(xxx == xxx)

  • pytest-timeout
    设置执行用例的超时时间
    用法:pytest --timeout=2

  • pytest-repeat
    重复执行,当执行一个测试用例时偶发性BUG时,我们可以使用 pytest-repeat 进行重复测试直到失败。
    用法:pytest -v -s --count=2 test_open.py 重复执行2次

  • pytest-dependency
    使用该插件可以标记一个test作为其他test的依赖,当依赖项执行失败时,那些依赖它的test将会被跳过;
    用法:用 @pytest.mark.dependency()对所依赖的方法进行标记,使用@pytest.mark.dependency(depends=[“test_name”])引用依赖

import pytest

@pytest.mark.dependency()
def test_01(test):
    assert False

@pytest.mark.dependency(depends=["test_01"])
def test_02(test):
    print("执行测试2")

运行结果:test_01是test_02的依赖,故而test_01失败后,test_02被跳过
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-07 00:07:16  更:2021-07-07 00:08:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 18:45:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码