Python+Selenium+Pytest+POM自動化測試框架封裝

🍅?點擊文末小卡片?,免費獲取軟件測試全套資料,資料在手,漲薪更快??

1、測試框架簡介

1)測試框架的優點

  • 代碼復用率高,如果不使用框架的話,代碼會顯得很冗余。
  • 可以組裝日志、報告、郵件等一些高級功能。
  • 提高元素等數據的可維護性,元素發生變化時,只需要更新一下配置文件。
  • 使用更靈活的PageObject設計模式。

2)測試框架的整體目錄

【注意】 init.py 文件用以標識此目錄為一個python包。

2、首先時間管理

首先,因為很多的模塊都會用到當前時間的時間戳,或者日期等等字符串,所以先單獨把時間操作(我們需要獲取的不同格式的時間信息)封裝成一個模塊。

然后讓其他模塊來調用即可。在 utils 目錄新建 times.py 模塊。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import time
import datetime
from functools import wrapsdef timestamp():"""時間戳"""return time.time()def dt_strftime(fmt="%Y%m"):"""datetime格式化時間:param fmt "%Y%m%d %H%M%S"""return datetime.datetime.now().strftime(fmt)def sleep(seconds=1.0):"""睡眠時間"""time.sleep(seconds)def running_time(func):"""函數運行時間"""@wraps(func)def wrapper(*args, **kwargs):start = timestamp()res = func(*args, **kwargs)print("校驗元素done!用時%.3f秒!" % (timestamp() - start))return resreturn wrapperif __name__ == '__main__':print(dt_strftime("%Y%m%d%H%M%S"))

3、添加配置文件

1)conf.py

UI自動化測試框架中應該有一個文件對整體的目錄進行管理;

在項目中的 config 目錄創建 conf.py 文件,所有的目錄配置信息寫在這個文件里面。

import os
from selenium.webdriver.common.by import By
from utils.times import dt_strftimeclass ConfigManager(object):# 項目目錄BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 頁面元素目錄ELEMENT_PATH = os.path.join(BASE_DIR, 'page_element')# 報告文件REPORT_FILE = os.path.join(BASE_DIR, 'report.html')# 元素定位的類型LOCATE_MODE = {'css': By.CSS_SELECTOR,'xpath': By.XPATH,'name': By.NAME,'id': By.ID,'class': By.CLASS_NAME}# 郵件信息EMAIL_INFO = {'username': 'xxxxxxx@qq.com',  # 切換成你自己的地址'password': 'QQ郵箱授權碼','smtp_host': 'smtp.qq.com','smtp_port': 465}# 收件人ADDRESSEE = ['xxxxxxxx@qq.com',]@propertydef log_file(self):"""日志目錄"""log_dir = os.path.join(self.BASE_DIR, 'logs')if not os.path.exists(log_dir):os.makedirs(log_dir)return os.path.join(log_dir, '{}.log'.format(dt_strftime()))@propertydef ini_file(self):"""配置文件"""ini_file = os.path.join(self.BASE_DIR, 'config', 'config.ini')if not os.path.exists(ini_file):raise FileNotFoundError("配置文件%s不存在!" % ini_file)return ini_filecm = ConfigManager()
if __name__ == '__main__':print(cm.BASE_DIR)

【注意】:QQ郵箱授權碼:點擊查看生成教程

2)config.ini

在項目 config 目錄新建一個 config.ini 文件,里面暫時先放入需要測試的URL。

[HOST]
HOST = https://www.baidu.com

3)讀取配置文件

①配置文件創建好了,接下來我們需要讀取這個配置文件以使用里面的信息。
②使用python內置的 configparser 模塊對 config.ini 文件信息進行了讀取。
③對于測試url值的提取,使用python高階語法 @property 屬性值,寫法更簡單。
④在 common 目錄中新建一個 readconfig.py 文件。

import configparser
from config.conf import cmHOST = 'HOST'class ReadConfig(object):"""配置文件"""def __init__(self):self.config = configparser.RawConfigParser()  # 當有%的符號時請使用Raw讀取self.config.read(cm.ini_file, encoding='utf-8')def _get(self, section, option):"""獲取"""return self.config.get(section, option)def _set(self, section, option, value):"""更新"""self.config.set(section, option, value)with open(cm.ini_file, 'w') as f:self.config.write(f)@propertydef url(self):return self._get(HOST, HOST)ini = ReadConfig()if __name__ == '__main__':print(ini.url)

4、記錄操作日志

在 utils 目錄中新建 logger.py 文件。

import logging
from config.conf import cmclass Log:def __init__(self):self.logger = logging.getLogger()if not self.logger.handlers:self.logger.setLevel(logging.DEBUG)# 創建一個handle寫入文件fh = logging.FileHandler(cm.log_file, encoding='utf-8')fh.setLevel(logging.INFO)# 創建一個handle輸出到控制臺ch = logging.StreamHandler()ch.setLevel(logging.INFO)# 定義輸出的格式formatter = logging.Formatter(self.fmt)fh.setFormatter(formatter)ch.setFormatter(formatter)# 添加到handleself.logger.addHandler(fh)self.logger.addHandler(ch)@propertydef fmt(self):return '%(levelname)s\t%(asctime)s\t[%(filename)s:%(lineno)d]\t%(message)s'log = Log().loggerif __name__ == '__main__':log.info('hello world')

5、項目中元素相關

POM模型:PO模式詳解

元素定位:①selenium UI自動化測試xpath定位詳解 ;②selenium UI自動化測試之CSS元素定位語法詳解

6、管理頁面元素

1)新建page_element目錄并在該目錄下新建search.yaml文件

①本教程選擇的測試地址是百度首頁,所以對應的元素也是百度首頁的。
②項目框架設計中有一個page_element 目錄就是專門來存放定位元素的文件的。
③通過對各種配置文件的對比,我在這里選擇的是YAML文件格式。其易讀,交互性好。
④在 page_element 中新建一個 search.yaml 文件。文件內容如下:

搜索框:"id==kw"
候選:"css==.bdsug-overflow"
搜索候選:"css==#form div li"
搜索按鈕:"id==su"

2)在common目錄中創建readelement.py文件。

①在 common 目錄中創建 readelement.py 文件。實現了定位元素的存儲和調用。文件內容如下:

②通過特殊方法 getitem 實現調用任意屬性,讀取yaml中的值。參考博客:python之__getitem__ 方法學習與使用 || python方法下劃線命名規則

import os
import yaml
from config.conf import cmclass Element(object):"""獲取元素"""def __init__(self, name):self.file_name = '%s.yaml' % nameself.element_path = os.path.join(cm.ELEMENT_PATH, self.file_name)if not os.path.exists(self.element_path):raise FileNotFoundError("%s 文件不存在!" % self.element_path)with open(self.element_path, encoding='utf-8') as f:self.data = yaml.safe_load(f)def __getitem__(self, item):"""獲取屬性"""data = self.data.get(item)if data:name, value = data.split('==')return name, valueraise ArithmeticError("{}中不存在關鍵字:{}".format(self.file_name, item))if __name__ == '__main__':search = Element('search')print(search['搜索框'])

3)新建script腳本文件目錄并新建inspect.py文件

在 script 腳本文件目錄中創建 inspect.py 文件,對所有的元素yaml文件內容進行審查。

import os
import yaml
from config.conf import cm
from utils.times import running_time@running_time
def inspect_element():"""檢查所有的元素是否正確只能做一個簡單的檢查"""for files in os.listdir(cm.ELEMENT_PATH):_path = os.path.join(cm.ELEMENT_PATH, files)with open(_path, encoding='utf-8') as f:data = yaml.safe_load(f)for k in data.values():try:pattern, value = k.split('==')except ValueError:raise Exception("元素表達式中沒有`==`")if pattern not in cm.LOCATE_MODE:raise Exception('%s中元素【%s】沒有指定類型' % (_path, k))elif pattern == 'xpath':assert '//' in value,\'%s中元素【%s】xpath類型與值不配' % (_path, k)elif pattern == 'css':assert '//' not in value, \'%s中元素【%s]css類型與值不配' % (_path, k)else:assert value, '%s中元素【%s】類型與值不匹配' % (_path, k)if __name__ == '__main__':inspect_element()

7、封裝Selenium基類

①工廠模式的寫法:很直白,簡單,又明了。

【創建driver對象,打開百度網頁,搜索selenium,點擊搜索,然后停留5秒,查看結果,最后關閉瀏覽器。】

import time
from selenium import webdriverdriver = webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.find_element_by_xpath("//input[@id='kw']").send_keys('selenium')
driver.find_element_by_xpath("//input[@id='su']").click()
time.sleep(5)
driver.quit()

②那為什么要封裝selenium的方法呢?

首先我們上述這種較為原始的方法,基本不適用于平時做UI自動化測試的:因為在UI界面實際運行情況遠遠比較復雜,可能因為網絡原因,或者控件原因,我們元素還沒有顯示出來,就進行點擊或者輸入。

所以我們需要封裝selenium方法,通過內置的顯式等待或一定的條件語句,才能構建一個穩定的方法。而且把selenium方法封裝起來,有利于平時的代碼維護。

新建page目錄并創建webpage.py文件

①在 page 目錄創建 webpage.py 文件。文件內容如下:

②在文件中我們對主要用了顯示等待對selenium的 click , send_keys 等方法,做了二次封裝。提高了運行的成功率。

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutExceptionfrom config.conf import cm
from utils.times import sleep
from utils.logger import log"""
selenium基類
本文件存放了selenium基類的封裝方法
"""class WebPage(object):"""selenium基類"""def __init__(self, driver):# self.driver = webdriver.Chrome()self.driver = driverself.timeout = 20self.wait = WebDriverWait(self.driver, self.timeout)def get_url(self, url):"""打開網址并驗證"""self.driver.maximize_window()self.driver.set_page_load_timeout(60)try:self.driver.get(url)self.driver.implicitly_wait(10)log.info("打開網頁:%s" % url)except TimeoutException:raise TimeoutException("打開%s超時請檢查網絡或網址服務器" % url)@staticmethoddef element_locator(func, locator):"""元素定位器"""name, value = locatorreturn func(cm.LOCATE_MODE[name], value)def find_element(self, locator):"""尋找單個元素"""return WebPage.element_locator(lambda *args: self.wait.until(EC.presence_of_element_located(args)), locator)def find_elements(self, locator):"""查找多個相同的元素"""return WebPage.element_locator(lambda *args: self.wait.until(EC.presence_of_all_elements_located(args)), locator)def elements_num(self, locator):"""獲取相同元素的個數"""number = len(self.find_elements(locator))log.info("相同元素:{}".format((locator, number)))return numberdef input_text(self, locator, txt):"""輸入(輸入前先清空)"""sleep(0.5)ele = self.find_element(locator)ele.clear()ele.send_keys(txt)log.info("輸入文本:{}".format(txt))def is_click(self, locator):"""點擊"""self.find_element(locator).click()sleep()log.info("點擊元素:{}".format(locator))def element_text(self, locator):"""獲取當前的text"""_text = self.find_element(locator).textlog.info("獲取文本:{}".format(_text))return _text@propertydef get_source(self):"""獲取頁面源代碼"""return self.driver.page_sourcedef refresh(self):"""刷新頁面F5"""self.driver.refresh()self.driver.implicitly_wait(30)

8、創建頁面對象

新建page_object目錄并創建一個searchpage.py文件

①在 page_object 目錄下創建一個 searchpage.py 文件。

②在該文件中我們對,輸入搜索關鍵詞,點擊搜索,搜索聯想,進行了封裝。【在平時中我們應該養成寫注釋的習慣,因為過一段時間后,沒有注釋,代碼讀起來很費勁。】

9、應用pytest測試框架

pytest.ini文件創建

①pytest項目中的配置文件,可以對pytest執行過程中操作做全局控制。
②在項目根目錄新建 pytest.ini 文件。文件內容如下:

[pytest]
addopts = --html=report.html --self-contained-html

③addopts 指定執行時的其他參數說明:

  • –html=report/report.html --self-contained-html 生成pytest-html帶樣式的報告
  • -s 輸出我們用例中的調式信息
  • -q 安靜的進行測試
  • -v 可以輸出用例更加詳細的執行信息,比如用例所在的文件及用例名稱等

10、編寫測試用例

新建TestCase目錄并創建test_search.py文件

①在 TestCase 目錄中創建 test_search.py 文件。文件內容如下:
② pytest.fixture裝飾器實現了和unittest的setup,teardown一樣的前置啟動,后置清理的裝飾器。

③第一個測試用例:實現了在百度搜索selenium關鍵字,并點擊搜索按鈕,并在搜索結果中,用正則查找結果頁源代碼,返回數量大于10我們就認為通過。

④第二個測試用例:實現了百度搜索selenium關鍵字,然后斷言搜索候選中的所有結果有沒有selenium關鍵字。

import re
import pytest
from utils.logger import log
from common.readconfig import ini
from page_object.searchpage import SearchPageclass TestSearch:@pytest.fixture(scope='function', autouse=True)def open_baidu(self, drivers):"""打開百度"""search = SearchPage(drivers)search.get_url(ini.url)def test_001(self, drivers):"""搜索"""search = SearchPage(drivers)search.input_search("selenium")search.click_search()result = re.search(r'selenium', search.get_source)log.info(result)assert resultdef test_002(self, drivers):"""測試搜索候選"""search = SearchPage(drivers)search.input_search("selenium")log.info(list(search.imagine))assert all(["selenium" in i for i in search.imagine])if __name__ == '__main__':pytest.main(['TestCase/test_search.py'])

conftest.py

①在項目根目錄下新建一個 conftest.py 文件。

②conftest.py是測試框架pytest的膠水文件,里面用到了fixture函數,封裝并傳遞出了driver。

import pytest
from py.xml import html
from selenium import webdriverdriver = None@pytest.fixture(scope='session', autouse=True)
def drivers(request):""":param request: python內置的fixture函數,本函數中用來注冊終結函數:return: 返回driver實例"""global driverif driver is None:driver = webdriver.Chrome()driver.maximize_window()def fn():driver.quit()request.addfinalizer(fn)return driver@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):"""當測試失敗的時候,自動截圖,展示到html報告中:param item:"""pytest_html = item.config.pluginmanager.getplugin('html')outcome = yieldreport = outcome.get_result()report.description = str(item.function.__doc__)extra = getattr(report, 'extra', [])if report.when == 'call' or report.when == "setup":xfail = hasattr(report, 'wasxfail')if (report.skipped and xfail) or (report.failed and not xfail):file_name = report.nodeid.replace("::", "_") + ".png"screen_img = _capture_screenshot()if file_name:html = '<div><img src="data:image/png;base64,%s" alt="screenshot" style="width:1024px;height:768px;" ' \'οnclick="window.open(this.src)" align="right"/></div>' % screen_imgextra.append(pytest_html.extras.html(html))report.extra = extradef pytest_html_results_table_header(cells):cells.insert(1, html.th('用例名稱'))cells.insert(2, html.th('Test_nodeid'))cells.pop(2)def pytest_html_results_table_row(report, cells):cells.insert(1, html.td(report.description))cells.insert(2, html.td(report.nodeid))cells.pop(2)def pytest_html_results_table_html(report, data):if report.passed:del data[:]data.append(html.div('通過的用例未捕獲日志輸出.', class_='empty log'))def _capture_screenshot():'''截圖保存為base64:return:'''return driver.get_screenshot_as_base64()

11、發送郵件

①當項目執行完成之后,需要發送到自己或者其他人郵箱里查看結果。
②編寫發送郵件的模塊。
③在 utils 目錄中新建 send_mail.py 文件,文件內容如下:

import zmail
from config.conf import cmdef send_report():"""發送報告"""with open(cm.REPORT_FILE, encoding='utf-8') as f:content_html = f.read()try:mail = {'from': 'xxxxxx@qq.com','subject': '最新的測試報告郵件','content_html': content_html,'attachments': [cm.REPORT_FILE, ]}server = zmail.server(*cm.EMAIL_INFO.values())server.send_mail(cm.ADDRESSEE, mail)print("測試郵件發送成功!")except Exception as e:print("Error: 無法發送郵件,{}!", format(e))if __name__ == "__main__":'''請先在config/conf.py文件設置QQ郵箱的賬號和密碼'''send_report()

④在 config/conf.py 文件中設置我們自己的QQ郵箱賬號以及QQ郵箱授權碼。運行 send_report() 函數。

最后感謝每一個認真閱讀我文章的人,禮尚往來總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走:

這些資料,對于做【軟件測試】的朋友來說應該是最全面最完整的備戰倉庫,這個倉庫也陪伴我走過了最艱難的路程,希望也能幫助到你!凡事要趁早,特別是技術行業,一定要提升技術功底。

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

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

相關文章

宋代大模型:智能重構下的文明再發現

引言&#xff1a;當汴京城遇見生成式AI 一幅動態的《清明上河圖》正通過全息投影技術演繹汴京城的市井百態。這個虛實交融的場景&#xff0c;恰似宋代大模型技術的隱喻——以人工智能為紐帶&#xff0c;連接起東京夢華的繁盛圖景與數字時代的文明重構。作為人工智能與歷史學交…

K-means++:讓K-means“聰明”地選擇初始中心點

大家好&#xff01;歡迎來到我的技術分享博客~ &#x1f44b; 在前兩篇博客中&#xff0c;我們深入探討了經典的 K-means 算法 以及它的優化方案 Canopy K-means。如果你還沒有看過&#xff0c;強烈建議先回顧一下&#xff0c;因為今天的主題 K-means 和它們有著千絲萬縷的聯系…

Langchain學習筆記(1)——如何調用Huggingface的模型并實現實時返回生成結果

Langchain支持很方便的OpenAI模型的調用&#xff0c;可以做到快速開發大模型應用。但是要使用Huggingface上的開源模型就沒有那么方便了&#xff0c;本文就詳細闡述如何用Langchain開發基于Huggingface上的模型&#xff0c;并實時返回生成結果。 實時返回生成結果是LLM很關鍵的…

Java安全-常規漏洞問題(SQL注入,XXE,SSRF,RCE)

靶場搭建 靶場下載 &#xff1a; https://github.com/whgojp/JavaSecLab這個靶場是使用Springboot搭建的所以不要下載 jar 文件運行&#xff0c;要使用IDEA運行他的文件夾 先打開pom 然后進行maven一下 改一下端口 配置完成之后修改一下 運行的模式 使用phpstudy搞一個sql數…

基于視頻的 AI 內存庫,極速語義檢索

簡介 在大模型應用里&#xff0c;將文本數據分塊嵌入存儲在向量數據庫已經是標準做法。然而&#xff0c;傳統向量數據庫雖然功能強大&#xff0c;但其高昂的RAM和存儲需求&#xff0c;以及復雜的部署運維&#xff0c;常常讓開發者望而卻步。今天&#xff0c;介紹一個名為 Memv…

接口適配器模式實現令牌桶算法和漏桶算法

以下是令牌桶算法、漏桶算法和雪花算法的清晰對比解析。它們屬于完全不同的技術領域&#xff0c;前兩者用于流量控制&#xff0c;后者用于分布式ID生成&#xff1a; 1. 令牌桶算法&#xff08;Token Bucket&#xff09; 領域&#xff1a;流量整形 / 速率限制核心目標&#xff…

618背后的電商邏輯重構:從價格血戰到價值共生

“今年終于沒做數學題。” 618進行到一半&#xff0c;行云已經買了很多&#xff0c;大件的有iPad、iWatch&#xff0c;小件的有運動鞋、面膜、紙巾。往年她要湊湊減減&#xff0c;經常要找個店鋪湊單&#xff0c;下完單再馬上退掉&#xff0c;今年她沒廢太多腦細胞&#xff0c…

解決 PyTorch 與 Python 3.12 的兼容性問題:`operator torchvision::nms does not exist` 深度解析

解決 PyTorch 與 Python 3.12 的兼容性問題 問題現象錯誤根源分析終極解決方案?? 推薦方案:創建 Python 3.11 虛擬環境? 備選方案:使用 PyTorch 夜間構建版(Python 3.12)驗證修復技術深度解析最佳實踐建議問題現象 當在 Python 3.12 環境中運行以下代碼時: from tran…

Git 實戰場景

四、標簽管理 4.1、標簽的理解 在使用 Git 進行版本管理時&#xff0c;**標簽&#xff08;Tag&#xff09;**扮演著非常重要的角色。它其實就是對某次提交&#xff08;commit&#xff09;的一個簡潔標識&#xff0c;相當于給這次提交起了一個可讀、易記的“別名”。比如&…

在同態加密系統中,參與角色以及各角色的功能作用流程圖,私鑰和公鑰分發流程,可能遇到的攻擊

一、角色劃分與職責 角色身份核心任務密鑰權限客戶端數據所有者 &#xff08;如醫院、用戶&#xff09;1. 加密原始數據 2. 上傳密文至服務器 3. 接收并解密結果&#xff08;可選&#xff09;持有公鑰服務器計算服務提供方 &#xff08;如云平臺&#xff09;1. 接收客戶端密文…

langchain從入門到精通(六)——LCEL 表達式與 Runnable 可運行協議

1. 多組件 invoke 嵌套的缺點 prompt ChatPromptTemplate.from_template("{query}") llm ChatOpenAI(model"gpt-3.5-turbo-16k") parser StrOutputParser() # 獲取輸出內容 content parser.invoke( llm.invoke( prompt.invoke( {"query": r…

ArcGIS中批量獲取輸入面圖層A中各要素的四至點的實現方法

一、背景及意義 在日常工作中&#xff0c;我們經常會需要獲取面圖層的四至點&#xff0c;我們能否在ArcGIS中直接獲取面圖層的四至點呢&#xff1f;答案是肯定的&#xff0c;請繼續往下看。 二、大體思路 使用字段計算器計算輸入面圖層A中各面要素的XY的最大值和最小值&…

大IPD之——華為的戰略本質與實踐(二)

華為戰略執行的能力如此強&#xff0c;有兩個核心原因&#xff1a;一是管理體系起了非常重大的作用&#xff1b;二是企業文化導致華為的執行力特別強。華為在戰略方面&#xff0c;為什么每次都能轉型成功&#xff1f;背后是有很多實質性的內容支撐的。而華為如何做戰略&#xf…

『大模型筆記』第3篇:多長的 Prompt 會阻塞其他請求?優化策略解析

『大模型筆記』多長的 Prompt 會阻塞其他請求?優化策略解析 文章目錄 一、更簡單的問題:長 Prompt 阻塞請求隊列1. 請求并行預填方案(Request-Parallel Prefills)二、根本的問題(Fundamental Flaw):Token 生成被并行預填拖慢1. 解耦預填(Disaggregated Prefill):以延遲優…

21 - GAM模塊

論文《Global Attention Mechanism: Retain Information to Enhance Channel-Spatial Interactions》 1、作用 這篇論文提出了全局注意力機制&#xff08;Global Attention Mechanism, GAM&#xff09;&#xff0c;旨在通過保留通道和空間方面的信息來增強跨維度交互&#xf…

Java01--使用IDEA編寫運行第一個Java程序HelloWorld

一.先新建一個文件夾存放項目(后續可以推送到Gitee) 二.創建項目 1.打開IDEA&#xff0c;點擊首頁的新建項目 2.新建空項目并命名&#xff0c;存放路徑為步驟一創建的文件夾&#xff1a; 3.在新項目中新建一個src文件夾&#xff08;用于集中管理文件&#xff09; 4.在src文件夾…

目標檢測相關【清晰易懂】

目標檢測相關 &#xff08;b&#xff09;是語義分割&#xff0c;&#xff08;c&#xff09;是實例分割 目標檢測 每個目標一個框標簽 實例分割 語義分割 識別每一個目標個體 目標檢測基礎上進一步提升模型能力有兩個方向&#xff1a;實例分割、旋轉目標檢測。 實例分割 …

強化學習 A2C算法

3.actor-critic方法 3.1 Reinforce 算法&#xff0c;也稱為蒙特卡洛策略梯度。蒙特卡洛方差 第一節介紹了DQN 在上一節基于策略的方法中&#xff0c;我們的目標是直接優化策略&#xff0c;而無需使用價值函數。更準確地說&#xff0c;Reinforce 是 基于策略的方法 的一個子類…

關于MCU、MPU、SoC、DSP四大類型芯片

目錄 MCU、MPU、SoC、DSP四大類型芯片分析 一、MCU 1、概念 2、特點 3、常見芯片 4、應用場景 二、MPU 1、概念 2、特點 3、常見芯片 4、應用場景 三、SoC 1、概念 2、特點 3、常見芯片 4、應用場景 四、DSP 1、概念 2、特點 3、常見芯片 4、應用場景 MCU、…

【數據結構】圖論最短路圣器:Floyd算法如何用雙矩陣征服負權圖?

最短路徑 穿越負權迷霧&#xff1a;Floyd算法如何解鎖全圖最短路徑&#xff1f;??一、Floyd算法1.1 算法思想1.2 算法邏輯1.3 算法評價1.4 算法限制 二、三種算法對比&#x1f31f;結語 穿越負權迷霧&#xff1a;Floyd算法如何解鎖全圖最短路徑&#xff1f;?? 大家好&…