pytest +uiautomator2+weditor app自動化從零開始

目錄結構1.0
在這里插入圖片描述
把設備連接單獨移出去了
在這里插入圖片描述
模塊操作代碼,有一些流程操作和斷言方法

from devices import dv
from time import sleep
import random
from tool.jt import capture_screenshotdef initialization(func):def wrapper():sleep(1)dv.app_stop('com.visteon.txzing.accountcenter')dv.app_start('com.visteon.txzing.accountcenter')sleep(2)func()return wrapper@initialization
def f1():'''1、打開賬號切換,點擊其他的賬號,點擊確認登錄,點擊取消'''dv(text='賬號切換').click()dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/change_account_recycler"]/android.view.ViewGroup[2]').click()dv(text='確定').click()dv(text='取消').click()@initialization
def f2():'''2、點擊設置、點擊退出登錄、點擊取消'''dv(text='設置').click()dv(text='退出登錄').click()dv(text='取消').click()@initialization
def f3():'''3、點擊設置、點擊用戶協議,點擊返回,點擊隱私政策,點擊返回,再次點擊返回到個人中心主頁面'''dv(text='設置').click()dv(text='用戶協議').click()sleep(1.5)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/top_bar_back"]').click()dv(text='隱私政策').click()sleep(1.5)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/top_bar_back"]').click()sleep(1.5)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/top_bar_back"]').click()@initialization
def f4():'''4、點擊賬號關聯,點擊高德地圖綁定,點擊確定'''dv(text='賬號關聯').click()try:dv.xpath('//*[@content-desc="綁定高德地圖"]').click()except:dv.xpath('//*[@content-desc="綁定高德地圖"]').click()dv(text='確定').click()def f5():'''5、進入問題反饋,點擊開始錄音,5s內結束錄音,重新開始錄音,切換問題類別從第一個切到最后一個,然后提交,最后播放語音'''dv(text='問題反饋').click()dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()sleep(4)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()sleep(1)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()for i in ['多媒體', '導航', '藍牙電話', '維保類', '設置', '其他']:dv(text=i).click()sleep(1)# 錄音秒數隨機sleep(random.randint(1, 80))dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()dv(text='提交').click()sleep(2)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.view.ViewGroup[1]').click()def run():while True:try:f1()f2()f3()f5()f4()except Exception as e:capture_screenshot(e)print(f'報錯了重新運行{e}')# 通過獲取文本來斷言
b = '//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.widget.TextView[1]'
a = dv.xpath(b).get_text()
print(a)# 通過判斷元素是否存在來斷言
c = dv.xpath('//*[@text="2023/11/30 15:49"]').exists
print(c)# 通過元素屬性是否發生變化來進行斷言
d = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]')
# 獲取語音條初始狀態的info信息
initial_info = d.info
d.click()
clicked_info = d.info
# 比較前后的info信息,找出差異數據
diff = {k: clicked_info[k] for k in clicked_info if clicked_info[k] != initial_info[k]}
print("前后的差異數據:", diff)
if len(diff) == 0:print('狀態未發生變化')
else:print('斷言成功')if __name__ == '__main__':while True:run()

目錄結構1.1
新增test_accountcenter.py編寫測試用例
新增run.py執行pytest
新增pytest.ini配置文件
在這里插入圖片描述
test_accountcenter.py
刪除了3個場景,留下2個場景,每個場景加了2種斷言方式f1(ex):f5(ex):,測試用例是test_zhanghao():test_luyin():,f1(ex):f5(ex):內部實現了斷言并且返回結果

from devices import dv
from time import sleep
import random
from tool.jt import capture_screenshot
def f1(ex):'''1、打開賬號切換,點擊其他的賬號,點擊確認登錄,點擊取消'''dv.app_stop('com.visteon.txzing.accountcenter')dv.app_start('com.visteon.txzing.accountcenter')dv(text='賬號切換').click()dv.xpath('//*[@resource-id="com.visteon.txzing.accountcenter:id/change_account_recycler"]/android.view.ViewGroup[2]').click()dv(text='確定').click()text= dv(text='請在互聯小程序確認登錄').get_text()if not dv.xpath('//*[@resource-id="com.visteon.txzing.accountcenter:id/loading_cancel"]').exists:return Falseass =ex==textreturn assdef f5(ex):'''5、進入問題反饋,點擊開始錄音,5s內結束錄音,重新開始錄音,切換問題類別從第一個切到最后一個,然后提交,最后播放語音'''dv.app_stop('com.visteon.txzing.accountcenter')dv.app_start('com.xxxxxxx.xxxxxxx.accountcenter')dv(text='問題反饋').click()dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()sleep(4)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()sleep(1)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()lb=['多媒體', '導航', '藍牙電話', '維保類', '其他', '設置']for i in lb:dv(text=i).click()sleep(1)# 錄音秒數隨機sleep(random.randint(5, 10))dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()dv(text='提交').click()ass= '設置'==ex'''元素信息變化'''d = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]')# 獲取語音條初始狀態的info信息initial_info = d.infod.click()clicked_info = d.info# 比較前后的info信息,找出差異數據diff = {k: clicked_info[k] for k in clicked_info if clicked_info[k] != initial_info[k]}print("前后的差異數據:", diff)if len(diff) == 0:return Falsesleep(2)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.view.ViewGroup[1]').click()return assdef test_zhanghao():f1('請在互聯小程序確認登錄')assert Truedef test_luyin():assert f5('設置')run.py文件
運行文件,暫未配置參數
```python
import pytest
pytest.main([])

pytest.ini文件
配置了下報告的一些參數

[pytest]
addopts = -s --alluredir ./report/data

目錄結構1.2
新增斷言方法文件
在這里插入圖片描述
assertion.py文件
首先dw()判斷元素是否存在,不存在不需要進行后續操作,element_existence方法適用于斷言元素是否存在,element_info_existence方式適用于判斷元素在點擊后是否發生了屬性變化來斷言,element_text_existence適用于判斷元素文本和預期結果是否一致

from time import sleep
def dw(dv, element, positioning_method):''':param dv: 設備:param element: 定位元素:param positioning_method: 定位方式:return: 判定元素是否存在,存在則返回元素對象用于后續操作'''if positioning_method == 'xpath':if not dv.xpath(element).exists:print('斷言元素不存在,直接判定斷言失敗')return Falsereturn dv.xpath(element)if positioning_method == 'text':if not dv(text=element).exists:print('斷言元素不存在,直接判定斷言失敗')return Falsereturn dv(text=element)def element_existence(dv, element, positioning_method):''':param dv: 設備:param element: 定位元素:param positioning_method: 定位方式:return:通過元素是否存在來斷言'''element_ = dw(dv, element, positioning_method)if not element_:return Falsereturn Truedef element_info_existence(dv, element, positioning_method):''':param dv: 設備:param element: 定位元素:param positioning_method: 定位方式:return:通過元素屬性是否發生變化來斷言'''if not dw(dv, element, positioning_method):return Falseelse:el = dw(dv, element, positioning_method)initial_info = el.infoel.click()sleep(1)clicked_info = el.infodiff = {k: clicked_info[k] for k in clicked_info if clicked_info[k] != initial_info[k]}print(f'元素差異字段{diff}')if len(diff) == 0:print('元素屬性未發生變化,斷言失敗')return Falsereturn Truedef element_text_existence(dv, element, positioning_method, text):''':param dv: 設備:param element: 定位元素:param positioning_method: 定位方式:param text: 預期結果文本:return: 通過文本是否相等來斷言'''if not dw(dv, element, positioning_method):return Falseelse:el = dw(dv, element, positioning_method)el_text=el.get_text()if not text ==el_text :print(f'文本不匹配預期結果{text},實際結果{el_text}')return Falseelse:return True

目錄結構1.3
新增case文件夾
case-fun 以每個模塊一個文件,里面包含多個場景操作,和場景斷言
case-test_case 以每個模塊一個文件,和fun文件夾文件一一對應,負責執行模塊的每個場景
在這里插入圖片描述
accountcenter.py文件

import random
from time import sleep
from tool.assertion import element_existence, element_info_existence, element_text_existencedef f1(dv):'''1、打開賬號切換,點擊其他的賬號,點擊確認登錄'''dv.app_stop('com.visteon.txzing.accountcenter')dv.app_start('com.visteon.txzing.accountcenter')dv(text='賬號切換').click()dv.xpath('//*[@resource-id="com.visteon.txzing.accountcenter:id/change_account_recycler"]/android.view.ViewGroup[2]').click()dv(text='確定').click()'''斷言'''return element_existence(dv, '取消', 'text')def f2(dv):dv.app_stop('com.xxxxxxx.xxxxxxx.accountcenter')dv.app_start('com.xxxxxxx.xxxxxxx.accountcenter')'''2、點擊設置、點擊退出登錄、點擊取消'''dv(text='設置').click()dv(text='退出登錄').click()dv(text='取消').click()return element_text_existence(dv, '退出登錄', 'text', '退出登錄')def f5(dv):'''5、進入問題反饋,點擊開始錄音,5s內結束錄音,重新開始錄音,切換問題類別從第一個切到最后一個,然后提交,最后播放語音'''dv.app_stop('com.xxxxxxx.xxxxxxx.accountcenter')dv.app_start('com.xxxxxxx.xxxxxxx.accountcenter')dv(text='問題反饋').click()dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()sleep(2)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()sleep(1)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()lb = ['多媒體', '導航', '藍牙電話', '維保類', '其他', '設置']for i in lb:dv(text=i).click()sleep(1)# 錄音秒數隨機sleep(random.randint(5, 10))dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()dv(text='提交').click()sleep(2)dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]').click()  # 點擊語音條'''斷言'''return element_info_existence(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]','xpath')

test_accountcenter.py文件

from case.fun.accountcenter import f1, f2, f5
from devices import dv
def test_f1():assert f1(dv)
def test_f2():assert f2(dv)
def test_f5():assert f5(dv)

familytime.py

import random
from time import sleep
from devices import dv
from tool.assertion import element_existence, element_info_existence, element_text_existence'''這些是通過觀察元素屬性觀察得出的結論,這些是通用值'''def tu(number):'''家人時光每個圖片定位'''tu = dv.xpath(f'//*[@resource-id="com.visteon.txzing.familytime:id/recycler_view"]/android.view.ViewGroup[{number}]/android.widget.ImageView[1]')return tu# 設為按鈕
set_as = dv(text='設為')
# 設置壁紙
set_wallpaper = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]')
# 設置屏保
set_screensaver = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]')
# 設為按鈕
confirm = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]')
# 取消按鈕
cancel = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_cancel"]')def set_s_w():dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')dv.app_start('com.xxxxxxx.xxxxxxx.familytime')tu(1).click()set_as.click()set_wallpaper.click()set_screensaver.click()confirm.click()# 多個斷言處理ass_1 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath','壁紙、屏保設置成功')ass_2 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_label"]', 'xpath','壁紙 屏保')ass_list = [ass_1, ass_2]for i in ass_list:if not i:print(f'斷言{i}失敗')return Falsereturn Truedef cancel_s_w():dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')dv.app_start('com.xxxxxxx.xxxxxxx.familytime')tu(1).click()set_as.click()set_wallpaper.click()set_screensaver.click()confirm.click()return element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath','壁紙、屏保取消成功')

test_familytime.py

from case.fun.familytime import set_s_w, cancel_s_w
from devices import dv
from time import sleep
def test_set_s_w():set_s_w()
def test_cancel_s_w():cancel_s_w()

目錄結構1.4
新增dw.py文件,增加元素定位封裝,定位失敗截圖
新增conftest.py,配合pytest.fixture實現前后置
在這里插入圖片描述
dw.py

from time import sleep
from lxml import etree
from tool.screenshot import capture_screenshot
class DwFail(Exception):pass
def jt(case_name, positioning_instructions):print('定位元素不存在,進行截圖')info = f'用例標題{case_name},定位元素說明:{positioning_instructions}'capture_screenshot(info)
def find_elements(dv, element, positioning_method, case_name, positioning_instructions):''':param dv: 設備對象:param element:元素定位數據:param positioning_method:元素定位方式:param case_name:測試用例名稱:param positioning_instructions: 這個元素測試的對象說明:return:'''sleep(1.5)if positioning_method == 'xpath':try:if dv.xpath(element).exists:print('定位成功')return dv.xpath(element)else:jt(case_name, positioning_instructions)raise DwFail(f'定位失敗,用例標題{case_name},定位元素說明:{positioning_instructions}')except etree.XPathEvalError:jt(case_name, positioning_instructions)raise DwFail(f'xpath路徑錯誤定位,用例標題{case_name},定位元素說明:{positioning_instructions}')elif positioning_method == 'text':if dv(text=element).exists:return dv(text=element)else:jt(case_name, positioning_instructions)raise DwFail(f'定位失敗,用例標題{case_name},定位元素說明:{positioning_instructions}')else:print('暫時只支持xpath,text定位')if __name__ == '__main__':from devices import dv# find_elements(dv, '.ViewGroup[2]', 'xpath', 'xpath', '點擊設12222211111111置')find_elements(dv, '//*[@resource-id="com.visteon.txzing.accountcenter:id/feedback_record_bar_time', 'xpath','進行錄音問題反饋', '點擊語音條').click()# find_elements(dv, '//*[@resource-id="com.visteon.txzing.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.view.ViewGroup[1]', 'xpath',#               '進行錄音問題反饋', '點擊語音條').click()

dw.py文件find_elements方法應用

import random
from time import sleep
from devices import dv
from tool.assertion import element_existence, element_info_existence, element_text_existence
from tool.dw import find_elements'''這些是通過觀察元素屬性觀察得出的結論,這些是通用值'''
def tu(number):'''家人時光每個圖片定位'''tu = dv.xpath(f'//*[@resource-id="com.visteon.txzing.familytime:id/recycler_view"]/android.view.ViewGroup[{number}]/android.widget.ImageView[1]')return tu# 設為按鈕
set_as = dv(text='設為')
# 設置壁紙
set_wallpaper = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]')
# 設置屏保
set_screensaver = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]')
# 設為按鈕
confirm = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]')
# 取消按鈕
cancel = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_cancel"]')
def set_s_w():dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')dv.app_start('com.xxxxxxx.xxxxxxx.familytime')find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/recycler_view"]/android.view.ViewGroup[1]/android.widget.ImageView[1]','xpath', '照片設置為屏保壁紙', '點擊照片進入詳情').click()find_elements(dv, '設為','text', '照片設置為屏保壁紙', '點擊設為按鈕').click()find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]','xpath', '照片設置為屏保壁紙', '勾選壁紙').click()find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]','xpath', '照片設置為屏保壁紙', '勾選屏保').click()find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]','xpath', '照片設置為屏保壁紙', '進行設置').click()# 多個斷言處理ass_1 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath','壁紙、屏保設置成功','照片設置為屏保壁紙斷言1')ass_2 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_label"]', 'xpath','壁紙 屏保','照片設置為屏保壁紙斷言2')ass_list = [ass_1, ass_2]for i in ass_list:if not i:print(f'斷言{i}失敗')return Falsereturn Truedef cancel_s_w():dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')dv.app_start('com.xxxxxxx.xxxxxxx.familytime')find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/recycler_view"]/android.view.ViewGroup[1]/android.widget.ImageView[1]','xpath', '照片取消為屏保壁紙', '點擊照片進入詳情').click()find_elements(dv, '設為', 'text', '照片取消為屏保壁紙', '點擊設為按鈕').click()find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]','xpath', '照片取消為屏保壁紙', '取消勾選壁紙').click()find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]','xpath', '照片取消為屏保壁紙', '取消勾選屏保').click()find_elements(dv,'//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]','xpath', '照片取消為屏保壁紙', '進行設置').click()return element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath','壁紙、屏保取消成功','照片取消為屏保壁紙')

conftest.py文件

import pytest
from uiautomator2 import UiObjectNotFoundError
from tool.screenshot import capture_screenshot
@pytest.fixture(scope='function',autouse=True)
#autouse=True這將使該 fixture 在每個測試用例中自動執行,而無需顯式地添加裝飾器或參數
def zx(request):print('開始')print(f'用例信息{request}')yieldprint('結束')# def pytest_runtest_protocol(item, nextitem):
#     reports = yield
#     for report in reports:
#         if report.when == "call" and report.failed:
#             # 檢查是否是 UiObjectNotFoundError 異常
#             if isinstance(report.longrepr, UiObjectNotFoundError):
#                 # 獲取異常信息
#                 err_info = str(report.longrepr)
#
#                 # 調用截圖方法
#                 capture_screenshot(err_info)

截圖效果
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/207392.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/207392.shtml
英文地址,請注明出處:http://en.pswp.cn/news/207392.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS特效025:旋轉的loading狀態

CSS常用示例100專欄目錄 本專欄記錄的是經常使用的CSS示例與技巧,主要包含CSS布局,CSS特效,CSS花邊信息三部分內容。其中CSS布局主要是列出一些常用的CSS布局信息點,CSS特效主要是一些動畫示例,CSS花邊是描述了一些CSS…

Ubuntu 修改當前用戶的名稱

UBUNTU 2018.04 LTS 64位 修改當前用戶的名稱 操作步驟如下: 假設你的帳號AAA , 打算修改為BBB。開機進入桌面。按下ctrl alt F1~F7 三個組合鍵。功能鍵F1到F7任選1個。 進入黑屏。登陸root 用戶,進入后。修改以下三個文件 /etc/passwd&a…

Linux學習筆記(九)MISC設備驅動

前言 misc 的意思是混合、雜項的,因此 MISC 驅動也叫做雜項驅動。也就是當我們板子上的某些外設無法進行分類的時候就可以使用 MISC 驅動。 MISC 驅動其實就是最簡單的字符設備驅動,通常嵌套在 platform 總線驅動中,實現復雜的驅動&#xff0…

Mysql 索引概念回顧

一、什么是索引 在關系數據庫中,索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單。索引的作用相當于圖書的目錄,可以根據…

《算法競賽進階指南》------圖論篇

文章目錄 0x01 Telephone Lines POJ - 36620x02 P1073 [NOIP2009 提高組] 最優貿易0x03 道路和航線 BZOJ22000x04 Sorting It All Out POJ - 1094 topo0x05 Sightseeing trip POJ - 1734 最小環問題0x06 Cow Relays POJ - 3613 S到E經過k條邊的最短路0x07 走廊潑水節 &#xff…

為什么Java程序員需要掌握多線程?揭秘并發編程的奧秘

為什么Java程序員需要掌握多線程?揭秘并發編程的奧秘 個人簡介前言多線程對于Java的意義📌1.提高程序性能:📌2 提高用戶體驗:📌3支持并發處理:📌4 資源共享和同步:&#…

OpenSSL 編程示例

參考:深入探索 OpenSSL:概念、原理、開發步驟、使用方法、使用場景及代碼示例 地址:https://oneisall.blog.csdn.net/article/details/131489812?spm1001.2014.3001.5502 目錄 1. OpenSSL 概念2. OpenSSL 原理3. OpenSSL 開發步驟4. OpenSSL…

C# 語法筆記

1.ref、out:參數傳遞的兩種方式 ref:引用傳遞 using System; namespace CalculatorApplication {class NumberManipulator{public void swap(ref int x, ref int y){int temp;temp x; /* 保存 x 的值 */x y; /* 把 y 賦值給 x */y temp; /* 把 t…

Python中的range()函數詳解:掌握迭代的利器

更多資料獲取 📚 個人網站:ipengtao.com Python中的range()函數是一個強大的工具,用于生成一系列的數字,常用于循環操作。雖然看似簡單,但其靈活性和功能卻不容小覷。在本文中,將深入研究range()函數&…

9. 從零用Rust編寫正反向代理, HTTP2改造篇之HPACK示例, 了解http2頭信息如何處理

wmproxy wmproxy是由Rust編寫,已實現http/https代理,socks5代理, 反向代理,靜態文件服務器,內網穿透,配置熱更新等, 后續將實現websocket代理等,同時會將實現過程分享出來&#xff…

vue3,元素可拖拽,自定義指令,鼠標以及手指事件的寫法不一樣

使用很簡單&#xff0c;直接 <div v-drag><div class"header"></div><div class"content"></div> </div>// 自定義指令 —— 拖動div const vDrag {// 在綁定元素的父組件// 及他自己的所有子節點都掛載完成后調用m…

docker容器_自定義上傳jenkins鏡像(Dockerfile實現)

1.創建jenkins目錄&#xff0c;并上傳相應的包 mkdir /jenkins/ 2.創建一個Dockerfile文件 FROM daocloud.io/library/centos:7#把當前目錄下的jenkins.war包傳到內部容器的/ 下 ADD ./jenkins.war /#把當前目錄下的jdk傳到內部容器的/opt/,并解壓 ADD ./jdk-11.0.19_linu…

程序解釋與編譯

?1.程序的解釋執行方式 程序語言強寫的計策機指令序列稱為“源程序”,計算機并不能直接執行用高級語言編寫的源程序&#xff0c;源程序必須通過“翻譯程序”翻譯成機器指令的形式&#xff0c;計算機才能項別和執行。源程序的翻譯有兩種方式&#xff1a;解釋執行和編譯執行。不…

網絡編程基礎api

1. IP 協議 1.1 IP 分片 &#xff08;1&#xff09;IP 分片和重組主要依靠 IP 頭部三個字段&#xff1a;數據報標識、標志和片偏移 以太網幀的 MTU 是 1500 字節&#xff1b; 一個每個分片都有自己的 IP 頭部&#xff0c;它們都具有相同的標識值&#xff0c;有不同的片偏移…

css 十字分割線(含四等分布局)

核心技術 偽類選擇器含義li:nth-child(2)第2個 lili:nth-child(n)所有的lili:nth-child(2n)所有的第偶數個 lili:nth-child(2n1)所有的第奇數個 lili:nth-child(-n5)前5個 lili:nth-last-child(-n5)最后5個 lili:nth-child(7n)選中7的倍數 border-right: 3px solid white;borde…

EasyExcel-最簡單的讀寫excel工具類

前言&#xff1a; easyExcel 的官網文檔給的示例非常全&#xff0c;可以參考https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read 在此我貼出自己的工具類&#xff0c;可以直接用 導包 <dependency><groupId>com.alibaba</groupId><…

機器學習第15天:GBDT模型

??主頁 Nowl &#x1f525;專欄《機器學習實戰》 《機器學習》 &#x1f4d1;君子坐而論道&#xff0c;少年起而行之 ?? 文章目錄 GBDT模型介紹 Boosting 殘差 GBDT的缺點 python代碼實現 代碼 模型參數解釋 結語 GBDT模型介紹 GBDT&#xff08;Gradient Boos…

vivado $clog2函數

對于.v文件在vivado中是不支持&#xff0c;但是可以修改為.sv或更改文件屬性使用sytemverilog來支持。 /*** Math function: $clog2 as specified in Verilog-2005** clog2 0 for value 0* ceil(log2(value)) for value > 1** This implementatio…

php+mysql期末作業小項目

目錄 1、登錄界面 2、注冊界面 3、主界面 4、學生表界面 5 、查詢學生界面?編輯 6、修改學生信息界面?編輯 7、刪除學生信息界面 8、添加學生信息界面 9、后臺數據庫?編輯 一個簡單的php?mysql項目學生信息管理系統&#xff0c;用于廣大學子完成期末作業的參考&…

測試架構工程師需要具備哪些能力 ?

前言 相比于我們常見的研發架構師&#xff0c;測試架構師是近幾年才出現的一個崗位&#xff0c;當然崗位title其實沒有特殊的含義&#xff0c;在我看來測試架構師其實更像對某一類人的抽象稱呼和對其復合能力的期待及認可。 在聊這篇文章的主題之前&#xff0c;先來看這樣一個…