一、pytest 介绍、运行、参数化和数据驱动、Fixture

pytest安装与介绍

为何选择pytest

  • 兼容unittest
  • 定制化插件开发

pycharm 配置github

  • VSC--Git--Remotes...

pycharm pytest 配置

  • settings--搜索pytest--Python integrated Tools--testing--选择pytest:根据黄色叹号fix安装pytest安装到环境

pytest命名规则

pytest运行测试用例

1 - pycharm

2 - 命令行运行方式 - 推荐(以便后续持续集成)

可能会遇到的找不到模块的路径问题,需要在导包之前引入路径 import sys sys.path.append('路径')

  • 运行包: pytest (pytest会自动检索当前目录下所有符合规则的测试用例)
  • 运行一个模块:pytest -vs test.py
  • 只执行某一条测试用例:pytest 目录/模块.py::类名::用例名
常用命令行参数
  • pytest --help: 获取所有参数列表
  • -x: 用例一旦失败(fail/error),就立刻停止
    • 使用场景:一般用于冒烟测试

      • 冒烟测试最早由google提出的一个概念,一般针对每日构建的版本,对系统的基本功能进行简单测试的测试类型,主要强调程序主体的功能
  • --maxfail=num: 用例达到最大数num停止运行
  • -m: 标记用例
  • -k: 执行包含某个关键字的测试用例
  • -v: 打印详细日志
  • -s 打印输出日志(一般-vs一块使用)
  • --collect-only:(测试平台,pytest 自动导入功能)

标记测试用例:mark

  • 场景:只执行符合要求的某一部分用例,把项目分为多个模块,然后指定模块名称执行
  • 解决:在测试用例的上方加上pytest装饰器:@pytest.mark.标签名
  • 执行 -m 标记自定义的相关用例
    • pytest -s test_mark.py -m=标签名
    • pytest -s test_mark.py -m 标签名
    • pytest -s test_mark.py -m "not 标签名" (not:逻辑运算,表示不是标签名的都去执行)

跳过(skip)及预期失败(xfail)

pytest的内置标签,可以处理一些特殊的、及不能成功的测试用例

  • ship: 始终跳过该用例

    • 方式1: @pytest.mark.skp(reason="代码没有实现")
    • 方式2:在测试用代码中添加判断的语句
      def test_demo():
      if not login():
      pytest.skip("未登录无法运行该用例")
  • skipif: 遇到特定情况跳过该测试用例,需要给定条件

    @pytest.mark.skipif(条件="", reason="打印提示信息内容")

  • xfail: 遇到特殊情况,产生一个“期望失败”输出

运行结果分析

  • 常用:fail error pass
  • 特殊结果:
    • warning
    • deselect

pytest常用执行参数

----------

更多用法使用 pytest --help 查看帮助文档

用例匹配:

  • pytest -k "add" 匹配所有用例名称中包含add的用例
  • pytest -m mark 标签名、标记:在测试用例上添加装饰器 @pytest.mark.login
    • pytest有很多自带的标签,我们自己定的标签,如login 他会不识别,所以在运行后会有 deselected、warnings

      警告信息,需要创建pytest配置文件:pytest.ini

      pytest.ini
      
      [pytest]
      # markers 帮助文档解释:为你的测试用例添加标签
      markers = login
      search
      '个人中心'
  • pytest --junitxml=./result.xml 生成执行结果文件
  • pytest --setup-show 回溯fixture的执行过程

pytest.ini:

  • pytest.ini是pytest的配置文件

    • 文件内容要以 [pytest] 开头
    • 修改pytest模块名、类名、用例名称规则(以什么开头:如pytest文件名和用例名默认以test_* 开头或结尾)
      • python_files (args):用于Python测试模块发现的全局样式文件模式(文件名)

      • python_classes (args):前缀或glob名称,用于发现Python测试类(类名)

      • python_functions (args): Python测试函数和方法发现的前缀或glob名称(方法名)

      • addopts:添加一个或多个命令行参数,如,添加 -vs 命令参数后:运行pytest test_case.py 等同于 pytest -vs test_case.py

        pytest.ini

        [pytest]
        # 为测试用例添加标签
        markers = login
        search # 修改pytest模块名、类名、用例名称规则(以什么开头:如pytest文件名和用例名默认以test_* 开头或结尾)
        pytest_files = test_* *_test check_*
        pytest_functions = test_* *_test check_* # 添加一个或多个命令行参数,如,添加 -vs 命令参数后:运行pytest test_case.py 等同于 pytest -vs test_case.py
        addopts = -vs --alluredir=./result

pytest框架结构

  • setup() teardown() 类方法运行前后被调用

    • 模块级别:setup_module/teardown_module 全局的、优先级最高
    • 函数级别:setup_function/teardown_function 只在函数用例生效(与方法的级的区别:不在类中)
    • 类级别:setup_class/teardown_class 只在类中前后运行一次(在类中)
    • 方法级别:setup_method/teardown_method 开始与方法的始末、每个方法运行强后都运行一遍(与函数级别的区别:方法在类中,函数不在类中)

pytest参数化与数据驱动

  • 参数化一般与数据驱动一起使用,

    • 参数化:将变化的测试数据以参数的形式传入到测试方法,待测试的输入和输出是一组数据,可以把测试数据组织起来,用不同的测试数据调用相同的测试方法
    • 数据驱动:数据的改变从而驱动自动化的执行,最终引起测试结果的改变,测试数据的数据驱动、测试步骤的数据驱动、配置的数据驱动、po的数据驱动

pytest参数化

  • pytest自带参数化概念

    • 加入参数化装饰器:@pytest.mark.parametrize("a, b, result", [1, 2, 3], [2, 3, 5], [0.3, 1, 1.3])

      • ids参数:定义每一组测试数据生成的测试用例的别名,多少组数据就对应有多少个ids
import pytest
import yaml def add(a, b):
return a + b class TestDate:
@pytest.mark.parametrize("a, b", [(10, 20), (10, 30), (2, 6)])
def test_param(self, a, b):
print(a + b) @pytest.mark.parametrize(["x", "y"], [(10, 20), (10, 30)])
def test_param2(self, x, y):
# print(x + y)
print(add1(x, y)) @pytest.mark.parametrize("a", "b", yaml.safe_load(open(r'E:\data.yaml')))
def test_param5(self, a, b):
print(f'相加等于{add(a, b)}')
  • 运行用例test_parm会得出三条测试用例数据:

pytest异常捕获

设计测试用例的时候要尽可能的区分类型,比如除数为0时,预期结果是抛出异常,则此用例pass,所以使用pytest捕获ZeroDivisionError异常,如果捕获到,则不报出异常 则此测试用例通过

with pytest.raises(ZeroDivisionError, TypeError):

fixture高级用法

fixture 介绍:

  • 官网 Features--Modular有详细介绍
  • fixture又名测试桩子,类似setup teardown
  • fixture 能做到setup teardown 做不到的事情
    • 比如:一个模块里又很多用例,这些方法有的需要的前置条件不一样,如有的需要登录,有的不需要登录

      def login():
      print('登录') def test_search():
      print('搜索') def test_search():
      print('购物') def test_search():
      print('下单')
    • 如,如果使用setup teardown 只能是用例前后被调用,但是去搜索,首先不需要登录,所以就可以把login定义为fixture函数,然后传入到测试方法里

      使用方法:在被重复调用的方法上加上@pytest.fixture()装饰器,如果某个方法需要登录,就传入login

      @pytest.fixture()
      def login():
      print('登录') def test_search():
      print('搜索') def test_search(login):
      print('购物') def test_search(login):
      print('下单')
    • 在命令行中使用执行回溯,可以看到fixture执行的详细过程:pytest test_case.py --setup-show

fixture 作用

  • Fixture是在测试函数运行前后,由pytest执行的外壳函数,代码可以定制,满足多变的测试需求,功能包括:

    • 定于传入测试中的数据集
    • 配置测试前系统的初始状态
    • 为批量测试提供数据源等
  • Fixture是pytest用于将测试前后进行预备,清理工作的代码分类核心测试逻辑的一种机制

fixture用法

  • 1- 类似setup teardown功能,但比setup teardown更灵活
  • 2- 直接通过函数名调用或者装饰去@pytest.mark.usefixtures('test1')
  • 3- 允许使用多个Fixture
  • 4- 使用autouse自动应用,如果由返回值,需要穿fixture函数名
  • 5- 作用域 session>module>class>function

使用-- setup-show 回溯fixture的执行过程

  • pytest test_case.py --setup-show

pytest yield

  • 以上fixture记录的仅仅是setup,即测试用例运行前的操作,如果需要加上teardown的操作,需要在fixture函数中加入 yield

    @pytest.fixture()
    def login():
    print('登录') # 用例运行前登录
    yield # 相当与 return 可以返回一些数据 如 yield token
    print('退出') # 用例结束后退出

conftest + fixture

  • conftest.py文件,它主要是实现数据(fixture)共享的文件,名字是固定的。

    • 1- 第一,conftest.py文件当中,它储存的都是fixture,就是给用例提供做前置准备工作和后置清理工作的一个东西;
    • 2- 第二,conftest.py文件可以将它的fixtures共享到它自己目录下的所有用例,用例当中如果使用fixture的话,是不需用导入conftest.py这个文件的,会直接自动去查找;
    • 3- 第三,conftest.py它是属于层级共享的,也就是说,一个自动化项目当中,可以在不同的包下面去创建conftest.py这个文件。
  • 运行原则:就近原则,如果当前包下没有conftest.py就会往上一层找

fixture 参数化


二、常用插件、数据驱动、编写pytest插件、Allure

pytest常用插件

pip install pytest-ordering:控制用例的执行顺序

  • 建议在编写测试用例的时候,能不让用例顺序执行就不顺序执行,这样可能会更好的暴露出问题
  • 在测试方法上加上装饰器:@pytest.mark.run(order=2)

pip install pytest-dependency:控制用例的依赖关系

ps:设计测试用例的时候进可能不要让用例有顺序,不要让测试用例有依赖关系,如果无法做到,可以临时的用插件解决

  • 官网 : https://pytest-dependency.readthedocs.io/en/latest/usage.html#basic-usage

  • 设置一个用例和一个用例的依赖关系:一旦用例A失败,那么用例B也不会执行。比如:用例A为添加购物车,用例B为去结算,那么如果用例A没有登录就会执行失败,则用例B也就会执行失败

    pytest-dependency 要做的就是,让他们之间存在一种依赖关系:一旦用例A失败,那么用例B也不会执行 SKIP

    import pytest
    # 官方demo: @pytest.mark.dependency() # test_a测试用例设置了dependency依赖关系
    @pytest.mark.xfail(reason="deliberate fail")
    def test_a():
    assert False @pytest.mark.dependency() # test_b测试用例设置了dependency依赖关系
    def test_b():
    pass @pytest.mark.dependency(depends=["test_a"]) # test_c 依赖于测试用例 test_a。 因为test_a断言失败,所以test_c会跳过
    def test_c():
    pass @pytest.mark.dependency(depends=["test_a"]) # test_d 依赖于测试用 test_b
    def test_d():
    pass @pytest.mark.dependency(depends=["test_b", "test_c"]) test_e依赖与测试用例 test_b 和 test_c 因为test_b通过了,但test_c跳过,所以test_e也会跳过
    def test_e():
    pass

pip install pytest-xdist:分布式并发执行测试用例

  • 机制:哪个cpu先执行完一个任务,就下发另一个任务

    • pytest -n 3 :3=当前系统的cpu个数,如果不知系统有多少个cpu或者不知道可以承载多少个进程,使用 pytest -n aotu 自动分发空闲的进程

pip install pytest-rerunfailures:失败重跑

  • pytest --reruns 5 : 如果用例失败,就会重新跑5次
  • pytest --reruns 5 --reruns-delay 2:用例失败后等待2秒后再执行,或者再用例方法上加上装饰器@pytest.mark.flaky(5, reruns-delay=2)

pip install pytest-assume:多重校验

  • 通常一个测试方法中会写多个断言,如果第一条断言过不去,下面的就不执行了,如果我们想报错也往下执行,使用pytest提供的断言方法方法

    • pytest.assume(14) 相当于 assert 14 # 此方法应用场景较少

pip install pytest-random-order:用例随机执行

  • pytest --random-order-seed= 设置一个种子,使用比较少

pip install pytest-html:测试报告

  • 后续使用allure,不做介绍

三、pytest高级用法 hook函数

pytest插件加载方式

  • 内置plugin

    • 从代码内部的 _pytest 目录加载

      • External Libraries - site-package - _pytest - hookspec.py

        • hookspec.py 有很多方法 即我们所说的hook方法,我们可以改写hook方法来满足我们一些需求
  • 外部插件(第三方插件)

  • conftest.py 存放的本地插件(重点):

    • 自动模块发现机制
  • pytest --trace-config 查看当前pytest中所有的plugin(带有hook方法的文件)

Allure 生成测试报告

另起...

python测试框架-pytest的更多相关文章

  1. Python测试框架pytest入门基础

    Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.T ...

  2. Python测试框架pytest命令行参数用法

    在Shell执行pytest -h可以看到pytest的命令行参数有这10大类,共132个 序号 类别 中文名 包含命令行参数数量 1 positional arguments 形参 1 2 gene ...

  3. 全功能Python测试框架:pytest

    python通用测试框架大多数人用的是unittest+HTMLTestRunner,这段时间看到了pytest文档,发现这个框架和丰富的plugins很好用,所以来学习下pytest.   imag ...

  4. 可能是 Python 中最火的第三方开源测试框架 pytest

    作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...

  5. Python最火的第三方开源测试框架 ——pytest

    一.介绍 本篇文章是介绍的是Python 世界中最火的第三方单元测试框架:pytest.它有如下主要特性: assert 断言失败时输出详细信息(再也不用去记忆 self.assert* 名称了) 自 ...

  6. 用 Python 测试框架简化测试

    用 Python 测试框架简化测试 摘要:本文将向您介绍了三种流行 Python 测试框架(zope.testing,py.test,nose)的基本特性,并讨论新一代的测试风格. 最近出现了行业级的 ...

  7. 【转载】Python测试框架doctest

    原文在这里 :Python测试框架doctest 先记录一下,直接复制粘贴后,排版是乱的,后续再弄.

  8. <自动化测试>之<使用unittest Python测试框架进行参数化测试>

    最近在看视频时,虫师简单提到了简化自动化测试脚本用例中的代码量,而python中本身的参数化方法用来测试很糟糕,他在实际操作中使用了parameterized参数化... 有兴趣就查了下使用的方法,来 ...

  9. python 测试框架nose

    python测试框架nose nose不是python自带模块,这里我才用pip的方式安装 pip install nose 这样就完成了安装,然后再确认下是否安装成功了,直接打开cmd输入noset ...

随机推荐

  1. CF253A Boys and Girls 题解

    Content 有 \(n\) 个男生.\(m\) 个女生坐在一排,请求出这样一种方案,使得相邻两个座位之间的人的性别不同的次数最多. 数据范围:\(1\leqslant n,m\leqslant 1 ...

  2. Shell之awk常用用法

  3. 选课系统V1.0

    tree . . ├── bin │   ├── __init__.py │   └── start.py #启动文件 ├── conf │   ├── __init__.py │   └── set ...

  4. 使用.NET 6开发TodoList应用(5.1)——实现Repository模式

    需求 经常写CRUD程序的小伙伴们可能都经历过定义很多Repository接口,分别做对应的实现,依赖注入并使用的场景.有的时候会发现,很多分散的XXXXRepository的逻辑都是基本一致的,于是 ...

  5. 【LeetCode】138. Copy List with Random Pointer 复制带随机指针的链表 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人公众号:负雪明烛 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https:/ ...

  6. 1678 lyk与gcd

    1678 lyk与gcd 基准时间限制:2 秒 空间限制:131072 KB 这天,lyk又和gcd杠上了.它拥有一个n个数的数列,它想实现两种操作. 1:将  ai 改为b.2:给定一个数i,求所有 ...

  7. Codeforces 777B:Game of Credit Cards(贪心)

    After the fourth season Sherlock and Moriary have realized the whole foolishness of the battle betwe ...

  8. matplotlib 进阶之Tight Layout guide

    目录 简单的例子 Use with GridSpec Legend and Annotations Use with AxesGrid1 Colorbar 函数链接 matplotlib教程学习笔记 ...

  9. [C++]C++ STL库函数大全

    #include <assert.h> //设定插入点 #include <ctype.h> //字符处理 #include <errno.h> //定义错误码 # ...

  10. 对vector和map容器的删除元素操作

    /** * 删除头部元素 * 切割map到指定的个数 * @param map * @param i * @return */ map<int, Rect> PublicCardFrame ...