vv、vt 埋点上报自动化文档

news2024/11/17 16:29:14

vv、vt 埋点自动化文档


文章目录

  • vv、vt 埋点自动化文档
  • 一、项目简介
  • 二、环境搭建
    • Airtest官方参考文档
    • AirtestIDE下载
    • Python环境安装
    • Airtest安装
      • 安卓环境
      • IOS 环境
          • iOS-Tagent 编译
    • 设置代理
  • 三、框架介绍
  • 四、实现原理
    • 4.1 框架流程图
    • 4.2 初始化配置
      • 4.2.1 读取mock server配置,设置mock规则
        • 参数
        • 返回值
        • 异常
        • 原理
      • 4.2.2 清理mock server 日志
        • 参数
        • 返回值
        • 异常
        • 原理
      • 4.2.3 手机日志清理并开启日志记录
        • 原理
    • 4.3 UI操作封装
      • 4.3.1 UI 控件定位
      • 4.3.2 操作函数封装
      • 4.3.3 整体case自动化实现
    • 4.4 数据校验
        • 参数
        • 返回值
        • 原理
        • 自动化当前校验的点(新播放器)
      • 4.4.1 API接口实际值获取
        • 参数
        • 返回值
        • 原理
      • 4.4.2 ES数据实际值获取
        • 参数
        • 返回值
        • 原理
      • 4.4.3 如何查询ElasticSerarch埋点相关日志
      • 4.4.4 如何获取ElasticSerarch埋点相关日志
    • 4.5 日志计算逻辑
      • 4.5.1 播放器日志计算
        • 原理
      • 4.5.2 小窗日志计算
        • 原理
    • 4.6 Android 包下载及安装自动化
        • 原理
        • 注意:
    • 4.7 企业微信机器人推送
  • 五、使用&脚本示例
    • 5.1 概要
    • 5.2 环境准备
    • 5.3 依赖下载及配置参数
    • 5.4 测试用例编写步骤
    • 5.4 注意事项
  • 六、常见问题
    • 6.1 E airtest.core.error.DeviceConnectionError: 'device not ready'
    • 6.2 adb server version(40) doesn’t match this client(41)
        • 参考如下:
        • 注意:
    • 6.3 获取不到es数据
    • 6.4 PocoService连跑后不断重启,闪屏
        • 表现如下:
        • 主要原因
        • 解决方法
    • 6.5 total_time,pause_time 计算不准确导致fail
    • 6.6 连跑出现httpconnection错误,连接池无法新建连接(连接池爆了)
        • 原因
        • 解决办法
    • 6.7 连跑出现logcat的日志缓冲区给刷爆了,错误:logcat: Unexpected EOF!
        • 解决办法
    • 6.8 连跑偶现出现error报错,openAI 获取屏幕截图失败
        • 原因
    • 6.9 hasson平台mock_log日志查询不到请求头信息
        • 原因
        • 解决
    • 6.10 连跑的时候由于记录了上一次播放位置导致提早播放结束(视频时长太短了)
        • 解决
  • 七、代码仓库
  • 八、jenkins配置


一、项目简介

该项目实现播放次数播放时长的数据上报进行自动化校验,解决发版手工校验播放器数据上报以及北极星埋点的痛点,保障数据的正常上报和落表。

二、环境搭建

Airtest官方参考文档

Airtest官方文档

AirtestIDE下载

AirtestIDE下载地址

Python环境安装

Python <= 3.9

  • pip3 install pytest-html
  • pip3 install pymysql
  • pip3 install pytest-assume

已把所有依赖项整理成了requirement.txt文件,详情可见项目(用pycharm打开可选择自动下载所有依赖)

Airtest安装

安卓环境

  • pip3 install airtest
    • 添加adb权限:cd {your_python_path}/site-packages/airtest/core/android/static/adb/mac, chmod+x adb
      • 无法执行时,尝试将本地的adb复制到以上路径下,替换原来的adb(比如:cp /Users/ogvqa/Android/sdk/platform-tools/adb . 然后chmod+x adb)
  • pip3 install pocoui

IOS 环境

iOS-Tagent 编译
  • git clone git@github.com:AirtestProject/iOS-Tagent.git
  • 使用Xcode打开 iOS-Tagent, 用数据线连接iPhone至Mac
  • 连接iPhone后,在iPhone设备上弹出的“是否信任Mac设备”,选择信任
  • 选择项目,在菜单栏 product -> Scheme -> WebDriverAgentRunner
  • 选择设备,在菜单栏 product -> Destination -> 选择你的真机

在这里插入图片描述

  • 使用苹果账号或苹果开发者账号,登录Xcode,并注册真机设备

    • 左侧导航栏,选择 WebDriverAgentRunner -> TARGETS -> WebDriverAgentRunner -> Signing & Capabilities -> Team
  • 选择 Team -> Add an Account -> 登录苹果账号(个人免费或开发者账号)

  • 选择 TARGETS -> WebDriverAgentRunner -> Build Settings -> Basic

  • 双击 Product Bundle Identifier值,填写一个属于自己独一无二的字串

  • 回到,上文提过的Signing & Capabilities界面,查看有无报错

  • 无报错,则继续;若有报错,查看 登陆开发者账号

  • 1.4 启动Test,在菜单栏 product -> Test。当你看到这样的日志的时候,代表 iOS-Tagent 已经启动成功了

  • 一点坑,xcode 12.x报错Building for iOS Simulator, but the linked and embedded framework ‘***‘ was built …解决方式,将Validate Workspace为Yes后,重新编译

  • 运行报错: wda.exceptions.WDAUnknownError: WDARequestError(status=110, value={‘error’: ‘unknown error’, ‘message’: ‘-[XCUIScreen screenshotDataForQuality:rect:error:]: unrecognized selector sent to instance 0x2832349c0’})

    • 可以更换appium下的WebDriverAgentRunner,参考文档:iOS 真机如何安装 WebDriverAgent

设置代理

  • 安装libimobiledevice
    • brew install libimobiledevice
  • 运行proxy
    • 终端输入 iproxy 8100 8100
  • -启动成功后,可以试着在浏览器访问 http://127.0.0.1:8100/status ,如果访问成功并且可以看到一些json格式的手机信息,即表示启动成功

三、框架介绍

Airtest是网易开源的一款UI自动化测试项目,基于python脚本的方式,用于web、windows程序、app自动化测试.

官方文档介绍:airtest官网

在这里插入图片描述
在这里插入图片描述

四、实现原理

4.1 框架流程图

在这里插入图片描述

4.2 初始化配置

在每个测试用例执行之前都会先进行初始化配置:

在这里插入图片描述

具体分为三步:

  1. 读取mock server配置,设置mock规则
  2. 清理mock server日志
  3. 手机日志清理并开启日志记录

4.2.1 读取mock server配置,设置mock规则

核心函数:buryingpoint_setmockrule_new()

该函数用于设置 Mock Rule,以在自动化测试中对每个case模拟指定的response或者request。以下是对函数的详细说明:

参数

  • mock_env (字符串): 表示要使用的 Mock Server 环境的名称。
  • tc_name (字符串): 表示当前测试用例的名称。
  • env (字符串): 表示测试环境的名称。
  • params (字典): 包含测试参数和配置信息的字典。
  • platform (字符串): 表示测试平台的名称。

返回值

  • True (布尔值): 如果成功设置 Mock Rule,则返回 True。
  • False (布尔值): 如果设置 Mock Rule 失败或出现异常,则返回 False。

异常

  • 如果 mock_env 为空字符串,则会打印错误消息 “Mockserver未设置” 并返回 False。
  • 如果无法读取 Mock 数据文件,则会引发 FileNotFoundError 异常。
  • 如果重置 Mock 规则失败(状态码不为 200 或返回的数据不为 “ok”),则会打印错误消息并返回 False。
  • 如果测试用例的 Mock 规则未给出或未包含在参数中,则会打印错误消息并返回 False。
  • 如果设置 Mock 规则失败(状态码不为 200 或返回的数据不为 “ok”),则会打印错误消息并返回 False。
  • 如果在设置 Mock 规则过程中发生其他异常,则会打印异常消息并返回 False。

原理

该函数使用了 Python 的 requests 模块来发送 HTTP 请求,post请求地址如下:

在这里插入图片描述

通过控制两次post请求传参来改变 hasson平台上mock规则的状态(开关):

在这里插入图片描述

  1. 第一次请求会把当前mock_env 环境下的所有规则开关状态初始化为false;
  2. 第二次请求会把每个case需要的mock规则开关置为true;

代理规则配置json文件:

在这里插入图片描述

每个case具体配哪个mock规则在conf.py文件中配置:

在这里插入图片描述

4.2.2 清理mock server 日志

核心函数:buryingpoint_cleanup_new()

该函数用于清理 mock log 数据,以准备下一次的自动化测试。以下是对函数的详细说明:

参数

  • mock_env (字符串): 表示要清理的 Mock Server 环境的名称。
  • tc_name (字符串): 表示当前测试用例的名称。
  • test_env (字符串): 表示测试环境的名称。
  • params (字典): 包含测试参数和配置信息的字典。

返回值

  • True (布尔值): 如果成功清理 mock log,则返回 True。
  • False (布尔值): 如果清理 mock log 失败或出现异常,则返回 False。

异常

  • 如果无法访问 params 字典中指定的键或键不存在,则会引发 KeyError 异常。
  • 如果请求删除 mock log 的响应状态码不为 200,则会打印错误消息并返回 False。

原理

该函数实现清理hasson平台上指定env、host、path 下的日志数据,实现初始化,便于后续读取每个case的日志上报。

在这里插入图片描述

通过遍历conf.py文件的入参字典中的数据构建 args 列表,其中包含了需要清理的 Mock Log 的相关信息。
在这里插入图片描述

随后函数会调用 delete_mock_log 函数来发送http请求以删除 Mock Log。

在这里插入图片描述

4.2.3 手机日志清理并开启日志记录

核心函数:start_log_collection(cls)

原理

该函数实现手机日志的清理,开启一个子线程开启手机日志清理任务
在这里插入图片描述

随后创建一个AndroidLogThread对象log_thread,用于在后台收集并保存设备的日志信息。
在这里插入图片描述

以下为开启日志线程的具体实现(安卓端为例):

在这里插入图片描述

4.3 UI操作封装

埋点上报自动化在UI定位和操作上结合了airtest框架和poco框架

4.3.1 UI 控件定位

pages文件夹涵盖了目前case所需的所有UI控件名以及坐标位置
在这里插入图片描述
部分代码示例:
在这里插入图片描述

相关控件属性可以通过airtest IDE 提供的 poco-inspecter 抓取。

4.3.2 操作函数封装

相关的操作函数都经过封装放在了keywords文件夹

结合了poco框架和airtest框架提供的部分函数,以及一些shell指令实现。

部分代码示例:

在这里插入图片描述

4.3.3 整体case自动化实现

相关的case实现放在了testcase文件夹下,通过对封装好的操作函数进行拼接就可以实现各种case的UI操作
在这里插入图片描述

4.4 数据校验

核心函数:buryingpoint_player_assert()

该函数用于对api接口上报数据和es数据库中的数据的预期值和实际值进行断言。

参数

  • cls:类对象
  • mock_env:模拟环境信息
  • tc_name:测试用例名称
  • env:环境信息
  • buvid:Buvid信息
  • check_point_index:检查点索引
  • params:检查点参数
  • timestamp:时间戳信息
  • log_path:日志文件路径
  • ignore_play:是否忽略播放
  • miniplayer_play_time:最小播放器播放时间
  • paused_time:暂停时间

返回值

  • result:断言结果(True/False)
  • api_result_list:API结果列表
  • es_result_list:ESP结果列表

原理

函数会检索conf.py文件下的配置信息,获得对应case的预期值字典(包含api和es的校验预期值)

在这里插入图片描述

随后函数会获取api接口实际上报的值和es库中的值,和预期值进行比对。

自动化当前校验的点(新播放器)

vv:

  • aid、cid、epid、sid= 实际值
  • epid_status:EP 付费状态
  • type :4 (视频类型为pgc)
  • sub_type: 1番剧 2电影 3纪录片 4国创 5电视剧
  • auto_play :(0:非自动播放上报,1:动态自动播放上报,2:天马feed流inline 自动播放,3:相关推荐自动播放)
  • mobi_app:实际测试系统(安卓传android、iPhone传iPhone)
  • device:实际测试终端(安卓传空、iPhone传phone)
  • mid 、buvid: 实际值
  • spmid:pgc.pgc-video-detail.0.0
  • from_spmid:(进入页面的spmid)
  • playlist_type + playlist_id:播单、离线缓存的场景特有字段

vt:

  • played_time = 播放器实际播放耗时
  • paused_time= 暂停时间
  • total_time = played_time+paused_time
  • actual_played_time = 计算倍速后的真实耗时
  • last_play_progress_time = 结束播放时的播放进度
  • max_play_progress_time = 此次播放中最大播放进度
  • miniplayer_play_time = 小窗播放时长
  • auto_play:(0:非自动播放上报,1:动态自动播放上报,2:天马feed流inline 自动播放,3:相关推荐自动播放)
  • quality:上报应为当前播放的清晰度,非用户清晰度

vv包含的所有字端vt均需要校验

当前会校验上报的数量和接口的数据

4.4.1 API接口实际值获取

核心函数: get_actual_api_counts_and_values()

该函数用于获取实际的API计数和值

参数

mock_env:模拟环境信息
check_point:检查点信息

返回值

actual_api_counts:实际API计数字典
actual_api_values:实际API值字典

原理

该函数会检索conf.py文件,并获取到对应case 的mock_env, host, path作为入参
在这里插入图片描述

然后去调用get_mock_log_info函数去通过post请求获取hasson平台上的mock_log日志

在这里插入图片描述

最后对返回的json数据进行整理,过滤,获得实际的上报的值

在这里插入图片描述

4.4.2 ES数据实际值获取

核心函数: get_es_data()

该函数用于从Elasticsearch获取ESP数据。它接受日志ID、Buvid、起始时间戳等参数作为输入。

参数

  • log_id:日志ID
  • buvid:Buvid信息
  • gte:开始时间戳
  • expected_size:期望的结果集大小
  • event_id=“”:事件ID(默认为空字符串)
  • platform=“”:平台信息(默认为空字符串)
  • tc_name=“”:测试用例名称(默认为空字符串)
  • *kw:conf.py文件中es的期望key值(元组)

返回值

  • data:包含ESP数据的字典
  • actual_size:实际的结果集大小
  • message:获取到的Elasticsearch日志消息

原理

定义不同场景下可能的事件ID列表
在这里插入图片描述

构建Elasticsearch查询的URL、请求头和排序方式,以及根据输入参数构建查询字符串,包括环境、日志ID、Buvid、事件ID等

在这里插入图片描述

获取当前时间戳 lte 并构建Elasticsearch查询的查询体,发送POST请求到Elasticsearch,获取返回结果。

在这里插入图片描述

解析返回结果,提取命中的文档列表和文档数量。

遍历每个命中的文档:

  1. 解析日志内容,并对一些特定情况下的字段进行处理。
  2. 将解析结果添加到ESP数据存储字典 data 中。

在这里插入图片描述

4.4.3 如何查询ElasticSerarch埋点相关日志

  • 步骤1:登录kibana kibanna
  • 步骤2: 筛选索引 billions-datacenter.buryingpoint.buryingpoint-@*

在这里插入图片描述

  • 步骤3: 添加筛选条件,如 事件id,buvid,fields.env 等等

在这里插入图片描述

4.4.4 如何获取ElasticSerarch埋点相关日志

billions-proxy 支持通过Restful api的方式查询ops-log/uat-log中的数据

uat-log使用姿势

http需要包含的header

  • Appid: 部门.项目.应用
  • Appkey: key
  • Content-Type: application/json

统一访问地址:172.22.33.113:81/{location}

Appid: billions Appkey: proxy

相应的请求方法对应location为:

  • v7/<index_name>/_search

  • v7/<index_name>/_count

请求body必须传入!!!

在这里插入图片描述

日志查询接口:

curl --location --request POST 'http://172.22.33.113:81/v7/billions-datacenter.buryingpoint.buryingpoint-@*/_search' \
--header 'content-type: application/json' \
--header 'Appid: billions' \
--header 'Appkey: proxy' \
--data-raw '{"size": 2, "sort": {"@timestamp": {"order": "asc"}}, "query": {"bool": {"filter": [{"query_string": {"query": "fields.env:\"prod\" AND \"logId=000032\" AND \"buvid=ZB485FB68E7385DB42BA887F688058916AF5\""}}, {"range": {"@timestamp": {"gte": 1647513614961, "lte": 1647513645514}}}]}}}'
(gte:开始测试的时间,lte:当前的时间)

4.5 日志计算逻辑

核心函数:get_play_time_v2()

该函数用于从手机日志文件中获取ijk播放器状态和事件来计算播放器以及小窗的播放时间、暂停时间、倍速播放时间。

4.5.1 播放器日志计算

原理

逐行读取日志文件,并从每行中提取ijk播放器相关信息,将其存储在 player_record 列表和 small_player_record 列表中。

在这里插入图片描述

接着遍历 player_record 列表,根据时间戳和播放器状态计算播放时间和暂停时间。

在这里插入图片描述

处理特定事件,例如播放速度更改或在播放过程中切换项目。

在这里插入图片描述

计算完播放时间和暂停时间后,将结果存储在 time_list 列表中。

4.5.2 小窗日志计算

该函数还会计算小窗口播放器(miniplayer)的持续时间(如果适用)。

在这里插入图片描述

原理

过滤手机日志中获取小窗相关的事件以及里面的mCTime去计算小窗的持续时间,开始时间

过滤出来的日志如下:

在这里插入图片描述

4.6 Android 包下载及安装自动化

已支持从fawkes平台上自动下载包以及包的安装和卸载

原理

在fawkes平台上构建好指定的包
在这里插入图片描述

通过对指定接口发送get请求获取到自己当下构建好的包,从接口返回中拿到下载的url

在这里插入图片描述

然后把这个链接下载到本地项目中,再通过调用shell指令去安装指定的apk

注意:

此处注意把params、cookies、headers 改成自己实际的值,否则无法请求到自己构建的包
在这里插入图片描述

4.7 企业微信机器人推送

已支持企业微信机器人,后续接入测试报告的推送。

五、使用&脚本示例

5.1 概要

本项目是在UAT环境下基于Hasson和数据平台进行校验,UI脚本与数据校验相分离

5.2 环境准备

双端通过Hasson连接至uat环境
在这里插入图片描述

5.3 依赖下载及配置参数

在conftest.py文件下面设置设备的参数:

在这里插入图片描述主函数可以运行对应的测试套件:

在这里插入图片描述

5.4 测试用例编写步骤

在这里插入图片描述

示例:

在这里插入图片描述

相关conf.py 配置如下:

在这里插入图片描述

5.4 注意事项

在这里插入图片描述

六、常见问题

6.1 E airtest.core.error.DeviceConnectionError: ‘device not ready’

  • 确保设备正确连接:请确保您的设备已连接到计算机,并且在执行测试之前已完成设备驱动程序的安装和设置。可以通过运行 adb devices 命令来验证设备是否正确连接。

  • 重启设备和计算机:有时候,重新启动设备和计算机可以解决连接问题。尝试断开设备,并重新启动设备和计算机,然后再次进行测试。

  • 检查设备调试模式和USB调试选项:确保设备已启用调试模式,并且 USB 调试选项已启用。这些选项通常在设备的开发者选项中找到。启用调试模式后,重新连接设备并尝试运行测试。

  • 检查设备连接方式:根据您的测试环境,可能需要使用正确的连接方式。例如,如果您正在使用真实的 Android 设备,则需要使用 Android:/// 进行连接。如果您正在使用模拟器,则可能需要使用相应的模拟器连接方式。

  • 更新相关软件:确保您使用的相关软件(如 Airtest、ADB)是最新版本,并且与您当前的测试环境兼容。有时候,更新软件可以解决一些已知的问题或错误。

6.2 adb server version(40) doesn’t match this client(41)

这个错误提示表明你的ADB(Android Debug Bridge)客户端版本与ADB服务器版本不兼容。ADB客户端和服务器之间需要保持相同的版本以确保它们可以正常通信。

要解决这个问题,你可以尝试以下几种方法:

  • 更新ADB客户端:如果你的ADB客户端版本较旧,请尝试更新到与ADB服务器版本匹配的最新版本。你可以从Android SDK Manager中下载最新的ADB版本,或者从Android官方网站上下载ADB二进制文件并手动替换掉旧版本。

  • 降级ADB服务器:如果你的ADB客户端是最新版本,但服务器版本过高,可能需要将ADB服务器降级到与客户端兼容的版本。你可以在Android SDK目录下找到ADB二进制文件,并替换为与你的ADB客户端版本匹配的较旧版本。

  • 检查环境变量和路径设置

参考如下:

把pycharm中的adb版本改成和终端下载的版本一致即可

把这个路径 /venv/lib/python3.9/site-packages/airtest/core/android/static/adb/Mac/adb 下的adb 换成终端下载好的adb就行

注意:

记得在环境变量加入终端的path,否则运行不成功!!!
在这里插入图片描述

6.3 获取不到es数据

  • 有时候es那边可能在做什么改动,偶尔会出现拿不到es数据的情况
  • 如果是发生错误了,请检查一下无线网是否连接的是正确的
    在这里插入图片描述

获取es的接口对网段做了一些限制

6.4 PocoService连跑后不断重启,闪屏

表现如下:

在这里插入图片描述

主要原因

每条case都会实例化多个poco对象,若手机后台自动清理了poco,框架自带的监控进程会不断尝试重启,影响自动化运行

解决方法

修改框架里面的Androiduiautomation类变成了单例模式实现,全局只实例化一个对象(目前的做法)

或者参考一下下面的文章,修改一下手机的设置项:

poco无限重启解决办法

6.5 total_time,pause_time 计算不准确导致fail

由于跟播放时长和暂停时长的计算逻辑是根据ijk播放器的状态去计算,并未结合ijk播放器的事件去计算,受网络原因影响或者手机性能影响会造成计算值与实际值不准确的情况(自动化时间算法和开发那边的逻辑不一致),可能有类似于缓冲态这种事件,会导致计算不准确。

6.6 连跑出现httpconnection错误,连接池无法新建连接(连接池爆了)

原因

  1. http保持长连接导致短时间内大量连接存在,最终服务器拒绝访问;
  2. 访问次数频繁,被禁止访问

解决办法

  • 更改连接池最大数量
  • 修改keep-alive = false
  • 把代码中所有的request都关闭连接,让连接池回收(目前的做法)

6.7 连跑出现logcat的日志缓冲区给刷爆了,错误:logcat: Unexpected EOF!

解决办法

  1. 在开发者选项中,可以通过显示/允许增加环形缓冲区的大小,进行相关的缓冲区的大小设置(这样只能改一部分的缓冲区)
  2. getprop | grep “persist.logd.size” 查看缓冲区大小,然后手动设置
  3. 每次case开始都清除所有的缓冲区(目前的做法)
    在这里插入图片描述

6.8 连跑偶现出现error报错,openAI 获取屏幕截图失败

原因

airtest框架问题,长时间运行代码可能某些case截取屏幕就会失败,所以建议某些case最好不使用airetest框架,直接用adb shell来控制手机的操作

6.9 hasson平台mock_log日志查询不到请求头信息

原因

直接去请求get 平台的信息,平台做了一些过滤,只会给出接口上报的请求体,响应头和响应体信息。

解决

若后续需要增加的字段是在请求头中的,比如 buvid , 需要修改请求的参数,并把这个字段做处理增加到校验列表里(已在代码中实现)

6.10 连跑的时候由于记录了上一次播放位置导致提早播放结束(视频时长太短了)

解决

已新增mock规则,每个case结束 history接口上报的progress = -1 ,即不记录历史记录

在这里插入图片描述

后续只需要在conf.py中 在对应的case 配置一下这个mock规则即可。
在这里插入图片描述

七、代码仓库

八、jenkins配置

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

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

相关文章

sqli-labs

目录 Less1 首先来爆字段 联合注入 判断注入点 爆数据库名 爆破表名 information_schema information_schmea.tables group_concat() 爆破列名 information_schema.columns 爆值 SQLMAP 主要对sqli-labs 的深入学习 Less1 我们先看看源代码 <?php //includ…

山西电力市场日前价格预测【2023-07-16】

日前价格预测 预测明日&#xff08;2023-07-16&#xff09;山西电力市场全天平均日前电价为395.36元/MWh。其中&#xff0c;最高日前电价为510.19元/MWh&#xff0c;预计出现在20: 00。最低日前电价为309.52元/MWh&#xff0c;预计出现在13: 15。 价差方向预测 1&#xff1a;实…

如何从零开始搭建公司自动化测试框架?

搭建的自动化测试框架要包括API测试&#xff0c;UI测试&#xff0c;APP测试三类。以上三类其实可以简化为两类&#xff0c;那就是&#xff1a; 1&#xff09;接口自动化测试框架搭建 2&#xff09;UI自动化测试框架搭建。 没问题&#xff0c;安排&#xff0c;且是手把手教你如何…

Next.js框架入门笔记

内置组件 ‘pages/_document.js’ 文件&#xff0c;自定义document DOC&#xff1a; https://www.nextjs.cn/docs/advanced-features/custom-document <Head>组件 <Head>是一个内置在 Next.js 中的 React 组件。它允许您修改页面的<head>。 Docs: https:/…

JVM理论(四)运行时数据区--堆/方法区

堆(heap) 堆内存逻辑上分为三部分 一个JVM实例只存在一个堆内存,JVM启动时创建堆区&#xff0c;通常情况下也是最大的内存空间&#xff0c;几乎所有的对象实例都要在堆中分配内存&#xff0c;所以堆也是垃圾回收的重点区域堆是被所有线程共享的,在堆里面也可以划分线程私有的缓…

肝!熬夜到天明,阿里顶配级 Spring Security 笔记

Spring Security Spring Security 是一个能够为基于 Spring 的企业应用系统提供声明式的安全访问控制解决方案的安全框架。由于它是 Spring 生态系统中的一员&#xff0c;因此它伴随着整个 Spring 生态系统不断修正、升级&#xff0c;在 spring boot 项目中加入 springsecurit…

Ubuntu下安装Miniconda

下载 到根据自己本地python版本到官网下载 https://docs.conda.io/en/latest/miniconda.html#linux-installers 我本地是python3.8 然后上传到Ubuntu服务器上&#xff0c;或者直接使用wget下载&#xff1a; wget https://repo.anaconda.com/miniconda/Miniconda3-py38_23.5…

WebSocket理论和实战

一 WebSocket理论 1.1 什么是http请求 http链接分为短链接、长链接&#xff0c;短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。长链接是在一定的期限内保持链接&#xff08;但是是单向的&#xff0c;只能从客户端向服务端发消息&#x…

单例模式、指令重排序、锁、有序性

今天在回顾单例模式时&#xff0c;我们都知道懒汉式单例中有一种叫做双重检查锁的单例模式。 我们来看下下面的代码有没有问题&#xff1a; 这段代码我们可以看到&#xff0c;即优化了性能&#xff0c;在多线程情况下&#xff0c;如果实例不为空了&#xff0c;则直接返回了。…

1766_perl实现readlines功能

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 近段时间写一个Perl程序&#xff0c;中间反反复复用到了文件的读写。虽说是用Perl的基本功能实现读写非常简单&#xff0c;但是写的过程中我不止一次在想Python以及MATLAB的功能…

华为OD机试真题 Java 实现【评论转换输出】【2023 B卷 100分】,附详细解题思路

目录 专栏导读一、题目描述在这里插入图片描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A…

什么是元学习?外循环和内循环?支持集和查询集?

一、前言 元学习近几年也算是一个比较热门的研究方向&#xff0c;大部分被用来解决低资源少样本零样本学习的任务场景中。 那么为什么元学习可以提升低资源少样本的学习效果呢&#xff1f;活着说元学习到底是一个什么阳的算法呢&#xff1f; 这里做一个简单的概念阐述。元学…

echart之map地图图表使用教程

本文以echarts展示成都地图为例子。 echarts map &#xff08;echarts地图&#xff09;使用教程 效果展示准备阶段获取地图geojson数据安装echarts 开始绘制容器准备js代码 补充事项vue3.0 用ref定义echarts报错toRaw、markRaw 扩展 地图隐藏南海诸岛地图显示提示框地图实现下钻…

Vue项目的启动

前言&#xff1a; 由于最近开始实习&#xff0c;负责人上来就给我丢一个前端vue项目和后端文件&#xff0c;让我在本机完成部署&#xff0c;由于之前学的基本上都是后端相关知识&#xff0c;很少有了解到前端的东西&#xff0c;因此在这里将自己部署Vue项目时遇到的问题和解决过…

编译libtiff库给IOS平台用

打开libtiff官方网 : libtiff / libtiff GitLab 克隆: git clone --recursive https://gitlab.com/libtiff/libtiff.git 克隆成功并打开libtiff目录,发现有autogen.sh 与CMakeLists.txt所以可生成Configure程序来配置并编译,也可直接使用CMake-GUI来配置编译,选择其中一种 …

远程会诊如何实现?

比如&#xff1a;医生遇到复杂病情需要求助院外专家远程会诊过程中&#xff0c;需要将电脑中的病人资料给院外专家看&#xff0c;同时确保医院电脑和网络系统绝对安全&#xff0c;电脑不允许安装任何外部软件&#xff0c;不能被外人控制和操作&#xff0c;外部设备不能接入医院…

【Java技术专题】「攻破技术盲区」带你攻破你很可能存在的Java技术盲点之技术功底指南(鲜为人知的技术)

带你攻破你很可能存在的Java技术盲点之技术功底指南 基本类型的包装类技术盲点&#xff1a;基本类型的比较技术盲点&#xff1a;字符串内部化&#xff08;string interning&#xff09;字符串内部化的示例 技术盲点&#xff1a;类型缓存机制&#xff08;空间换时间&#xff09;…

微信小程序border-radius不圆滑

border-radius可以设置&#xff1a;百分比或者像素值 1.使用像素值比较圆滑 2.使用百分比不够圆滑

习题1.25

对吗?实践出真知,运行看看。代码如下。 (defn square [x] (* x x))(defn fast-expt[b n](println "call iter" n)(cond (= 1 n) b(= 2 n) (square b)(even? n) (square (fast-expt b (/ n 2))):else (* b (fast-expt b (- n 1)))))(defn expmod [base exp m](mod…

pytest 结合logging输出日志保存至文件

API_log.py import loggingclass loger():def logering(self):# 创建logger对象logger logging.getLogger(test_logger)# 设置日志等级logger.setLevel(logging.DEBUG)# 追加写入文件a &#xff0c;设置utf-8编码防止中文写入乱码test_log logging.FileHandler(test.log, a,…