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

自动化测试如何做?搭建接口自动化框架从0到1实战(超细)

目录:导读

    • 前言
    • 一、Python编程入门到精通
    • 二、接口自动化项目实战
    • 三、Web自动化项目实战
    • 四、App自动化项目实战
    • 五、一线大厂简历
    • 六、测试开发DevOps体系
    • 七、常用自动化测试工具
    • 八、JMeter性能测试
    • 九、总结(尾部小惊喜)


前言

传统软件测试行业是以手工测试为主,也就是所谓的点点点,加上国内软件公司不注重测试,受制于大环境影响等也就给了大众一种测试人员虽然身处互联网行业,却是毫无技术可言的工种。

话锋一转,到了如今,不得不说一声:大人,时代变了,最直观的表现莫过于招聘要求的提高,越来越要求测试人员拥有七十二变的能力。
而在这其中,自动化测试能力是现在手工测试迈向更高技术岗位的必经之路。

搭建接口测试框架

构建接口测试思维:
当前互联网产品最大的特点就是快,上线周期通常是以"天"甚至是以"小时"为单位,而传统软件产品的周期多以"月",甚至以"年"为单位。因此,如何在保证产品质量下,有效缩短测试回归时间成了重中之重。

两个突破口:
引入测试的并发执行,即从以往的串行执行测试用例,采用分布式的方法并行执行。

从测试策略上找到突破口,从传统软件产品的金字塔测试策略往菱形测试策略转变。以接口测试为主,GUI测试为辅,单元测试则根据公司实际情况进行。

四点建议:
以中间层的API测试为重点做全面的测试;
轻量级的GUI测试,只覆盖最核心直接影响主营业务流程的E2E场景;
最上层的GUI测试通常利用探索式测试思维,以人工测试的方式发现尽可能多的潜在问题;
单元测试只对那些相对稳定并且核心的服务和模块开展全面的单元测试,而应用层或者上层业务只会做少量的;

为何要搭建测试框架?

开发自己的框架更能结合自身工作中的痛点,难点来做一个针对性的解决,使其扩展性更高,后期也能接入CI/CD。

利用现有工具来进行接口测试,随着项目的规模变大,维护成本将会增大,不利于管控。

工具本身具有一定的局限性,如支持的协议比较单一。
不用纠结技术选型,根据自身的技术实力和技术功底来选择,而不要以开发工程师的技术栈来选择。

定义专属框架目录结构
test_case:存放测试用例
test_data:存放测试数据
report:存放测试报告
common:存放公共方法
lib:存放第三方库
config:存放环境配置信息
main:框架主入口
fixture:类似unittest中的setUp/tearDown的存在,但功能远比他们强大

构建框架流程

在框架构建过程中,由于篇符有限,本文只涉及其中部分环节。

1、在common公共模块、封装定义框架专属的http请求能力

# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author: pan-li
import requestsclass HttpRequests(object):def __init__(self, url):self.url = urlself.req = requests.session()# 自定义请求头,根据自身所在公司项目需求self.headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}# 封装get请求def get(self, url='', params='', data='', headers=None, cookies=None):response = self.req.get(url=url, params=params, data=data, headers=headers, cookies=cookies)return response# post请求def post(self, url='', params='', data='', headers=None, cookies=None):response = self.req.post(url=url, params=params, data=data, headers=headers, cookies=cookies)return response# put请求def put(self, url='', params='', data='', headers=None, cookies=None):response = self.req.put(url=url, params=params, data=data, headers=headers, cookies=cookies)return response# delete请求def delete(self, url='', params='', data='', headers=None, cookies=None):response = self.req.delete(url=url, params=params, data=data, headers=headers, cookies=cookies)return response

2、抽离URL生成url_conf.py在config文件中

import enumclass URLConf(enum.Enum):TEST_URL = 'http://10.12.7.20:8443/v2x-omp/api/'

3、编写接口测试用例在test_case文件中,第一版测试用例,安装pytest,pip install -U pytest

import os
import sys
import pytest
import json
from common.http_requests import *
from config.url_conf import URLConf
project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(project_root)class TestV2x:@classmethoddef setup_class(cls) -> None:cls.url = URLConf.TEST_URL.valuecls.http = HttpRequests(cls.url)def setup(self) -> None:self.headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}self.http = HttpRequests(self.url)def tearDown(self):pass@staticmethoddef get_token():headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}response = TestV2x.http.post(url=URLConf.TEST_URL.value, data='{"cmd":"signin","params":{"userName":"smarttest","password":"72be4b7f62832c516b85fb26de59df53"}}', headers=headers)token = response.json()['detail']['token']return tokendef test_001_queryArea(self):"""查询区域"""playload = {"cmd": "queryArea", "csrfToken": TestV2x.get_token(), "params": {"cityId": "320200"}}response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)resultNote = response.json().get('resultNote')assert resultNote, 'Success'def test_002_queryYearlyCheckCount(self):"""查询年检总数"""playload = {"cmd": "queryYearlyCheckCount", "Token": TestV2x.get_token(), "params": {}}response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)resultNote = response.json().get('resultNote')assert resultNote, 'SUCCESS'def test_003_queryTrafficEvent(self):"""查询交通事件"""playload = {"cmd": "queryTrafficEvent", "Token": TestV2x.get_token(), "params": {}}response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)resultNote = response.json().get('resultNote')assert resultNote, 'Success'def test_004_queryRsuCount(self):"""查询rsu总数"""playload = {"cmd": "queryRsuCount", "Token": TestV2x.get_token(), "params": {}}response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)resultNote = response.json().get('resultNote')assert resultNote, '查询路测设备数量成功!'def test_005_queryDeviceDetail(self):"""查询设备详情"""playload = {"cmd": "queryDeviceDetail", "params": {"deviceId": '0086860703231572'}, "Token": TestV2x.get_token()}response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)resultNote = response.json().get('resultNote')assert resultNote, '查询终端信息成功!'if __name__ == '__main__':pytest.main()

4、显然前面的测试用例也是流水账似的,还有很大的优化空间,现在就来一步一步进行。

5、优化一:利用feature特性优化前置和后置条件,fixture目录下的v2x_fixture.py文件

import pytest
from common.http_requests import HttpRequests
from config.url_conf import URLConf@pytest.fixture(scope='function', autouse=True)
def http():url = URLConf.TEST_URL.valuehttp = HttpRequests(url)return http@pytest.fixture(scope='function', autouse=True)
def get_token(http):headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}response = http.post(url=URLConf.TEST_URL.value,data='{"cmd":"signin","params":{"userName":"smarttest","password":"72be4b7f62832c516b85fb26de59df53"}}',headers=headers)token = response.json()['detail']['token']return token

上述在引入feature之后,简化了http请求的调用,重新定义http()来进行调用。之前每次接口的调用都要附带token参数,现在把获取token的方法提取出来,单独封装,加上feature的装饰,他会作用与每一个方法,用起来更加方便。此处的token是依赖登陆接口之后返回的值,可根据自身项目的需求封装。

6、优化二: 为测试用例添加数据驱动模式

# 以第五个测试用例单独为例
@pytest.mark.parametrize('deviceid', ['0086860703231572', '0086337601270714', '0086822412608154'])def test_005_queryDeviceDetail(self, http, get_token, deviceid):"""查询设备详情"""playload = {"cmd": "queryDeviceDetail", "params": {"deviceId": deviceid}, "Token": get_token}response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)resultNote = response.json()assert resultNote.get('resultNote'), '查询终端信息成功!'logger.info('查询终端信息成功!')
"""直接利用pytest.mark.parametrize()装饰器,第一个参数为参数名,后边数组为测试数据,用例当中同样添加形参deviceid"""

在 pytest 中,数据驱动是经由 pytest 自带的 pytest.mark.parametrize() 来实现的。 pytest.mark.parametrize 是 pytest 的内置装饰器,它允许你在 function 或者 class 上定义多组参 数和 fixture 来实现数据驱动。

@pytest.mark.parametrize() 装饰器接收两个参数:

第一个参数以字符串的形式存在,它代表能被被测试函数所能接受的参数,如果被测试函数有多个参数, 则以逗号分

第二个参数用于保存测试数据。如果只有一组数据,以列表的形式存在,如果有多组数据,以列表嵌套元 组的形式存在

7、优化三: 为测试用例添加标签,此时用到pytest.ini配置文件,放在项目任意位置都能生效,有以下作用:

为你的测试框架定制用例查找规则;
为你的测试框架注册标签名称;
指定查找用例起始目录;

[pytest]
python_files = test_*  *_test test*
python_classes = Test* test*
python_functions = test_* test*markers =smoke: marks tests as smoketest : marks tests as testlog : marks tests as log
# 使用时只需要在测试用例上使用@pytest.mark.smoke即可
# 执行时pytest -m [标记名]

8、优化四: 配置pytest.ini文件集成日志收集和实时控制台打印功能

[pytest]
log_cli = 1
log_cli_level = DEBUG
log_cli_date_format = %Y-%m-%d-%H-%M-%S
log_cli_format = %(asctime)s - %(filename)s - %(name)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s
log_file = ..\\report\\run.log
log_file_level = DEBUG
log_file_date_format = %Y-%m-%d-%H-%M-%S
log_file_format = %(asctime)s - %(filename)s -%(name)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s

关于字段的详解可以在终端输入pytest --help 查看

9、优化五: 定制测试框架测试报告,属于第三方应用放在lib目录中

这里我们使用目前市面上使用人数较多的一款开源测试报告框架Allure,它支持绝大多数测试框架

安装方法:

pip install -U allure-pytest

github上下载最新版本放到lib目录,并配置成系统环境变量(: https://github.com/allure-framework/allure2/releases)
使用方法:

执行pytest命令,并指定allure报告目录: pytest -v -s test_v2x_api_02.py --alluredir=./allure_reports

在线生成allure报告:allure serve allure_reports
生成本地allure报告:allure generate allure_reports

当然这只是在控制台直接命令执行,还不够方便,如果我们想在其他环境运行就又得配置环境变量,那么我们如何把它集成到我们的框架中呢

在共同方法中生成allure工具类,以便分辨运行环境是windows还是mac

import os
import sys
import platformpath = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'lib')
allure_path = os.path.join(path, 'allure', 'bin')
sys.path.append(allure_path)class Report():@propertydef allure(self):if platform.system() == 'Windows':cmd = os.path.join(allure_path, 'allure.bat')else:cmd = os.path.join(allure_path, 'allure')return cmd

10、在main模块中,添加执行调度策略

import os
import threading
import pytestfrom common.report import Reportproject_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
report_dir = os.path.join(project_root, 'report')
result_dir = os.path.join(report_dir, 'allure_result')
allure_report = os.path.join(report_dir, 'allure_report')
report = Report()def run_pytest():pytest.main(['-v', '-s', f'--alluredir={result_dir}'])def general_report():cmd = "{} generate {} -o {} --clean".format(report.allure, result_dir, allure_report)print(os.popen(cmd).read())if __name__ == '__main__':run = threading.Thread(target=run_pytest)gen = threading.Thread(target=general_report)run.start()  # 多线程先执行pytest命令生成测试报告run.join()gen.start()	# 报告生成后调用allure工具类生成本地报告

11、最后一版测试用例,整合前面的优化

import os
import sys
import json
from fixture.v2x_fixture import *
from config.url_conf import URLConf
project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(project_root)class TestV2x:@pytest.mark.smoke  # 标签的使用def test_001_queryArea(self, http, get_token):"""查询区域"""playload = {"cmd": "queryArea", "csrfToken": get_token, "params": {"cityId": "320200"}}response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)resultNote = response.json()assert resultNote.get('resultNote'), 'success'logger.info('查询区域成功')def test_002_queryYearlyCheckCount(self, http, get_token):"""查询年检总数"""playload = {"cmd": "queryYearlyCheckCount", "Token": get_token, "params": {}}response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)resultNote = response.json()assert resultNote.get('resultNote'), 'SUCCESS'logger.info('查询年检成功')def test_003_queryTrafficEvent(self, http,get_token):"""查询交通事件"""playload = {"cmd": "queryTrafficEvent", "Token": get_token, "params": {}}response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)resultNote = response.json()assert resultNote.get('resultNote'), 'Success'logger.info('查询交通事件成功')def test_004_queryRsuCount(self, http, get_token):"""查询rsu总数"""playload = {"cmd": "queryRsuCount", "Token": get_token, "params": {}}response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)resultNote = response.json()assert resultNote.get('resultNote'), '查询路测设备数量成功!'# text = response.text# print(text)logger.info('查询路侧设备成功')# 简单的数据驱动@pytest.mark.parametrize('deviceid', ['0086860703231572', '0086337601270714', '0086822412608154'])def test_005_queryDeviceDetail(self, http, get_token, deviceid):"""查询设备详情"""playload = {"cmd": "queryDeviceDetail", "params": {"deviceId": deviceid}, "Token": get_token}response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)resultNote = response.json()assert resultNote.get('resultNote'), '查询终端信息成功!'logger.info('查询终端信息成功!')if __name__ == '__main__':# 打印更详细的信息pytest.main(['-s', '-v', ])
下面是我整理的2023年最全的软件测试工程师学习知识架构体系图

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

只要心中燃烧着不灭的激情,勇敢面对困难与挑战,坚持不懈地追求目标,就能书写属于自己的辉煌篇章。相信自己的能力与潜力,努力奋斗,每一次努力都是一次进步,每一次拼搏都是一次成长。奋斗不息,成功必将绽放!

不论前路多么曲折艰难,只要心怀信念与勇气,坚持不懈地奋斗,才能创造属于自己的辉煌。相信自己的才华与潜力,努力拼搏,每一次奋斗都是一次进步,每一次挑战都是一次成长。

勇往直前,不畏艰难险阻,只有坚持不懈的奋斗,才能追逐梦想的光芒。相信自己的能力与潜力,不断超越自我,每一次努力都是一次成长,每一次拼搏都是一次进步。

相关文章:

自动化测试如何做?搭建接口自动化框架从0到1实战(超细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 传统软件测试行业…...

安装Python之后 安装库报错 There was an error checking the latest version of pip.

报错代码 & 图片如下 Looking in indexes: https://pypi.tuna.tsicmdnghua.edu.cn/simple WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by NewConnectionError(<pip._vendor.urllib3.connection.HT…...

"科技与狠活"企业级无代码开发MES系统,一周实现数字化

随着科技的不断发展&#xff0c;企业级无代码开发平台成为了一种新型的解决方案&#xff0c;能够有效降低软件开发门槛&#xff0c;提升开发效率。在制造业领域&#xff0c;MES系统&#xff08;Manufacturing Execution System&#xff09;作为一种关键的生产管理工具&#xff…...

超实用的品牌软文推广方案分享,纯干货

品牌软文推广对于企业来说是一项关键且重要的战略&#xff0c;如何通过软文推广提高品牌的知名度、美誉度和影响力&#xff0c;成为了许多企业关注的问题。本文伯乐网络传媒将从多个角度深度探讨品牌软文推广方案&#xff0c;为企业提供一些有价值的参考。 一、确定品牌软文推广…...

网络安全(黑客)8大工具

1.Nmap 它是网络管理员 必用的软件之一&#xff0c;以及用以评估网络系统安全。正如大多数被用于网络安全的工具&#xff0c;nmap 也是不少黑客及骇客&#xff08;又称脚本小子 &#xff09;爱用的工具 。系统管理员可以利用nmap来探测工作环境中未经批准使用的服务器&#xff…...

重启Linux服务器 Oracle 数据库步骤

在一次重启数据库的时候&#xff0c;没有正确按照步骤重启数据库&#xff0c;导致服务器重启。 正确步骤及详解&#xff1a; (1) su - oracle 打开Xshell&#xff0c;连接到数据库所在的linux机器。若用户为root&#xff0c;请输入命令“su - oracle”并回车&#xff0c;若要…...

kaggle新赛:Bengali.AI 语音识别大赛赛题解析

赛题名称&#xff1a;Bengali.AI Speech Recognition 赛题链接&#xff1a;https://www.kaggle.com/competitions/bengaliai-speech 赛题背景 竞赛主办方 Bengali.AI 致力于加速孟加拉语&#xff08;当地称为孟加拉语&#xff09;的语言技术研究。Bengali.AI 通过社区驱动的…...

解放Linux内存:释放缓存(linux释放缓存)

随着软件越来越复杂&#xff0c;内存变得越来越宝贵。尤其是在Linux系统上&#xff0c;内存管理策略十分重要。它不仅可以帮助系统保持高效运行&#xff0c;而且也能够让程序有更多的空间来运行&#xff0c;避免系统出现假死和其他性能问题。 在Linux系统中&#xff0c;释放缓…...

前端跨域解决方案

跨域 同源指的是两个URL的协议、域名、端口号一致&#xff0c;反之则是跨域。 出现跨域的根本原因&#xff1a;浏览器的同源策略不允许非同源的URL之间进行资源的交互。 同源策略限制为以下几种行为&#xff1a; Cookie、LocalStorage和IndexDB无法获取。DOM和JS对象无法获得…...

脚手架(vue-cli)的安装详细教程

首先要下载node.js 下载 | Node.js 中文网 (nodejs.cn)https://nodejs.cn/download/ 大家根据自己的系统来选择哪个&#xff0c;我是Windows系统&#xff0c;所以选择红色箭头所指的安装包去安装&#xff01;&#xff01;&#xff01; 接下来双击安装&#xff01;&#xff01;…...

yolov5 onnx模型 转为 rknn模型

1、转换为rknn模型环境搭建 onnx模型需要转换为rknn模型才能在rv1126开发板上运行&#xff0c;所以需要先搭建转换环境 模型转换工具 模型转换相关文件下载&#xff1a; 网盘下载链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;teuc 将其移动到虚拟机中&#xf…...

Mybatis-Flex

一、Mybatis-Flex是什么&#xff1f; Mybatis-Flex 是一个优雅的 Mybatis 增强框架&#xff0c;它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 Mybaits-Flex 链接任何数据库&#xff0c;其内置的 QueryWrapper^亮点 帮助我们极大的减少了 SQL 编写的工作的同时…...

C++ | 红黑树以及map与set的封装

目录 前言 一、红黑树 1、红黑树的基本概念 2、红黑树相关特性 3、红黑树结点的定义 4、红黑树的查找 5、红黑树的插入 6、二叉树的拷贝构造与析构 7、红黑树的检测 8、红黑树总结 二、map与set的封装 1、红黑树的结点 2、红黑树迭代器 3、set的封装 4、map的封…...

逻辑斯特回归

*分类是离散的&#xff0c;回归是连续的 下载数据集 trainTrue&#xff1a;下载训练集 逻辑斯蒂函数保证输出值在0-1之间 能够把实数值映射到0-1之间 导函数类似正态分布 其他饱和函数sigmoid functions 循环神经网络经常使用tanh函数 与线性回归区别 塞戈马无参数&#x…...

OpenCV 算法解析

opencv大坑之BGR opencv对于读进来的图片的通道排列是BGR&#xff0c;而不是主流的RGB&#xff01;谨记&#xff01; #opencv读入的矩阵是BGR&#xff0c;如果想转为RGB&#xff0c;可以这么转 img4 cv2.imread(1.jpg) img4 cv2.cvtColor(img4,cv2.COLOR_BGR2RGB) OpenCV 常见…...

springboot创建并配置环境(一) - 创建环境

文章目录 一、介绍二、启动环境Environment的分析三、进入源码四、创建环境1. 如何确定应用类型2. 测试 一、介绍 在springboot的启动流程中&#xff0c;启动环境Environment是可以说是除了应用上下文ApplicationContext之外最重要的一个组件了&#xff0c;而且启动环境为应用…...

2023JAVA 架构师面试 130 题含答案:JVM+spring+ 分布式 + 并发编程》...

此文包含 Java 面试的各个方面&#xff0c;史上最全&#xff0c;苦心整理最全 Java 面试题目整理包括基JVM算法数据库优化算法数据结构分布式并发编程缓存等&#xff0c;使用层面广&#xff0c;知识量大&#xff0c;涉及你的知识盲点。要想在面试者中出类拔萃就要比人付出更多的…...

layui手机端上传文件时返回404 Not Found的解决方案(client_body_temp权限设置)

关于 1.client_body_temp的作用 client_body_temp是一个指令指定保存客户端请求体临时文件的目录路径&#xff0c;以及是否进行缓存的配置指令。 在Web服务器中&#xff0c;当客户端向服务器发送请求时&#xff0c;请求体中包含了请求的主体部分&#xff0c;比如表单数据、上…...

网络编程知识

网络编程知识 一.网络七层模型 OSI模型&#xff1a; OSI 模型(Open System Interconnection model)是一个由国际标准化组织&#x10fc01;提出的概念模型&#xff0c;试图提供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。它将计算机网络体系结构划分为七层…...

线性神经网路——线性回归随笔【深度学习】【PyTorch】【d2l】

文章目录 3.1、线性回归3.1.1、PyTorch 从零实现线性回归3.1.2、简单实现线性回归 3.1、线性回归 线性回归是显式解&#xff0c;深度学习中绝大多数遇到的都是隐式解。 3.1.1、PyTorch 从零实现线性回归 %matplotlib inline import random import torch #d2l库中的torch模块&a…...

js实现多种按钮

你可以使用JavaScript来实现多种类型的按钮&#xff0c;以下是几个常见的示例&#xff1a; 普通按钮&#xff08;Normal Button&#xff09;&#xff1a; <button>Click me</button> 带图标的按钮&#xff08;Button with Icon&#xff09;&#xff1a; <bu…...

getopt函数(未更新完)

2023年7月28日&#xff0c;周五上午 这是我目前碰到过的比较复杂的函数之一&#xff0c; 为了彻底弄懂这个函数&#xff0c;我花了几个小时。 为了更好的说明这个函数&#xff0c;之后我可能会录制讲解视频并上传到B站&#xff0c; 如果我上传到B站&#xff0c;我会在文章添…...

SpringCloud学习路线(9)——服务异步通讯RabbitMQ

一、初见MQ &#xff08;一&#xff09;什么是MQ&#xff1f; MQ&#xff08;MessageQueue&#xff09;&#xff0c;意思是消息队列&#xff0c;也就是事件驱动架构中的Broker。 &#xff08;二&#xff09;同步调用 1、概念&#xff1a; 同步调用是指&#xff0c;某一服务…...

postcss-pxtorem适配插件动态配置rootValue(根据文件路径名称,动态改变vue.config里配置的值)

项目背景&#xff1a;一个项目里有两个分辨率的设计稿(1920和2400)&#xff0c;不能拆开来打包 参考&#xff1a; 是参考vant插件&#xff1a;移动端Vant组件库rem适配下大小异常的解决方案&#xff1a;https://github.com/youzan/vant/issues/1181 说明&#xff1a; 因为vue.c…...

代码随想录算法训练营第二十三天 | 额外题目系列

额外题目 1365. 有多少小于当前数字的数字借着本题&#xff0c;学习一下各种排序未看解答自己编写的青春版重点代码随想录的代码我的代码(当天晚上理解后自己编写) 941.有效的山脉数组未看解答自己编写的青春版重点代码随想录的代码我的代码(当天晚上理解后自己编写) 1207. 独一…...

UiAutomator

运行Espresso和UI Automator测试时要使用模拟器。国内手机的ROM大多进行过修改&#xff0c;可能加入很多限制&#xff0c;导致测试无法正常运行。 Espresso只支持一个活动内部交互行为的测试。跨越多个活动、多个应用的场景需要使用UI Automator。使用Espresso和UI Automator的…...

stm32标准库开发常用函数的使用和代码说明

文章目录 GPIO&#xff08;General Purpose Input/Output&#xff09;NVIC&#xff08;Nested Vectored Interrupt Controller&#xff09;DMA&#xff08;Direct Memory Access&#xff09;USART&#xff08;Universal Synchronous/Asynchronous Receiver/Transmitter&#xf…...

有关合泰BA45F5260中断的思考

最近看前辈写的代码&#xff0c;发现这样一段代码&#xff1a; #ifdef SUPPORT_RF_NET_FUNCTION if(UART_INT_is_L()) { TmrInsertTimer(eTmrHdlUartRxDelay,TMR_PERIOD(2000),NULL); break; } #endif 其中UART_INT_is_L&am…...

Numpy-算数函数与数学函数

⛳算数函数 如果参与运算的两个对象都是ndarray&#xff0c;并且形状相同&#xff0c;那么会对位彼此之间进 第 30 页 行&#xff08; - * /&#xff09;运算。NumPy 算术函数包含简单的加减乘除: add()&#xff0c;subtract()&#xff0c;multiply() 和divide()。 &#x1f…...

Nginx在springboot中起到的作用

面试时这样回答&#xff1a; 在Spring Boot项目中使用Nginx可以有以下用途&#xff1a; 1. 反向代理&#xff1a;Nginx可以作为反向代理服务器&#xff0c;将外部请求转发到后端的Spring Boot应用&#xff0c;并可以实现负载均衡、高可用、缓存等功能&#xff0c;提高系统的性…...