pytest测试框架基本使用

入门

介绍

  • pytest 能够支持简单的单元测试和复杂的功能测试;
  • pytest 可以结合 Requests 实现接口测试; 结合 Selenium、Appium 实现自动化功能测试;
  • 使用 pytest 结合 Allure生成测试报告
  • 集成到 Jenkins 中可以实现持续集成。

基础

  • 安装: pip install pytest

  • pytest编写规则:

    • 文件以 test_ 开头 或者 _test 结尾
    • 类以 Test 开头 ,测试类中不能有 __init()__ 方法
    • 方法以 test_ 开头
  • 测试装置,前置后置操作

    • 模块级: setup_module、teardown_module 整个py文件开始结束执行
    • 函数级:setup_function、teardown_function ,只对函数用例生效(不在类中)
    • 类级: setup_class、teardown_class
    • 方法级:setup_method()、teardown_method 在类中
    • setup、teardown() 方法级别
  • pycharm配置

    配置在pycharm 可以点击 三角形按钮执行 测试用例(类似main)

    windows: file-> setting->Tools->Python Integrated Tools :将TestingDefault test runner 设置为pytest

  • 运行方式

    if __name__ == '__main__':
        # 1、运行当前目录下所有符合规则的用例,包括子目录(test_*.py 和 *_test.py)
        pytest.main()
        # 2、运行test_mark1.py::test_dkej模块中的某一条用例
        pytest.main(['test_mark1.py::test_dkej','-vs'])
        # 3、运行某个 标签
        pytest.main(['test_mark1.py','-vs','-m','dkej'])
    

pytest命令运行

  • 单独运行一个文件/类/方法

  • 运行一个文件: pytest test_add.py

  • 运行一个类:pytest 文件名::类名,运行某个模块的测试类

    # 运行test_add模块中的 TestAdd 类
    pytest test_add.py::TestAdd
    
  • 运行某个类中的方法:pytest 文件名::类名::方法名

    # 运行test_add模块中的 TestAdd 下的test_add()方法
    pytest test_add.py::TestAdd::test_add				
    
  • 常用参数:

    • pytest -v :打印详细运行日志信息
    • pytest -s:打印输出到控制台的信息(如print打印的结果)
    • pytest -x 文件名 一旦运行到报错,停止运行
    • pytest --maxfail=[num] 失败用例数量达到num停止运行
    • pytest -k "类名 and not 方法名":运行某个类,但不允许其中某个方法
    • pytest -m 标记名: 运行指定标记的用例(PS:通过@pytest.mark.P0标记用例)
    • pytest --lf/--last-failed : 运行上次失败的用例,没有失败的则全部运行
    • pytest --ff/--failed-first: 先运行上次失败,在执行成功
    • pytest --collect-only : 只收集用例不执行
    • pytest --junitxml=./result.xml : 生成执行结果文件

pyest.ini 配置

在配置文件中科因进行以下操作:

  • 修改用例的命名规则

  • 指定执行目录,排除搜索目录

    ;设置执行的路径
    testpaths = testcases
    ;忽略某些文件夹/目录
    norecursedirs = result logs datas test_demo*
    
  • 添加标签,防止运行过程报警告错误

  • 添加默认参数

    addopts = -v -s --alluredir=./results
    

在项目目录创建 pytest.ini 文件,使用时windows环境删除中文

[pytest]
;addopts:配置命令行参数,用空格进行分隔
;可执行标记为mark的对应用例,用or表示标记为demo或者smoke的用例都会执行
addopts = -vs  --alluredir=./results/json --clean-alluredir -m "demo or smoke"

;避免ids 中文乱码
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True

;注册 mark 标记
markers =
    demo : marks tests as demo
    smoke: marks tests as smoke
    uat : marks tests as uat
    test : marks tests as test

# 指定pytest最低版本
minversion = 5.0

;测试用例的路径,可自己配置,
;../pytestproject为上一层的pytestproject文件夹
;./testcase为pytest.ini当前目录下的同级文件夹
;改变用例的查找路径规则,当前目录的testcase文件夹
testpaths =./testcase

;模块名的规则,配置测试搜索的模块文件名称
python_files = test*.py

;类名的规则,配置测试搜索的测试类名
python_classes = Test*

;方法名的规则,配置测试搜索的测试函数名
python_functions = test

参数化与数据驱动

在pytest中使用 @pytest.mark.parametrize装饰器实现参数化

  • 用法

    @pytest.mark.parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None)):

参数 说明
argnames 必传,参数名, 以逗号分隔的字符串,表示一个或多个参数名称(key),或参数字符串的列表/元组
argvalues 必传,参数值,若argnames有一个单值列表传入,若argnames有多个,以套用元组的或者列表嵌套的展示,无组内与参数名一一对应
indirect 为true时,那argnames一定是一个fixture函数名称,argvalues值将传入对应的fixture内,相当于@pytest.fixture(params=)的用法,默认False
ids 标记子用例执行名称,与argvalues数量一致,未指定自动生成,默认None
# 其中'a,b,expect'为argnames, [[1, 2, 3], [-0.01, 0.02, 0.01],[10,0.02,10.02]]为argvalues
@pytest.mark.parametrize('a,b,expect',
                             [[1, 2, 3], [-0.01, 0.02, 0.01],[10,0.02,10.02]],
                             ids=['两个整数相加', '2个浮点数','整数加浮点数'])
    def test_add(self, a, b, expect):
        result = self.cal.add(a, b)
        # 断言预期结果等于实际结果
        assert result == expect

进阶

Allure生成测试报告

  • allure 安装

    allure 需要java的运行环境,建议安装java8,

    java安装完成后,安装alure的zip包

    之后需要将allure的bin目录配置到环境变量中

安装allure-pytest

  • pip installl allure-pytest

  • 运行:

    • 生成中间结果 pytest —alluredir=./report/

    • 生成并打开html报告: allure serve ./report

    • 只生成报告:allure generate ./report

    • 清除之前的报告pytest --clean-alluredir

fixture 在自动化中的应用

特点及优势

  • 1、命令灵活:对于 setup,teardown,可以不起这两个名字
  • 2、数据共享:在 conftest.py 配置⾥写⽅法可以实现数据共享,不需要 import 导⼊。可以跨⽂件共享
  • 3、scope 的层次及神奇的 yield 组合相当于各种 setup 和 teardown
  • 4、实现参数化,可以将函数名,作为参数传递给另一个函数进行调用

基本用法

场景:

测试⽤例执⾏时,有的⽤例需要登陆才能执⾏,有些⽤例不需要登陆。

setup 和 teardown ⽆法满⾜。fixture 可以。默认 scope(范围)function

  • 步骤:
    • 1.导⼊ pytest
    • 2.在登陆的函数上⾯加@pytest.fixture()
    • 3.在要使⽤的测试⽅法中传⼊(登陆函数名称),就先登陆
    • 4.不传⼊的就不登陆直接执⾏测试⽅法。

作用域

取值 范围 说明
function 函数级 每一个函数或方法都会调用
class 类级别 每个测试类只运行一次
module 模块级 每一个.py文件调用一次
package 包级 每一个python包只调用一次(暂不支持)
session 会话级 每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法

yield 关键字

场景:

你已经可以将测试⽅法【前要执⾏的或依赖的】解决了,测试⽅法后销毁清除数据的要如何进⾏呢?

解决:

通过在fixture 函数中加⼊ yield 关键字,yield 是调⽤第⼀次返回结果,第⼆次执⾏它下⾯的语句返回。

步骤:

在@pytest.fixture(scope=module)。在登陆的⽅法中加 yield,之后加销毁清除的步骤

数据共享

使⽤ conftest.py 这个⽂件进⾏数据共享,并且他可以放在不同位置起着不同的范围共享作⽤

  • conftest ⽂件名是不能换的
  • 放在项⽬下是全局的数据共享的地⽅

系统执⾏到参数 login 时先从本模块中查找是否有这个名字的变量,如果没有之后在 conftest.py 中找是否有

自动应用

场景:

不想原测试⽅法有任何改动,或全部都⾃动实现⾃动应⽤,

没特例,也都不需要返回值时可以选择⾃动应⽤

解决:

使⽤ fixture 中参数 autouse=True 实现

步骤:

在⽅法上⾯加 @pytest.fixture(autouse=True)

参数化()

场景:

测试离不开数据,为了数据灵活,⼀般数据都是通过参数传的

解决:

fixture 通过固定参数 request 传递

步骤:

在 fixture 中增加@pytest.fixture(params=[1, 2, 3, ‘linda’])

在⽅法参数写 request,方法体里面使用 request.param 接收参数

Fixture的用法总结

  • 模拟setup,teardown(一个用例可以引用多个fixture)
  • yield 的用法
  • 作用域( session,module, 类级别,方法级别 )
  • 自动执行 (autouse 参数)
  • conftest.py用法,一般会把fixture写在conftest.py 文件中(这个文件名字是固定的,不能改)
  • 实现参数化

外部插件

  1. 多进程执行用例:

    • 插件:pytest-xdist

    • 安装: pip insatll pytest-xdist

    • 运行: pytest -n auto 自动识别CPU核数,调用空闲的CPU,也可以指定 数字

内置hook体系

后续补充

插件开发

后续

pytest的demo

你可能感兴趣的:(pytest测试框架,pytest)