接口自动化测试_L1

news2025/6/23 15:29:57

目录:

  1. 接口自动化测试框架介绍
    1. 接口测试场景
    2. 自动化测试场景
    3. 接口测试在分层测试中的位置
    4. 接口自动化测试与 Web/App 自动化测试对比
    5. 接口自动化测试与 Web/App 自动化测试对比
    6. 接口测试工具类型
    7. 为什么推荐 Requests
    8. Requests 优势
    9. Requests 环境准备
  2. 接口请求方法
  3. 接口请求参数
  4. 接口请求头
  5. 接口请求体-json
  6. 接口响应断言
  7. json响应体断言
  8. 宠物商店接口自动化测试实战

1.接口自动化测试框架介绍

接口测试场景

自动化测试场景 

接口测试在分层测试中的位置 

接口自动化测试与 Web/App 自动化测试对比 

接口自动化测试与 Web/App 自动化测试对比 

看起来接口自动化测试什么都比 Web/App 自动化测试要好,为什么还要做 Web/App 自动化测试?

  • 接口关注数据无法触达用户体验。
接口测试工具类型
测试类型工具价值
接口抓包Charles、Postman接口抓包工具,可以抓取 App 的数据包
接口测试Postman接口调试工具,接口手工测试工具,学习成本低,直接安装即可使用
接口自动化测试Requests、RestAssured用于接口自动化测试的 Java、Python 第三方库,需要与对应编程语言结合使用
性能测试JMeter性能测试工具
为什么推荐 Requests
  • 是由 Python 实现的 API 测试框架。
  • 支持发起 POST, GET, PUT, DELETE 等请求。
  • 可以用来验证和校对响应信息。
Requests 优势 
  • 功能全面:HTTP/HTTPS 支持全面。
  • 使用简单:简单易用,不用关心底层细节。
  • 定制性高:结合测试框架完成二次封装,比如 HttpRunner。
Requests 环境准备 
  • 安装命令:pip install requests

2.接口请求方法

常见 HTTP 请求方法构造
方法说明
requests.request()构造一个请求,支撑以下各方法的基础方法。
requests.get()构造 HTTP 协议中的 GET 请求。
requests.post()构造 HTTP 协议中的 POST 请求。
requests.put()构造 HTTP 协议中的 PUT 请求。
requests.delete()构造 HTTP 协议中的 DELETE 请求。
底层设计

HTTP 协议知识回顾 
  • URL 结构
  • HTTP 请求
  • HTTP 响应
构造 GET 请求
  • requests.get(url, params=None, **kwargs)
    • url: 接口 url。
    • params:拼接在 url 中的请求参数。
    • **kwargs:更多底层支持的参数。
import requests


def test_get():
    # 定义接口的 url 和拼接在 url 中的请求参数
    url = "https://httpbin.ceshiren.com/get"
    # 发出 GET 请求,r 接收接口响应
    r = requests.get(url, verify=False)
    # 打印接口响应
    print(r.json())
构造 POST 请求 
  • requests.post(url, data=None, json=None, **kwargs)
    • url: 接口 url。
    • data:表单格式请求体。
    • json:JSON 格式请求体。
    • **kwargs:更多底层支持的参数。
def test_post():
    # 定义接口的 url
    url = "https://httpbin.ceshiren.com/post"
    # 发出 POST 请求,r 接收接口响应
    response = requests.post(url, verify=False)
    # 打印接口响应
    print(response.text)
构造 PUT 请求
  • requests.put(url, data=None, **kwargs)
    • url: 接口 url。
    • data:表单格式请求体。
    • **kwargs:更多底层支持的参数。
def test_put():
    # 定义接口的 url
    url = "https://httpbin.ceshiren.com/put"
    # 发出 POST 请求,r 接收接口响应
    r = requests.put(url, verify=False)
    # 打印接口响应
    print(r)
 构造 DELETE 请求
  • requests.delete(url, **kwargs)
    • url: 接口 url。
    • **kwargs:更多底层支持的参数。
def test_delete():
    # 定义接口的 url 和表单格式请求体
    url = "https://httpbin.ceshiren.com/delete"
    # 发出 POST 请求,r 接收接口响应
    r = requests.delete(url, verify=False)
    # 打印接口响应
    print(r)
构造请求方法
  • requests.request(method, url, **kwargs)
    • method: 请求方法。
      • GETOPTIONSHEADPOSTPUTPATCHDELETE
    • url: 接口 url。
    • **kwargs:更多底层支持的参数。
  1. GET:GET是最常见的方法,通常用于请求服务器发送某些资源。浏览器大部分时间都在使用GET方法,比如当你在网址栏输入一个URL,或者点击一个链接时。GET请求会将请求参数附加在URL后面,以'?'符号分隔。这些参数会被浏览器发送到服务器,但是浏览器不会保存这些参数,也就是说,GET请求不应该是用来发送敏感数据的,因为这些数据可能会被第三方获取。
  2. OPTIONS:OPTIONS方法用于获取目标资源支持的通信选项。它可以用来检查服务器的性能,或者查看可以使用哪些HTTP方法来请求一个特定的URL。
  3. HEAD:HEAD方法和GET方法类似,但是服务器在响应中只返回HTTP头部,而不返回实际的数据。这可以用来检查链接的有效性,或者获取有关资源的元数据,例如Last-Modified头,ETag头等。
  4. POST:POST方法用于向服务器发送数据。它通常用于提交表单,上传文件等。POST请求会将请求主体发送到服务器,这个主体可以包含表单数据,文件内容等。服务器可以根据这些数据执行一些动作,例如创建新的资源。
  5. PUT:PUT方法用于更新服务器上的资源。它与POST方法的主要区别是,PUT请求通常知道它正在更新的资源的完整URL,而POST请求通常不知道。因此,PUT请求通常用于更新已经存在的资源,而POST请求用于创建新的资源。
  6. PATCH:PATCH方法是PUT方法的简化版本。与PUT相比,PATCH请求通常只包含资源的部分更新信息,而不是完整的信息。因此,PATCH方法通常用于对资源的部分进行修改。
  7. DELETE:DELETE方法是HTTP方法中最简单的一个。它用于从服务器删除资源。当你点击一个删除链接或者执行相应的JavaScript代码时,你的浏览器就会向服务器发送一个DELETE请求。
def request(method, url, **kwargs):
    """Constructs and sends a :class:`Request <Request>`.

    :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
        in the query string for the :class:`Request`.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
        object to send in the body of the :class:`Request`.
    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
        to add for the file.
    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
    :param timeout: (optional) How many seconds to wait for the server to send data
        before giving up, as a float, or a :ref:`(connect timeout, read
        timeout) <timeouts>` tuple.
    :type timeout: float or tuple
    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
    :type allow_redirects: bool
    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
    :param verify: (optional) Either a boolean, in which case it controls whether we verify
            the server's TLS certificate, or a string, in which case it must be a path
            to a CA bundle to use. Defaults to ``True``.
    :param stream: (optional) if ``False``, the response content will be immediately downloaded.
    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
底层参数说明
参数应用场景
method请求方法
url请求 URL
params请求中携带 URL 参数
data请求中携带请求体(默认为表单请求)
json请求中携带 json 格式的请求体
headers请求中携带头信息
cookies请求中携带 cookies
files请求中携带文件格式的请求体
auth请求中携带认证信息
timeout设置请求超时时间
allow_redirects请求是否允许重定向
proxies设置请求代理
verify请求是否要认证
cert请求中携带 ssl 证书

 

3.接口请求参数

请求参数简介
  • 接口请求中携带的,会在路径之后使用?代表客户端向服务端传递的参数。
  • 使用 key=value 形式拼接在 URL 中。
  • 如果有多个,则使用&分隔
  • 案例: https://ceshiren.com/search?expanded=true&q=requests
 携带请求参数的方式
  • 常用两种方式:
    • 直接在 URL 中拼接:?username=LiMing&id=666
    • 通过 params 参数传递:requests.get(url, params)
 携带请求参数的 GET 请求
def test_get_by_params():
    url = "https://httpbin.ceshiren.com/get"
    params = {"get_key": "get_value"}
    r = requests.get(url, params=params, verify=False)
    print(r.json())


def test_get_by_url():
    url = "https://httpbin.ceshiren.com/get?get_key=get_value"
    r = requests.get(url, verify=False)
    print(r.json())
携带请求参数的 POST 请求 
def test_post_by_params():
    url = "https://httpbin.ceshiren.com/post"
    params = {"post_key": "post_value"}
    r = requests.post(url, params=params,verify=False)
    print(r.json())

4.接口请求头

请求头信息的使用场景
  • 身份认证
  • 指定数据类型

请求头信息 
  • HTTP 请求头是在 HTTP 请求消息中包含的元数据信息,用于描述请求或响应的一些属性和特征。
  • 实际工作过程中具体要关注的头信息字段需要和研发沟通。
  • 常见的头信息(右侧表格):
内容含义
Authorization表示客户端请求的身份验证信息
Cookie表示客户端的状态信息,通常用于身份验证和会话管理
Content-Type表示请求消息体的 MIME 类型
User-Agent发送请求的客户端软件信息
构造头信息
  • 使用 headers 参数传入。
  • 通常使用字典格式。
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)

 代码示例:

import requests


def test_header():
    url = "https://httpbin.ceshiren.com/get"
    headers = {"name": "LiMing", "User-Agent": "apple", "Content-type": "application/json"}
    r = requests.get(url, verify=False, headers=headers)
    print(r.json())

5.接口请求体-json

接口请求体简介 
  • 进行HTTP请求时,发送给服务器的数据。
  • 数据格式类型可以是JSON、XML、文本、图像等格式。
  • 请求体的格式和内容取决于服务器端API的设计和开发人员的要求。

常用接口请求体
类型介绍Content-type
JSON(JavaScript Object Notation)轻量级的数据交换格式,最常见的一种类型。application/json
表单数据(Form Data)以键值对的形式提交数据,例如通过 HTML 表单提交数据。application/x-www-form-urlencoded
XML(eXtensible Markup Language)常用的标记语言,通常用于传递配置文件等数据。application/xml
text/xml
文件(File)可以通过请求体上传文件数据,例如上传图片、视频等文件。上传文件的 MIME 类型,例如 image/jpeg
multipart/form-data
纯文本(Text)纯文本数据,例如发送邮件、发送短信等场景text/plain
其他格式二进制数据、protobuf 等格式
JSON 简介
  • 是 JavaScript Object Notation 的缩写。
  • 是一种轻量级的数据交换格式。
  • 是理想的接口数据交换语言。
  • Content-Type 为 application/json。

JSON 格式请求体示例 
  1. 进入登录页面。
  2. 打开开发者工具。
  3. 输入用户名密码,点击登录。
  4. https://litemall.hogwarts.ceshiren.com/#/login

 构造 JSON 格式请求体
  • 定义为字典格式。
  • 使用 json 参数传入。
import requests


def test_request_body():
    url = "https://httpbin.ceshiren.com/post"
    request_body = {"name": "LiMing", "teacher": 'Jenny'}
    r = requests.post(url, verify=False, json=request_body)
    print(r.json())

6.接口响应断言

 接口断言使用场景
  • 问题:
    1. 如何确保请求可以发送成功。
    2. 如何保证符合业务需求。
  • 解决方案:
    • 通过获取响应信息,验证接口请求是否成功,是否符合业务需求。
Requests 中的响应结果对象 
import requests


def test_assert():
    url = "https://httpbin.ceshiren.com/get"
    r = requests.get(url, verify=False)
    print(r)
响应结果类型 
属性含义
r响应 Response 对象(可以使用任意的变量名)
r.status_codeHTTP 响应状态码
r.headers返回一个字典,包含响应头的所有信息。
r.text返回响应的内容,是一个字符串。
r.url编码之后的请求的 url
r.content返回响应的内容,是一个字节流。
r.raw响应的原始内容
r.json()如果响应的内容是 JSON 格式,可以使用该方法将其解析成 Python 对象。

代码示例:

import requests


def test_assert():
    url = "https://httpbin.ceshiren.com/get"
    r = requests.get(url, verify=False)
    print("------------------------------------------")
    print(r.status_code)
    print("------------------------------------------")
    print(r.headers)
    print("------------------------------------------")
    print(r.text)
    print("------------------------------------------")
    print(r.url)
    print("------------------------------------------")
    print(r.content)
    print("------------------------------------------")
    print(r.raw)
    print("------------------------------------------")
    print(r.json())
响应状态码断言 
  • 基础断言:
    • r.status_code

 代码示例:

def test_assert_base():
    url = "https://httpbin.ceshiren.com/get"
    r = requests.get(url, verify=False)
    assert r.status_code == 200

7.json响应体断言

什么是 JSON 响应体?
  • JSON格式的响应体指的是HTTP响应中的消息体(message body),它是以JSON格式编码的数据。
{
  "name": "John",
  "age": 30,
  "city": "New York"
}
断言 JSON 格式响应体使用场景 
  • 验证API接口的返回结果是否符合预期。
    • 业务场景上是否符合预期。
    • 格式是否符合文档规范。 
断言 JSON 格式响应体 
  • r.json():返回 python 字典。
import requests

def test_res_json():
    r = requests.get("https://httpbin.ceshiren.com/get")
    assert r.status_code == 200
    assert r.json()["url"] == "https://httpbin.ceshiren.com/get"

代码示例:

import requests


def test_resonse_body_json():
    url = "https://httpbin.ceshiren.com/get"
    r = requests.get(url, verify=False)
    print(r.json())
    print(r.json()["headers"])
    print(r.json()["headers"]["Host"])

    assert r.status_code == 200
    assert r.json()["url"] == "https://httpbin.ceshiren.com/get"


def test_resonse_body_json_fail():
    url = "https://www.baidu.com"
    r = requests.get(url)
    # 如果响应体是非 json 的场景,那么就不要使用 r.json() 的方式,否则则会# raise RequestsJSONDecodeError
    # print(r.json())
    # 可以使用r.text
    print(r.text)
    assert r.status_code == 200
若碰到复杂断言应该如何处理? 
  • 多层嵌套的数据提取与断言: JSONPath
  • 整体结构响应断言: JSONSchema
  • 自行编写解析算法

 

8.宠物商店接口自动化测试实战

被测产品
  • PetStore 宠物商城:
    • 一个在线的小型的商城。
    • 主要提供了增删查改等操作接口。
    • 结合 Swagger 实现了接口的管理。

 

需求说明
  • 完成宠物商城宠物查询功能接口自动化测试。
    • 编写自动化测试脚本。
    • 完成断言。

 

相关知识点
形式章节描述
知识点接口请求方法http 接口请求方法构造
知识点接口请求参数http 接口请求参数构造
知识点接口请求体-jsonhttp 接口请求体为 json 格式
知识点接口响应断言http 接口响应状态码断言

实战思路

宠物商店需求分析
  • 被测产品:宠物商店系统 - 查询宠物信息
  • 宠物商店接口文档:https://petstore.swagger.io/
接口测试用例设计
  • 宠物查询单接口用例

 

编写接口自动化测试脚本思路
  1. 查询宠物信息。

 

编写自动化测试脚本 

test_petstore.py

import requests

from interface_automation_testing.接口自动化测试_L1.宠物商店接口自动化测试实战.utils.log_util import logger


class TestPetstorePetsearch:
    def setup_class(self):
        # 定义接口请求 URL
        self.base_url = "https://petstore.swagger.io/v2/pet"
        self.search_url = self.base_url + "/findByStatus"

    # "【冒烟】传入available状态可以正确获取该状态下的宠物信息"
    def test_search_pet1(self):
        # 查询接口请求参数
        params = {
            "status": "available"
        }
        # 发出查询请求
        r = requests.get(self.search_url, params=params, verify=False)

        logger.info('【冒烟】传入available状态可以正确获取该状态下的宠物信息')
        # 状态断言
        assert r.status_code == 200
        # 业务断言
        assert r.json() != []

        assert "id" in r.json()[0]

项目结构:

 

脚本优化 - 添加日志
  • 新建日志配置。
  • 在用例中使用配置好的日志实例。
import logging
import os

from logging.handlers import RotatingFileHandler

# 绑定绑定句柄到logger对象
logger = logging.getLogger(__name__)

# 获取当前工具文件所在的路径
root_path = os.path.dirname(os.path.abspath(__file__))

# 拼接当前要输出日志的路径
root_len = len(root_path)
strs = root_path[0:root_len-6]
log_dir_path = os.sep.join([strs,f'datas\logs'])

if not os.path.isdir(log_dir_path):
    os.mkdir(log_dir_path)

# 创建日志记录器,指明日志保存路径,每个日志的大小,保存日志的上限
file_log_handler = RotatingFileHandler(os.sep.join([log_dir_path, 'log.log']),
                                       maxBytes=1024 * 1024, backupCount=10,
                                       encoding="utf-8")

# 设置日志的格式
date_string = '%Y-%m-%d %H:%M:%S'
formatter = logging.Formatter(
    '[%(asctime)s] [%(levelname)s] [%(filename)s]/[line: %(lineno)d]/[%(funcName)s] %(message)s ',
    date_string)

# 日志输出到控制台的句柄
stream_handler = logging.StreamHandler()

# 将日志记录器指定日志的格式
file_log_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)

# 为全局的日志工具对象添加日志记录器
# 绑定绑定句柄到logger对象
logger.addHandler(stream_handler)
logger.addHandler(file_log_handler)

# 设置日志输出级别
logger.setLevel(level=logging.INFO)


def prit_path():
    print(root_path)
    print(log_dir_path)

prit_path()
脚本优化 - 参数化
  • 使用 pytest parametrize 装饰器实现宠物状态的参数化。

test_petstore_parameterization.py

import pytest
import requests

from interface_automation_testing.接口自动化测试_L1.宠物商店接口自动化测试实战.utils.log_util import logger


class TestPetstorePetsearch:
    def setup_class(self):
        # 定义接口请求 URL
        self.base_url = "https://petstore.swagger.io/v2/pet"
        self.search_url = self.base_url + "/findByStatus"

    # "【冒烟】传入available状态可以正确获取该状态下的宠物信息"
    # "【冒烟】传入pending状态可以正确获取该状态下的宠物信息"
    # "【冒烟】传入sold状态可以正确获取该状态下的宠物信息"
    @pytest.mark.parametrize(
        "status",
        ['available', 'pending', 'sold'],
        ids=["available_pets", "pending_pets", "sold_pets"]
    )
    def test_search_pet1(self, status):
        # 查询接口请求参数
        params = {
            "status": status
        }
        # 发出查询请求
        r = requests.get(self.search_url, params=params, verify=False)

        logger.info(f'【冒烟】传入{status}状态可以正确获取该状态下的宠物信息')
        # 状态断言
        assert r.status_code == 200
        # 业务断言
        assert r.json() != []

        assert "id" in r.json()[0]

    # "【异常】传入非指定状态字符串﹐响应为空"
    # "【异常】传入非指定状态数字,响应为空"
    # "【异常】传入空字符串,响应为空""
    @pytest.mark.parametrize(
        "status",
        ['petstatus', '123456', ''],
        ids=["petstatus_pets", "123456_pets", "null_pets"]
    )
    def test_search_pet2(self, status):
        # 查询接口请求参数
        params = {
            "status": status
        }
        # 发出查询请求
        r = requests.get(self.search_url, params=params, verify=False)

        logger.info(f'【异常】传入{status}字符串﹐响应为空')
        # 状态断言
        assert r.status_code == 200
        # 业务断言
        assert r.json() == []

    # 【异常】不传入status,响应为空"
    def test_search_pet3(self):
        # 查询接口请求参数
        # 发出查询请求
        r = requests.get(self.search_url, verify=False)

        logger.info(f'【异常】不传入status,响应为空')
        # 状态断言
        assert r.status_code == 200
        # 业务断言
        assert r.json() == []

    # "【异常】传入非status 的参数,响应为空"
    def test_search_pet4(self):
        # 查询接口请求参数
        params = {
            "key": "available"
        }
        # 发出查询请求
        r = requests.get(self.search_url, params=params, verify=False)

        logger.info(f'【异常】传入非status 的参数,响应为空')
        # 状态断言
        assert r.status_code == 200
        # 业务断言
        assert r.json() == []
 生成测试报告
  • 安装 allure 相关依赖。
# 生成报告信息
pytest --alluredir=./report
# 生成报告在线服务,查看报告
allure serve ./report/
pytest -vs .\test_petstore_parameterization.py --alluredir=./datas/report --clean-alluredir

 运行结果:

 

allure serve .\report\

 运行结果:

 

 总结
  • 通过 Swagger 文档获取接口信息。
  • 使用 Requests 发出携带请求参数的 GET 请求。
  • 断言响应符合是否符合预期。
  • 添加 Log 日志。
  • 使用参数化方式实现一条用例可执行多个测试数据。
  • 生成 Allure 测试报告。

项目地址: template: 用来存放开发模版 - Gitee.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1086266.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web自动化测试进阶:网页中难点之等待机制 —— 强制等待,隐式等待

为什么要添加等待 避免页面未渲染完成后操作&#xff0c;导致的报错 经常会遇到报错&#xff1a;selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":&q…

[LitCTF 2023]导弹迷踪

这道题相较于其他的分数类型的js题有一点不一样&#xff0c;他不是像常规的有用bp多次抓包修改最后得分来获取flag的。 本题将flag藏到了他的前端文件中本身没有任何难度&#xff0c;只是为了记录一种新的做法 按照我们平常做js的思路就是先随便玩一下然后bp抓包看得分或者抓包…

如何提升设备投资回报率:预测性维护在制造业的应用

在当今竞争激烈的制造业市场中&#xff0c;企业需要不断寻求提高生产效率和降低成本的方法。作为重要资产之一&#xff0c;设备投资回报率成为制造企业关注的焦点。然而&#xff0c;许多企业在设备维护和管理方面面临着一些挑战&#xff0c;这可能导致设备投资回报率的下降。为…

【重拾C语言】八、表单数据组织——结构体(类型、类型别名、直接/间接访问;典例:复数、成绩单)

目录 前言 八、结构体 8.1 结构体类型 8.2 结构体类型名 8.2.1 typedef关键字 8.2.1 结构体类型别名 8.3 结构体变量 8.3.1 使用结构体类型引用 8.3.2 使用结构体类型定义 8.3.3 使用typedef定义的结构体类型别名 8.4 访问结构体变量 8.4.1 直接成员选择表达式 8.…

如何才能找到合适的法语交传翻译服务呢?

法语交传&#xff0c;无需其他语言介入&#xff0c;直接在口译者与听众之间进行即时翻译&#xff0c;这是一种高级口译服务。法语交传在国际会议、商务谈判、法律诉讼等各种场合中发挥着至关重要的作用。那么&#xff0c;如何才能找到合适的法语交传翻译服务呢&#xff1f;法语…

2023年全球新能源动力电池盒市场发展规模及趋势分析:动力电池盒向底盘一体化方向发展[图]

中国新能源汽车市场维持高速增长的态势&#xff0c;电池盒作为在新能源汽车中用以承载、固定、保护以及集成电池组的机构部件&#xff0c;是构成新能源汽车完整动力系统的关键组成部分。2022年&#xff0c;全球新能源动力电池盒市场规模约430亿元&#xff0c;同比增长65.38%&am…

迅镭激光切割机在钣金加工行业中的应用

钣金是一种针对金属薄板(厚度通常在6mm以下)的归纳冷加工工艺&#xff0c;包括剪切、冲切、切割、复合、弯曲、焊接、铆接、拼接和成型等步骤&#xff0c;其显著特征是所有零件的厚度保持一致。 电器控制箱和机器外壳等通常都是钣金件&#xff0c;钣金加工能力的需求持续攀升&a…

JavaFx学习问题2--音频、视频播放失败情况

文章目录 一、路径注意事项&#xff1a;① 用相对路径的时候别忘了前面的斜杠② uri问题 二、播放不了的问题① 获取的媒体文件路径本身就是不对的② 必须是uri 额外收获: 一、路径注意事项&#xff1a; ① 用相对路径的时候别忘了前面的斜杠 并不是什么大问题&#xff0c;只是…

JavaScript-Vue基础语法-创建-组件-路由

文章目录 1.创建vue项目1.1.自定义创建项目1.2.项目结构解析1.3.主要文件1.4.其它 2.项目运行3.Vue组件概念3.1.组件基础概念3.2.单文件组件三要素3.3.组件注册3.4.组件通信 4.Vue路由概念4.1.简单使用4.2.路由参数4.3.嵌套路由4.4.路由导航4.5.代码导航4.6.路由守卫 5.总结 HT…

【Java 进阶篇】JavaScript `typeof` 操作符详解

JavaScript是一种弱类型语言&#xff0c;这意味着变量的数据类型通常是灵活的。为了更好地理解和操作数据&#xff0c;JavaScript提供了typeof操作符&#xff0c;它可以用来确定一个值的数据类型。在本篇博客中&#xff0c;我们将详细讨论typeof操作符&#xff0c;包括它的用法…

访问网站被拦截提示“该网站可能包含违法或违规内容”访问不了怎么办?设置一下360安全卫士即可解决

本来是一个正常的网站&#xff0c;结果被恶意举报后访问提示 该网站可能包含违法或违规内容 根据相关部门规定或投诉举报&#xff0c;此链接可能存在违反相关法律法规或政策的内容&#xff0c;建议您谨慎访问。 您访问的网址是&#xff1a;https://www.shuzhiqiang.com

Mongodb----部署副本集 实现读写分离

使用软件&#xff1a; xshell7 vmware16 centos8 nosql booster 1 部署副本集 推荐方案&#xff1a; 为了降低资源分配&#xff0c;这里仅使用一台服务器&#xff0c;但是分配3个端口&#xff08;27017、27018、27019&#xff09;来分别实现 主节点、副本节点…

echarts双y轴存在负数情况两轴0刻度不对齐问题

例一&#xff1a; <div id"main" style"width: 700px;height:600px;"></div> <script src"https://cdn.bootcss.com/echarts/4.7.0/echarts.min.js"></script> <script>const myChart echarts.init(document.ge…

自定义类型:结构体,枚举,联合 (1)

1 结构体的声明 1.1 结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.2 结构的声明 struct tag { member-list; }variable-list; 例如描述一个学生&#xff1a; struct是结构体关键字&#xff0c;不能省略。 …

MES管理系统如何解决电子企业排产难度大的问题

随着消费者需求的多样化和个性化&#xff0c;电子产品定制化程度越来越高&#xff0c;款式多样且需要小批量生产。这种情况下&#xff0c;企业面临着计划排产难度大、资源协调困难等问题。为了解决这些问题&#xff0c;越来越多的企业开始引入MES管理系统&#xff0c;本文将从M…

NVIDIA偷偷换接口,显卡终于不“烧”了

去年10月 NVIDIA RTX 4090 正式发布&#xff0c;可上市没多久便频频「翻车」。 接口熔化、自燃&#xff0c;有意无意间问题指向了供电能力本应更强的 12VHPWR 新接口。 后续大伙应该还记得&#xff0c;玩家安装不规范导致的咯。 然而后续是&#xff0c;即便确保接口插到底、无…

微信个人号如何实现自动回复客户消息?

企业在进行运营媒体平台与来自各个渠道的用户打交道时&#xff0c;像微博和公众号可以通过设置关注语/自动欢迎语来与用户互动。微信也提供了类似的功能&#xff0c;可以通过微信管理系统的自动回复功能实现。 微信管理系统的自动回复功能分为两种&#xff1a;通过好友自动回复…

UTF-16编码原理讲解

文章目录 一、unicode二、什么是UTF-16三、编码规则一个码元两个码元 四、问题大端序小端序&#xff1f; 参考 一、unicode unicode是一个字符集&#xff0c;也称为unicode编码&#xff0c;为每一个字符分配了一个ID&#xff0c;这个ID称为码点 Unicode的编码空间从U0000到U1…

Win11磁盘分区后在恢复之前分区的方法介绍

电脑磁盘分区对于新购买的电脑来说&#xff0c;是整理电脑第一步要做的事情&#xff0c;大家一般都会根据自己的需要把磁盘划分为C盘、D盘、E盘等等方面文件的管理&#xff0c;今天小编给大家介绍一下Win11操作系统下&#xff0c;如何进行分区&#xff0c;如何恢复之前的分区&a…

容器部署的openstack进入数据库流程、查看install目录流程、容器部署使用virsh命令流程【查看计算节点上的虚拟机信息】

说明 何为容器部署&#xff0c;无需多说吧&#xff1f; 如下 计算节点的容器 进入数据库方法【控制节点】 获取nova密码 首先获取nova数据库的密码 控制节点执行&#xff1a;grep mysql /etc/kolla/nova-api/nova.conf 【目录不是固定的&#xff0c;可以通过find命令查找n…