当前位置: 首页 > news >正文

自动化测试-pytest框架-进阶

在我们进行使用某一个接口的时候,会发现有一些接口会有一些前置条件或者是后置条件,俗称上下游,比如在使用图书管理系统的查询图书接口之前,我们要先进行登录,或者说在借阅一本书之前要先去查这本书是否还有剩余,这样的一些额外的操作可以保证我们流程正常的运行,模拟用户最真实的使用步骤,确保测试的真实性

pytest框架有以下三种设置前后置的方法:

  • 分别使用 setup_method teardown_method 进行对方法的前后置操作

import pytestclass TestFacing:def setup_method(self):print("这是前置操作")def test_1(self):print("测试用例1")def test_2(self):print("测试用例2")def teardown_method(self):

执行代码之后,可以看到两个用例都分别输出了前后置:

  • 分别使用 setup_class teardown_class 对整个测试类进行前后置操作

import pytestclass TestFacing:# 使用类前后置def setup_class(self):print("这是类前置操作")def teardown_class(self):print("这是类后置操作")def test_1(self):print("测试用例1")def test_2(self):print("测试用例2")

执行代码之后,可以看到只有在整个运行流程的开头和结尾输出了前后置:

  • 使用 fixture ,这是pytest推荐的实现测试用例前后置的操作

断言

断言(assert)是一种辅助测试的工具,用来检查程序的运行结果是否符合预期.如果断言失败(即条件为假,结果不符合期待值),python解释器就会抛出一个 AssertionError 异常.

pytest 允许你在 Python 测试中使用标准的 Python assert 语句来验证预期和值。

# 条件语句必须是一个布尔表达式,报错信息时断言失败会显示的错误信息
assert 条件语句,报错信息(非必要)

例子:

基本数据类型的断言

import pytestclass Test:def test_1(self):a = 1b = 1assert a == bdef test_2(self):a = 1b = 2assert a == b , "两个数据不相等!"

数据结构断言

class Test:def test1(self):print("断言列表")a = [1,"test",3]b = [1,"test",3]assert a == bdef test2(self):print("断言元组")a = ("test",4,5)b = ("test",4,5)assert a == bdef test3(self):print("断言字典")a = {"test1":1,"test":2}b = {"test1":1,"test":2}assert a == bdef test4(self):print("断言集合")a = {4,"test6",89}b = {4,"test6",89}assert a == b

函数断言

def get_result(a,b):assert a!=0return a/bclass Test:def test1(self):print(get_result(4, 2))def test2(self):print(get_result(0, 2))

接口返回值断言

有一个免费的API可以用来进行测试学习: https://jsonplaceholder.typicode.com/

断言整个返回值
import requestsclass Test:def test1(self):print("断言接口返回值-完整字段/值")url = "https://jsonplaceholder.typicode.com/posts/1"actual_val = requests.get(url=url).json()export_val = {"userId": 1,"id": 1,"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit","body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}assert  actual_val == export_val

断言返回值的重要字段
import requestsclass Test:def test(self):url = "https://jsonplaceholder.typicode.com/posts"actual_val = requests.get(url=url).json()for i in range(1,5):assert i == actual_val[i-1]["id"]

断言接口html返回值
import requestsclass Test:def test1(self):print("期望值存在,断言成功")url = "https://jsonplaceholder.typicode.com/"actual_val = requests.get(url=url).textassert "Use your own data" in actual_valdef test2(self):print("期望值不存在,断言失败")url = "https://jsonplaceholder.typicode.com/"actual_val = requests.get(url=url).textassert "Ue yur on data" in actual_val

参数化

参数化是自动化测试的一个重要组成部分,通过定义设计参数和规则,让测试流程更加灵活可控

通过使用pytest内置的 pytest.mark.parametrize 装饰器来对测试函数的参数进行参数化

方法参数化
import pytestclass Test:@pytest.mark.parametrize("input,except_val",[("8+7",15),("8*7",56)])def test(self,input,except_val):assert eval(input) == except_val

使用装饰器定义了两组不同的元组,并作为参数进行传递,测试函数使用参数运行了两次,分别判断不同的参数元组

类参数化

除了对某一个测试方法进行参数化,我们还可以对全局进行参数化

import pytest@pytest.mark.parametrize("input,except_val",[(1,2),(3,6),(5,10)])
class Test:def test1(self,input,except_val):assert input*2 == except_valdef test2(self,input,except_val):assert input*input < except_val*except_val

自定义参数化数据源
import pytestdef get_result():return ["a","b"]class Test:@pytest.mark.parametrize("data",get_result())def test(self,data):assert data is not Nonedata += "c"print(f"data: {data}")

Fixture

Fixture 是pytest的一种机制,用于提供测试函数所需要的资源(参数化)以及处理前后置操作.用于测试环境和数据的准备

函数调用

没有进行标记的fixture方法和标记之后的方法的调用完全不一样,前者需要在方法体中进行调用,后者可以将函数名作为参数进行调用

如果在测试脚本中存在的很多重复或者公共的代码以及数据对象时,可以使用fixture

没有标记的方法调用
def fixture():print("这是调用的fixture方法")class Test:def test(self):fixture()print("测试结束")

标记的方法调用
import pytestclass Test:@pytest.fixturedef fixture(self):print("这是调用的fixture方法")def test(self,fixture):print("测试结束")

前置操作

可以使用fixture来进行前置的设置操作

我们先进行了登录操作,然后在进行查询操作,这样才能进行借书操作,而借书操作就是我们想要测试的接口

import pytestclass Test:@pytest.fixturedef login(self):print("登录操作")@pytest.fixturedef search(self,login):print("查询操作")def test1(self,search):print("成功借书,<book1>")def test2(self,search):print("成功借书,<book2>")

fixture嵌套

在测试当中,并不局限于只是用单个的fixture,我们可以使用任意数量的fixture来得到自己想要的测试效果,并且fixture方法也可以使用其他的fixture方法

import pytestclass Test:@pytest.fixturedef fixture_1(self):return ["a"]@pytest.fixturedef fixture_2(self,fixture_1):return fixture_1+["b"]def test(self,fixture_2):fixture_2 = fixture_2+["c"]except_val = ["a","b","c"]assert  except_val == fixture_2print("断言成功")

请求多个fixture

我们也可以一次性使用多个fixture

import pytestclass Animals:def __init__(self,name):self.name = namedef __eq__(self, other):return self.name == other.nameclass Test:@pytest.fixturedef fixture_1(self):return Animals("cat")@pytest.fixturedef fixture_2(self):return Animals("dog")@pytest.fixturedef create_zoo(self,fixture_1,fixture_2):return [fixture_1,fixture_2,Animals("wolf")]def test(self,fixture_1,create_zoo):assert fixture_1 in create_zooprint("断言成功")

yield fixture

进行测试的时候,我们并不希望当前运行的测试用例影响到其他的测试用例,所以就需要用例进行自我清洁,所以fixture有一个拆卸系统

而这里并不能使用 return 来进行清理,同时fixture的所有拆卸代码都是放在 yield 之后

当确定了 fixture 的线性顺序,将运行的每个 fixture 直到他返回 yield ,然后继续执行列表中的下一个 fixture 做同样的操作.测试结束之后, pytest 就会逆向遍历 fixture 列表,对于每个 yield fixture ,运行 yield 语句之后的代码

前后置操作
import pytestclass Test:@pytest.fixturedef login_logout(self):print("前置操作,登录中……")yieldprint("后置操作,注销中……")def test(self,login_logout):print("系统登录成功!")

创建文件句柄+关闭文件
import pytestclass Test:@pytest.fixturedef open_close(self):print("打开文件")file = open(r"C:\测试\接口自动化\ApiAutoTest01\test_module\fixtureUse\text.txt", "r", encoding="utf-8")yield filefile.close()print("文件关闭")@pytest.fixturedef file_write(self):print("进行文件内部操作")file = open(r"C:\测试\接口自动化\ApiAutoTest01\test_module\fixtureUse\text.txt", "w",encoding="utf-8")return filedef test(self,open_close,file_write):file1 = file_writefile1.write("进行测试!!!")file1.close()file2 = open_closestr = file2.read(20)print(f"文件内容:{str}")

参数化

格式:

@pytest.fixture(scope='',params='',autouse='',ids='',name='')

参数介绍:

  • scope 参数用于控制 fixture 的作用范围,决定了 fixture 的生命周期。可选值有:

    • function(默认):每个测试函数都会调用一次 fixture

    • class:在同一个测试类中共享这个 fixture

    • module:在同一个测试模块中共享这个 fixture。(一个文件里)

    • session:整个测试会话中共享这个 fixture

  • autouse 参数默认为 False。如果设置为 True,则每个测试函数都会自动调用该 fixture,无需显式传入

  • params 参数用于参数化 fixture,支持列表传入。每个参数值都会使 fixture 执行一次,类似于 for 循环

  • ids 参数与 params 配合使用,为每个参数化实例指定可读的标识符(给参数取名字)

  • name 参数用于为 fixture 显式设置一个名称。如果使用了 name,则在测试函数中需要使用这个名称来引用 fixture(给 fixture 取名字)

scope使用

除开 module session 需要多个测试文件进行配合,构造全局的场景以外,其余两个都是可以单独进行使用的

Function
import pytestclass Test:@pytest.fixture(scope='function')def init(self):print("初始化……")yieldprint("注销中……")def test1(self,init):print("测试用例1")def test2(self,init):print("测试用例2")

Class
import pytestclass Test:@pytest.fixture(scope='class')def init(self):print("初始化……")yieldprint("注销中……")def test1(self, init):print("测试用例1")def test2(self, init):print("测试用例2")

全局前后置

需要配合 conftest.py 文件一起使用,这个文件是固定的名字,在这个文件中进行前后置的配置

可以在不同的目录下创建多个文件,每个文件都是对其所在的文件以及子文件生效

module
# conftest.py
import pytest@pytest.fixture(scope='module',autouse=True)
def init():print("正在初始化……")yieldprint("正在注销中……")# 代码1
class Test:def test1(self):print("测试系统1的用例1")def test2(self):print("测试系统1的用例2")# 代码2
def test():print("这是额外的测试用例")class Test:def test1(self):print("测试系统2的用例1")def test2(self):print("测试系统2的用例2")

Session
# conftest.py
import pytest@pytest.fixture(scope='session',autouse=True)
def init():print("正在初始化……")yieldprint("正在注销中……")# 代码1
class Test:def test1(self):print("测试系统1的用例1")def test2(self):print("测试系统1的用例2")# 代码2
def test():print("这是额外的测试用例")class Test:def test1(self):print("测试系统2的用例1")def test2(self):print("测试系统2的用例2")

autouse使用

 autouse 默认为 false ,也就是当前的 fixture 需要手动显示调用,而当 autouse=True 时, fixture 会在测试函数执行之前进行自动调用,无论测试函数时候显示的使用了 fixture 

import pytestclass Test:@pytest.fixture(scope='class',autouse=True)def init(self):print("正在进行初始化……")yieldprint("正在进行注销……")def test1(self):print("测试用例1")def test2(self):print("测试用例2")

params使用

可以使用 params 进行参数化,我们需要使用 request 来继续取值(变量名是固定的)

import pytestclass Test:@pytest.fixture(params=["a","b"])def get_result(self,request):return request.paramdef test(self,get_result):assert get_result is not Noneprint(f"结果为:{get_result}")

http://www.dtcms.com/a/574238.html

相关文章:

  • 学习做网站的网站wordpress 教程 插件
  • (2)pytest+Selenium自动化测试-环境准备
  • 【项目】小型支付商城 MVC/DDD
  • uni-app开发app移动端使用ucharts自定义标签栏Tooltip
  • 《uni-app跨平台开发完全指南》- 03 - Vue.js基础入门
  • uniapp中的静态资源文件,如图片等文件,h5端设置本地与生产测试环境的区别,本地不加前缀,生产测试添加前缀,h5端的已进行测试可行,非h5的未进行测试
  • uni-app + Vue3 实现折叠文本(超出省略 + 展开收起)
  • 云南微网站搭建wordpress插件安装不
  • 汽车行业网站设计chrome google
  • 好用的云电脑!手机怎么用UU远程云电脑玩电脑游戏?
  • 网站开发安装网站原型图软件
  • 坑#Spring Cloud Gateway#DataBufferLimitException
  • 15年做哪些网站能致富网页升级访问紧急通知狼
  • ping: baidu.com: 域名解析暂时失败
  • 上海网站设计方法有哪些网站上可以做试卷
  • 网站建设项目立项登记 表自己家的电脑宽带50m做网站服务器
  • 宜宾公司做网站建设一个电子文学网站资金多少
  • 效率提升的声音助手——工业物联网中的智能化变革
  • 普罗宇宙发布大白机器人2.0 及灵巧手,携手京东加速全球化落地
  • Java 集合框架:List 体系与实现类深度解析
  • 阿里云 ip 网站哈尔滨行业网站建设策划
  • 注册了网站怎么建设网站视听内容建设
  • 泉州专业做网站网上做网站怎么防止被骗
  • 使用 ECharts + ECharts-GL 生成 3D 环形图
  • 做电影网站视频放在那里南阳做那个网站好
  • 美德的网站建设局网站建设招标
  • 学校网站的建设论文怎么建网站做推广
  • 第四阶段通讯开发-7:TCPListener和TCPClient
  • 中国最权威的网站排名电脑网站安全证书有问题如何解决
  • 网站建设实训小结在线网站流量查询