接口自动化测试-pytest框架

pytest接口自动化测试框架搭建 由于用例中用到了@pytest.mark.httptest给用例打标,因此需要创建pytest.ini文件,并在里面添加markers = httptest,不然会有warning,说这个Mark有问题。从Excel文件中读取数据的工具类:get_excel_data_utils.py(虽然本次框架中暂时未采用存放接口数据到Excel中,但也写了个工具类,需要的时候可以用)因此数据文件中url只填写后半段,不填域名。除了上面提到的读取Json文件工具类:read_jsonfile_utils.py, 阅读详情

1. 使用pytest完成接口自动化

1.1. pytest 简介

pytest 是 Python 的一款开源测试框架。

主要特点:

  • 简单灵活,文档丰富;
  • 能够支持单元测试、功能测试、接口自动化测试等;
  • 具有众多第三方插件,且可以自定义扩展;
  • 支持参数化,可控制测试用例的粒度;
  • 可以很好的和 CI 工具结合,例如 Jenkins 。

1.2. 使用参考

1.2.1. 命名约束

  • 测试文件以"test_"开头/以"_test"结尾
  • 测试类以"Test"开头,并且不能带有 __init__ 方法
  • 测试函数以"test_"开头

默认情况下,pytest 查找当前目录下所有以 test 开始或结尾的 Python 脚本,并执行文件内的所有以 test 开始的函数和方法。

1.2.2. 运行

在终端按需输入以下命令来运行 case:

  • 运行所有 case :pytest 
  • 运行指定 case :pytest testCase/test_demo1.py
  • 运行关键字匹配的 case :pytest -k “表达式”
  • 运行标记匹配的 case :pytest -m "标记"
  • 运行后控制台展示详细信息:pytest -v
  • ...

1.2.3. 断言assert

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

可以指定断言失败的返回信息,举例如下:

assert response["result_code"] == expected["response"]["result_code"], "实际的返回结果是:{}".format(response["result_code"])

1.2.4. fixture

fixture 是 pytest 特有功能,目的是提供一种手段去运行最基本的、重复的测试内容,是将测试前后的预备工作、清理工作的代码分离出核心测试逻辑的一种机制。通常用来对测试方法、测试函数、测试类和整个测试文件进行初始化或还原测试环境。

@pytest.fixture(scope="function", params=None, autouse=False, ids=None, name=None)

  • scope:作用域,(

    function:方法,默认为function

    class:类

    module:.py文件

    session:会话)

  • params:可选的参数列表,可使多个参数调用fixture功能
  • autouse:是否默认调用该fixture,默认为False
  • ids:每个字符串id的列表
  • name:装饰器名字

1.2.4.1. fixture 作为函数参数

可以通过使用 @pytest.fixture 注册成为一个 fixture 函数,来为测试方法提供一个 fixture 对象。 

如下图所示,connect_mysql_uds 函数被注册成了一个 fixture 函数,在 test_query_couplist 方法中可以直接被作为参数使用。

1.2.4.2. 在 conftest.py 中管理 fixture

若希望多个测试文件共享fixture,可以在某个公共目录下建立一个conftest.py文件,将fixture放在其中。

  • conftest.py文件用于存放fixture的配置文件,文件名是固定的
  • conftest.py是层级共享的,存放位置决定了其作用的范围
  • conftest.py文件无需被import,会自动执行

1.2.4.3. 执行顺序

(作用范围从大到小的排序:session>module>class>function)

  • 较高作用范围的 fixture(例如session会话级)比低范围的 fixture(例如function函数级或class类级)优先执行。
  • 相同范围的 fixture 对象的按引入的顺序或依赖关系按顺序调用

1.2.4.4. yield

yield 语句之后的所有代码都视为 teardown 代码。

举例,如下图所示,整个会话结束后,会打印出”关闭数据库”的语句。 

1.2.5. mark

1.2.5.1. 标记和分类用例

@pytest.mark.level

用法步骤:

a. 先在 pytest.ini 文件中对标签进行注册

b. 对用例进行标记

@pytest.mark.P0

c. 运行指定标记的用例

在终端输入: pytest -m "P0"

1.2.5.2. 标记跳过用例

无条件跳过:

@pytest.mark.skip(reason="跳过原因描述")

在指定条件下跳过:

@pytest.mark.skipif(condition, reason="跳过原因描述")

1.2.5.3. 标记用例为预期失败

@pytest.mark.xfail(reason="预期失败描述")

对于功能未完成或已知有问题的用例,可以用 xfail 标记,这样即使断言失败,也不会影响其他测试用例的的执行。

执行 case 后,控制台中显示:

  • XFAIL:表示预期失败,实际也失败
  • XPASS:表示预期失败,实际运行没有失败

1.2.5.4. 参数化

我们进行接口测试时,往往很多时候操作步骤都是一样的,只有数据不一样,这时候就可以使用参数化功能,来减少代码冗余。

@pytest.mark.parametrize(argnames, argvalues, ids=None)

  • argnames:参数名称,字符串格式
  • argvalues:参数值列表,列表格式
  • ids:用例的 ID ,字符串列表格式

举例,如下图所示,装饰器会自动对 list_params 解包并赋值给装饰器的第一参数。装饰器的第一个参数中逗号分隔的变量可以作为测试方法的参数,在测试方法内就可以直接获取这些变量的值。

1.2.6. Allure

Allure 是一种灵活、轻量级、多语言的测试报告工具,以简洁精美的 web 报告形式展示。

Python 中有一个第三方库:allure-pytest,用于连接 pytest 和 allure ,使它们可以更好的配合使用。

Allure的常用用法:

使用方法

说明

@allure.epic()描述史诗,即未拆解的story
@allure.feature()描述功能模块
@allure.story()描述用户故事
@allure.title()描述用例标题
@allure.step()描述用例步骤
@allure.severity()描述用例等级:blocker,critical,normal,minor,trivial

报告的主要页面介绍:

  • Graphs

该页面展示本次执行结果的统计信息,比如执行结果成功失败比例、测试用例等级分布、用例执行时间等。

  • Behaviors

该页面根据代码中设定的 @allure.feature()、@allure.story() 等来展示用例执行的结果,这里可以看到用例执行的详细信息。

pytest接口自动化测试框架搭建的全过程 Python接口自动化测试零基础入门到精通(2025最新版)pytest是Python的一种单元测试框架,可用来组织用例执行,用例断言,下面这篇文章主要给大家介绍了关于pytest接口自动化测试框架搭建的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下。 阅读详情

相关推荐

软件测试基础/requests+Pytest接口自动化测试实战

相关视频涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。

开源接口自动化测试工具AutoMeter

AutoMeter一站式提供项目管理、微服务、API接口、用例、环境管理、测试管理、前置条件、测试集合、变量管理、测试计划、Mock、测试报告等功能。在项目开发、迭代交付过程中,开发人员和测试人员需要针对系统微服务API进行调试、回归测试和性能测试,AutoMeter正是为此需求而设计的。AutoMeter作为一款开源的接口自动化测试平台,以其简洁的配置、强大的功能和良好的扩展性,为软件开发团队提供了一种高效、可靠的测试手段。

xuweilin的博客 1829

STM32-TIM4-定时器中断

#include "project.h" #include "timer.h" //TIM4_Init(2000 ,72);//定时2ms /* 定时器中断的定时时间设定 定时器只需要配置时钟、TIM和NVIC即可 */ void TIM4_Init(u16 period, u16 prescaler) { NVIC_InitTypeDef NVIC_InitStructure; TIM_...

snaygo 6205

Python 接口自动化测试

通过第四模块的接口开发,我们知道接口的请求方式有多种,在接口测试时我们不可能针对不同请求方式的接口不断的改变它的请求方法形式和参数,所以可以将多种不同请求方式统一整合,只改变请求方法(GET、POST、DELETE、UPDATE)来切换不同的请求形式。接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。

2301_80119579的博客 946

【ISP图像处理】Demosaic去马赛克技术演进与边缘优化策略

本文深入解析了ISP图像处理中的Demosaic(去马赛克)技术。从Bayer阵列原理出发,梳理了从双线性插值、Hamilton-Adams边缘导向算法到利用通道相关性与自相似性的技术演进历程,并重点探讨了针对边缘与纹理伪影的优化策略,为工程实践中的算法选型与硬件协同设计提供了专业指导。

weixin_29091445的博客 389

相机标定原理与张氏标定法

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

heeweii的博客 2280

【测试技术-自动化测试-pytest】Pytest基础总结

本文介绍了pytest测试框架基础,包括用例运行方式、用例运行设置方式、固件设置和测试报告输出。

weixin_42115131的博客 1723

深入剖析一个卷积块(ConvBlock)

深入剖析一个卷积块(ConvBlock)

qq_45670407的博客 1926

Pytest——接口自动化

pytest本身属于UnitTest的升级版。在python环境中,pytest可以直接调用UnitTest的内容来进行实现。pytest是一个非常成熟的测试框架,最大的特点就是具备有各种第三方库的支持。对于使用方面会更加的自由。

weixin_74783615的博客 8080

水环境综合管控平台完整方案

水环境综合管控平台项目(2026-2027)摘要 项目概况: 总投资5亿元的水环境综合管控平台项目,是国家数字政府与生态文明建设战略的重要实践。项目严格遵循2026年最新政策标准,整合物联网、大数据和AI技术,构建覆盖水质监测、污染溯源、生态保护等全流程的智能管控体系。 核心内容: 系统架构:采用五层设计(基础设施层至展示层),集成10大核心功能模块,包括水质动态监测、污染智能溯源和生态评估预警系统; 技术创新:运用2026年最新边缘计算和数字孪生技术,实现毫秒级水质异常响应和三维流域仿真; 实施规划:分7

随读手记 405

ESP32-C3微型9轴感知模块的硬件工程实践

在嵌入式系统小型化趋势下,低功耗微控制器与多传感器融合成为智能终端的基础技术路径。其核心原理在于芯片能效比、射频合规性与电源噪声抑制的协同优化,技术价值体现在降低认证门槛、提升EMC鲁棒性及保障MEMS传感器精度。典型应用场景包括可穿戴设备、微型无人机姿态控制和工业边缘传感节点。本文围绕ESP32-C3平台展开,深入解析QFN封装选型逻辑、同步降压电源设计、LSM9DS1九轴校准策略等关键环节,覆盖FCC/CE认证规避、USB-C接口EMC防护等高频工程痛点。

weixin_42607969的博客 370

python使用pytest接口自动化测试的使用

利用pytest对一个接口进行各种场景测试并且断言验证

软件测试小dao 1169

ADS基础教程22 - 有限元电磁仿真(FEM)

一、引言二、FEM操作过程1.新建Layout1.新建Layout2.EM设置3.设置Frequency plan4.设置Output plan5.设置Options6.设置网格频率7.仿真结果三、总结介绍了在ADS中如何进行FEM仿真过程。END!}}END!

XZ_ZC的博客 2584

pytest接口自动化测试框架 | 汇总

视频来源B站《冒死上传!pytest接口自动化测试框架(基础理论到项目实战及二次开发)教学视频【软件测试】》一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!...

团爸讲算法 9725

铁路场景雷达点云目标识别与追踪系统

本文介绍了一种基于毫米波雷达的铁路货运车站安全监控系统。该系统采用分布式架构,通过多个毫米波雷达节点采集点云数据,经过坐标转换、多雷达融合等处理后,利用机器学习算法实现列车、行人等目标的实时识别与追踪。系统包含数据采集层、处理层、目标识别层、追踪层、预警决策层和可视化层,能够克服传统视频监控受环境影响大的缺点,实现全天候可靠监测。文中详细展示了雷达数据解析和点云预处理的代码实现,包括坐标转换、数据格式解析和体素网格滤波等关键技术。该系统可有效预警铁路场景下的碰撞风险,提升货运车站的安全管理水平。

huanghm88的专栏 125

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

基于pytest搭建接口自动化测试框架,提供源码

基于pytest测试框架实现场景接口自动化和单接口自动化,支持参数驱动单接口执行,支持多接口依赖参数,支持配置全局变量,支持日志记录,数据库,yaml操作,二次封装requests库,支持allure报告直接打开......

亚索的博客 5万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Pytest接口自动化测试框架搭建

2023最新自动化测试自学教程新手小白26天入门最详细教程,目前已有300多人通过学习这套教程入职大厂!!_哔哩哔哩_bilibili2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibili​​​​也方便你下次能够快速查找。如有不懂还要咨询下方小卡片,博主也希望和志同道合的测试人员一起学习进步在适当的年龄,选择适当的岗位,尽量去发挥好自己的优势。我的自动化测试开发之路,一路走来都离不每个阶段的计划,因为自己喜欢规划和总结,

GDYY3721的博客 1452

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Pytest接口自动化测试框架搭建的全过程

Pytest目前已经成为Python系自动化测试必学必备的一个框架,网上也有很多的文章讲述相关的知识。最近自己也抽时间梳理了一份pytest接口自动化测试框架,因此准备写文章记录一下,做到尽量简单通俗易懂,当然前提是基本的python基础已经掌握了。如果能够对新学习这个框架的同学起到一些帮助,那就更好了~

m0_70669463的博客 2480
上一篇: mac下生成文件目录树
下一篇: 接口测试工具-charles抓包笔记
sssammmm
博客等级 码龄9年 369粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值