自動化測試實戰 - 博客系統自動化測試

目錄

1. 前言

2. 自動化實施步驟

3. 頁面分析

4. 設計測試用例

5. 搭建自動化環境

6. 編寫自動化代碼

6.1 準備工作 - Utils

6.1.1 允許遠程自動化 & 創建驅動

6.1.2?實現自動化截圖

?6.1.3?釋放 WebDriver

6.2 自動化測試登錄頁 - LoginTest

6.2.1 打開登陸頁

6.2.2?檢查登錄頁

6.2.3 測試登陸

6.2.3.1 登錄成功

6.2.3.2 登錄失敗

6.3 自動化測試列表頁 - ListPage

6.4 自動化測試詳情頁 - ?DetailPage

6.4.1 測試頁面內容

6.4.2 測試編輯按鈕功能

6.4.3 測試刪除按鈕功能

6.5 自動化測試編輯頁(發布博客) - EditPage


1. 前言

前段時間, 我們學習了 WebDriver 和 selenium, 并且掌握了自動化測試的核心函數.

此外, 我們基于 Spring 完成了博客系統的開發.

因此, 我們就使用自動化技術, 對我們的博客系統進行自動化測試.

2. 自動化實施步驟

  1. 需求分析
  2. 頁面分析
  3. 設計測試用例
  4. 搭建自動化環境
  5. 編寫自動化代碼
  6. 運行維護

設計測試用例時, 我們要根據項目中的頁面來設計對應的測試用例.

3. 頁面分析

博客系統一共分為以下 4 個頁面:

  1. 博客登錄頁
  2. 博客列表頁
  3. 博客詳情頁
  4. 博客發布(編輯)頁

我們需要對這些頁面來設計測試用例.

4. 設計測試用例

在編寫自動化代碼前, 需要先設計測試用例.

我們基于萬能公式設計測試用例:?

功能測試 + 性能測試 + 界面測試 + 兼容性測試 + 易用性測試 + 安全測試 (+ 弱網測試 + 安裝卸載測試)

除了牢記以上 “萬能公式” 外, 我們還需要充分的了解項目, 這樣才能設計出優秀的測試用例.

設計的測試用例如下:

5. 搭建自動化環境

設計完測試用例后, 需要為后續編寫自動化代碼搭建環境.

我們依賴如下環境:

  1. jdk
  2. idea
  3. selenium
  4. WedDriverManager(驅動管理)
  5. 瀏覽器(正版)

6. 編寫自動化代碼

根據測試用例, 編寫自動化代碼.

6.1 準備工作 - Utils

創建一個 Utils 包, 存放創建 driver, 截圖, 等待等操作的代碼.

6.1.1 允許遠程自動化 & 創建驅動

    public WebDriver createDriver() {if(driver == null) {// 安裝自動化驅動管理程序WebDriverManager.chromedriver().setup();// 瀏覽器配置ChromeOptions options = new ChromeOptions();// 允許來自任何源的遠程連接請求options.addArguments("--remote-allow-origins=*");// 將配置添加到驅動中driver = new ChromeDriver(options);// 隱式等待頁面元素 3 s, 保證代碼執行前, 相關元素已存在.driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));}return driver;}

6.1.2?實現自動化截圖

?以截圖時間為所截圖片的保存路徑.

    /*** 屏幕截圖* String s: 在進行哪個頁面的測試時, 進行的截圖.* 保存路徑: ./src/test/java/com/project/bloguiautotest/images/2025-05-03/15-44-23-23.png*/public static void screenShot(String s) throws IOException {// 年-月-日SimpleDateFormat dirFormat = new SimpleDateFormat("yyyy-MM-dd");// 時.分.秒.毫秒SimpleDateFormat fileFormat = new SimpleDateFormat("hh.mm.ss.SSS");String dirPath = dirFormat.format(System.currentTimeMillis());String filePath = fileFormat.format(System.currentTimeMillis()) + ".png";// 定義圖片保存路徑String picPath = "./src/test/java/com/project/bloguiautotest/images/" + dirPath + "/" + s + "-" + filePath;// 進行截圖, 生成圖片File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);// 將截圖保存在指定路徑下.FileUtils.copyFile(srcFile, new File(picPath));}

?6.1.3?釋放 WebDriver

    /*** 釋放 driver 對象*/public static void exit() {driver.quit();}

6.2 自動化測試登錄頁 - LoginTest

對登錄頁的自動化測試流程如下:

  1. 使用 webDriver 打開登錄頁, 檢查頁面是否打開成功
  2. 針對登陸成功和登陸失敗的情況, 輸入賬號密碼, 檢查是否符合預期?

6.2.1 打開登陸頁

將 LoginTest 繼承 Utils, 將登錄頁的 url 傳給 Utils, driver.get(url) 打開博客登陸頁面.

6.2.2?檢查登錄頁

使用 driver.get 打開登陸頁后, 我們需要檢查是否打開成功.

6.2.3 測試登陸

登陸頁成功打開后, 接下來測試登錄狀態.

6.2.3.1 登錄成功

輸入賬號密碼后, 如果登錄成功, 會跳轉到博客詳情頁.

因此, 我們可以查找詳情頁中的元素, 如果可以查找到, 則說明登陸成功.

博客詳情頁中有很多元素, 這里我選擇的是 “退出登錄” 這個按鈕.

6.2.3.2 登錄失敗

輸入的賬號密碼屬于以下情況任意一種時, 均會登錄失敗:

  1. 賬號為空, 密碼不為空
  2. 賬號不為空, 密碼為空
  3. 賬號和密碼, 都為空
  4. 賬號正確, 密碼錯誤
  5. 賬號錯誤, 密碼正確
  6. 賬號錯誤, 密碼錯誤
  7. 輸入不合法字符

這里演示第 4 種情況.

當輸入密碼錯誤時, 會出現警告彈窗提示, 我們需要關閉彈窗:

注意:

如果對輸入框進行輸入操作(sendKeys), 一定要先清空輸入框(clear)中的內容!!

6.3 自動化測試列表頁 - ListPage

登陸成功后, 來到博客詳情頁.?

博客列表頁中有以下三部分模塊:

  1. 個人信息模塊
  2. 博客列表模塊
  3. 菜單欄模塊

這里就僅對博客列表模塊進行測試:

public class ListPage extends Utils {// 博客列表頁 urlpublic static String url = "http://47.93.87.16:8080/blog_list.html";public ListPage() {super(url);}/*** 測試博客列表頁* 1. 個人信息模塊* 2. 博客列表模塊 ?* 3. 菜單欄模塊*/public void checkList() {// 獲取博客標題String blogTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.title")).getText();// 獲取博客發布日期String blogDate = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.date")).getText();// 獲取博客正文String blogContent = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.desc")).getText();// 獲取 “查看全文>>” 按鈕String button = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).getText();// 博客標題 & 博客發布日期 & 博客正文 均不能為空assert !blogTitle.isEmpty();assert !blogDate.isEmpty();assert !blogContent.isEmpty();// “查看全文>>” 按鈕應符合預期assert button.equals("查看全文>>");// 點擊 “查看全文>>” 按鈕, 應跳轉到博客詳情頁.driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();// 此時, 應來到博客詳情頁. 獲取詳情頁中的標題String jumpTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();// 跳轉后的博客標題, 應和跳轉后的保持一致assert blogTitle.equals(jumpTitle);// 此時已經來到博客詳情頁. 獲取這篇博客詳情頁的 URL.blogDetailURL = driver.getCurrentUrl();
//        System.out.println(blogDetailURL);}
}

6.4 自動化測試詳情頁 - ?DetailPage

6.4.1 測試頁面內容

對博客詳情頁進行測試時, 和登錄頁/列表頁不同的是, 我們不能將一篇博客的詳情頁的?url 寫死到屬性中, 因為這篇博客隨時可能會被刪除, 此時這個 url 就變成了一個不存在的博客的 url.

因此, 我們可以在博客列表頁中獲取某一篇存在的博客, 對這篇博客的詳情頁進行測試.

注意:?由于博客正文內容使用的標簽不固定, 有時是 p 標簽, 有時是 h 標簽(動態標簽), 我們無法為其編寫一個固定的選擇器.

?解決方案是:利用其結構穩定的父元素. 先通過選擇器定位到穩定的父元素, 然后基于此父元素來定位其內部的動態正文內容.

博客正文, 都存在于一個靜態的 div 標簽中, 因此, 我們可以通過定位正文的父類即 div 標簽來間接的定位博客正文.

public class DetailPage extends Utils {// 獲取父類中有效的 urlpublic static String url = blogDetailURL;public DetailPage() {super(url);}/*** 測試詳情頁*/public void checkPage() {// 博客標題driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title"));// 博客發布日期driver.findElement(By.cssSelector("body > div.container > div.right > div > div.date"));// 博客正文// 正文 -》 動態標簽. 解決辦法: 父類標簽是靜態的, 通過父類標簽間接定位到博客正文的標簽.(確定了父類, 就確定了子類)
//        driver.findElement(By.cssSelector("#detail > p"));webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#detail")));driver.findElement(By.cssSelector("#detail")); // 父類 div 標簽// 編輯按鈕// 刪除按鈕// 可能存在, 也可能不存在. 當作者是登陸用戶的時候存在, 因此這里不進行測試.}
}

6.4.2 測試編輯按鈕功能

我們的預期時, 在博客詳情頁點擊 "編輯" 按鈕, 會跳轉到博客編輯頁, 對博客信息進行修改, 點擊 "更新文章" 按鈕, 文章信息隨之發送改變.

我們編寫自動化代碼驗證功能是否正常.

    /*** 檢測博客詳情頁 編輯按鈕 功能*/public void checkDetailEdit() throws InterruptedException {// 獲取修改前的標題String titleBefore = driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();System.out.println("更新前的標題: " + titleBefore);// 查找 "編輯" 按鈕并點擊driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(1)")).click();// 此時跳轉到編輯頁, 更新標題 (首先清空之前的標題)webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#title")));driver.findElement(By.cssSelector("#title")).clear();// 根據當前時間更新標題webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#title")));SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HHmmssSS");String titleTime = simpleDateFormat.format(System.currentTimeMillis());driver.findElement(By.cssSelector("#title")).sendKeys(titleTime);//點擊發布----回到列表頁driver.findElement(By.cssSelector("#submit")).click();// 獲取更新后的標題 body > div.container > div.right > div:nth-child(1) > div.titlewebDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.container > div.right > div > div.title")));String titleAfter = driver.findElement(By.cssSelector("body > div.container > div.right > div > div.title")).getText();System.out.println("更新后的標題: " + titleAfter);// titleBefore != titleAfter 更新前和更新后的標題, 應不一致.assert !titleAfter.equals(titleBefore);}

使斷言 assert 生效需要進行一下配置:

-ea -Dfile.encoding=UTF-8?

6.4.3 測試刪除按鈕功能

定位到博客詳情頁的刪除按鈕后進行點擊, 完成刪除操作.

如何驗證刪除操作成功: 博客列表頁中, 刪除操作前的博客數量應和刪除操作后的博客數量不同.

    /*** 檢測博客詳情頁 刪除按鈕*/public void checkDetailDelete() throws InterruptedException {// 先回到列表頁, 確定刪除前, 一共有多少篇博客driver.get("http://47.93.87.16:8080/blog_list.html");List<WebElement> blogsBefore = driver.findElements(By.cssSelector("body > div.container > div.right > div"));int blogCntBefore = blogsBefore.size();System.out.println("刪除操作前的博客篇數: " + blogCntBefore);// 再次來到博客詳情頁, 定位到刪除按鈕并點擊driver.get(url);driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(2)")).click();// 此時來到博客列表頁, 重新查看共有多少篇博客Thread.sleep(500);List<WebElement> blogsAfter = driver.findElements(By.cssSelector("body > div.container > div.right > div"));int blogCntAfter = blogsAfter.size();System.out.println("刪除操作后的博客篇數: " + blogCntAfter);// 刪除前和刪除后, 列表頁的博客數量應不同assert blogCntBefore != blogCntAfter;}

6.5 自動化測試編輯頁(發布博客) - EditPage

通過 url 來到博客發布頁后, 我們需要填寫博客標題和博客正文.

填寫博客標題時, 我們通過選擇器獲取 xpath 定位到后, 直接通過 sendKeys 就可以自動化填寫.

但是, 填寫博客正文時, 如果我們仍然通過 sendKeys 來填寫內容時, 就會拋出元素不可交互異常:

ElementNotInteractableException?異常通常意味著我們通過 findElement 找到了指定的元素(findElement 成功), 但該元素當前狀態無法接收鍵盤輸入. (例如, 它可能被其他元素遮擋、被禁用、不可見, 或者它本身就不是一個設計用來直接接收輸入的元素, 如: 富文本編輯器)

而接收博客正文的區域, 它恰好是一個文本編輯器, 因此我們無法通過 sendKeys 來輸入內容.

此時, 我們就可以通過鍵盤鼠標操作來對向這個文本編輯器中輸入內容.

鍵盤操作 | Selenium

        // 通過鍵盤鼠標的方式, 來填寫正文WebElement contentEle = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre"));new Actions(driver).doubleClick(contentEle) // 模擬鼠標雙擊操作.keyDown(Keys.DELETE) // 模擬鍵盤刪除操作.doubleClick() // 模擬鼠標雙擊操作.keyDown(Keys.DELETE) // 模擬鍵盤刪除操作.sendKeys("自動化填寫博客正文...") // 輸入內容.perform(); // 將結果展示到頁面上

ok, 自動化輸入完博客正文后, 就可以點擊 "發布博客" 按鈕進行發布了.

那么, 如何自動化測試博客發布成功呢?

點擊發布按鈕后, 此時應來到博客列表頁, 而博客列表頁的最后一篇博客就是我們自動化發布的博客.

那我們就可以獲取列表頁最后一篇博客的標題/內容, 檢查是否和自動化輸入的標題/內容一致, 若一致, 則說明發布成功, 反之發布失敗.

如何獲取選中列表頁最后一篇博客呢? 我們可以采取拼接選擇器/xpath的方式:

/*** 發布博客*/
public class EditPage extends Utils {private static final String url = "http://47.93.87.16:8080/blog_edit.html";public EditPage() {// 調用父類構造, 來到博客發布頁面super(url);}/*** 正常發布博客*/public void editSuccess() {// 1. 填寫博客標題// 根據當前時間自動化生成博客標題webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#title")));SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-HH:mm:ss-SS");String titleTime = simpleDateFormat.format(System.currentTimeMillis());String titleBefore = "自動化發布博客 " + titleTime;driver.findElement(By.cssSelector("#title")).clear();driver.findElement(By.cssSelector("#title")).sendKeys(titleBefore);System.out.println("發布時輸入的博客名稱: " + titleBefore);// 2. 填寫博客正文// 由于正文的輸入框是一個文本編輯器(不可交互), 如果通過 sendKeys 來進行輸入操作, 會拋出異常.
//        // ElementNotInteractableException
//        WebElement contentEle = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre"));
//        contentEle.sendKeys("自動化填寫博客正文...");// 通過鍵盤鼠標的方式, 來填寫正文WebElement contentEle = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre"));new Actions(driver).doubleClick(contentEle) // 模擬鼠標雙擊操作.keyDown(Keys.DELETE) // 模擬鍵盤刪除操作.doubleClick() // 模擬鼠標雙擊操作.keyDown(Keys.DELETE) // 模擬鍵盤刪除操作.sendKeys("自動化填寫博客正文...") // 輸入內容.perform(); // 將結果展示到頁面上// 3. 點擊發布博客driver.findElement(By.cssSelector("#submit")).click();// 4. 校驗博客是否發布成功// 此時來到博客列表頁// 博客列表頁的最后一篇博客, 應是我們新發布的博客, 這篇博客的名稱應和我們發布時輸入的名稱一致// 獲取列表頁的博客列表List<WebElement> blogs = driver.findElements(By.cssSelector("body > div.container > div.right > div"));int size = blogs.size();// 獲取最后一篇博客的名稱String lastBlogTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(" + size + ") > div.title")).getText();System.out.println("發布后的博客名稱: " + lastBlogTitle);assert lastBlogTitle.equals(titleBefore);}
}

END

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

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

相關文章

網絡實驗-VRRP

VRRP協議簡述 VRRP(虛擬路由冗余協議)通過虛擬IP地址&#xff08;VIP&#xff0c;virtual ip&#xff09;來實現冗余。在正常情況下&#xff0c;Master路由器會響應VIP的ARP請求&#xff0c;并處理所有發往VIP的流量。Backup路由器則處于待命狀態&#xff0c;只有在Master路由…

計算機發展的歷程

計算機系統的概述 一, 計算機系統的定義 計算機系統的概念 計算機系統 硬件 軟件 硬件的概念 計算機的實體, 如主機, 外設等 計算機系統的物理基礎 決定了計算機系統的天花板瓶頸 軟件的概念 由具有各類特殊功能的程序組成 決定了把硬件的性能發揮到什么程度 軟件的分類…

JavaScript splice() 方法

1. JavaScript splice() 方法 1.1. 定義和用法 splice() 方法用于添加或刪除數組中的元素。 ??注意&#xff1a;這種方法會改變原始數組。 ??返回值&#xff1a;如果刪除一個元素&#xff0c;則返回一個元素的數組。 如果未刪除任何元素&#xff0c;則返回空數組。 1.2. …

磁盤I/O子系統

一、數據寫入磁盤流程 當執行向磁盤寫入數據操作的時候&#xff0c;會發生如下的一系列基本操作。假設文件數據存在于磁盤扇區上&#xff0c;并且已經被讀入到頁緩存中。 進程使用write()系統調用寫入文件。內核更新映射到文件的page cache。內核線程pdflush負責把頁緩存刷入…

單調棧和單調隊列

一、單調棧 1、使用場景 解決元素左 / 右側第一個比他大 / 小的數字。 2、原理解釋 用棧解決&#xff0c;目標是棧頂存儲答案。 以元素左側第一個比他小為例&#xff1a; &#xff08;1&#xff09;遍歷順序一定是從左向右。 &#xff08;2&#xff09;由于棧頂一定是答…

查看電腦信息的方法-CPU核心數量、線程數量等

1、查看CPU基本信息 step 1: windows下 “winr” 進入CMD step 2: 查看核心數&#xff1a;wmic cpu get NumberofCores 查看線程數&#xff1a;wmic cpu get NumberOfLogicalProcessors 查看CPU名稱&#xff1a;wmic cpu get Name 查看CPU時鐘頻率&#xff1a;wmic cpu get Ma…

令牌桶和漏桶算法使用場景解析

文章目錄 什么時候用令牌桶&#xff0c;什么時候用漏桶算法&#xff1f;&#xff1f;先放結論 兩個算法一眼看懂什么時候選令牌桶&#xff1f;什么時候選漏桶&#xff1f;組合用法&#xff08;90% 的真實系統都會這么干&#xff09;小結記憶 對令牌桶和漏桶組合用法再次詳細敘述…

uniapp|實現獲取手機攝像頭權限,調用相機拍照實現人臉識別相似度對比,拍照保存至相冊,多端兼容(APP/微信小程序)

基于uniapp以及微信小程序實現移動端人臉識別相似度對比,實現攝像頭、相冊權限獲取、相機模塊交互、第三方識別集成等功能,附完整代碼。 目錄 核心功能實現流程攝像頭與相冊權限申請權限拒絕后的引導策略攝像頭調用拍照事件處理人臉識別集成圖片預處理(Base64編碼/壓縮)調用…

OpenCV CUDA 模塊中用于在 GPU 上計算兩個數組對應元素差值的絕對值函數absdiff(

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 void cv::cuda::absdiff 是 OpenCV CUDA 模塊中的一個函數&#xff0c;用于在 GPU 上計算兩個數組對應元素差值的絕對值。 該函數會逐元素計算兩…

Rust 數據結構:HashMap

Rust 數據結構&#xff1a;HashMap Rust 數據結構&#xff1a;HashMap創建一個新的哈希映射HashMap::new()將元組變成哈希表 訪問哈希映射中的值哈希映射和所有權更新哈希映射重寫一個值僅當鍵不存在時才添加鍵和值基于舊值更新值 散列函數 Rust 數據結構&#xff1a;HashMap …

【從設置到上傳的全過程】本地多個hexo博客,怎么設置ssh才不會互相影響

偶然間&#xff0c;想多建一個博客&#xff0c;但電腦已經有一個博客了&#xff0c;怎么設置ssh才不會互相影響呢&#xff1f; 在 Windows 系統上設置多個 Hexo 博客的 SSH 配置&#xff0c;避免互相影響&#xff0c;通常戶就需要為每個博客配置不同的 SSH 密鑰&#xff0c;并…

【時時三省】(C語言基礎)字符數組應用舉例2

山不在高&#xff0c;有仙則名。水不在深&#xff0c;有龍則靈。 ----CSDN 時時三省 例題&#xff1a; 有3個字符串&#xff0c;要求找出其中“最大”者。 解題思路&#xff1a; 可以設一個二維的字符數組str&#xff0c;大小為320&#xff0c;即有3行20列&#xff08;每一…

2025認證杯挑戰賽第二階段B題【 謠言在社交網絡上的傳播 】原創論文講解(含完整python代碼)

大家好呀&#xff0c;從發布賽題一直到現在&#xff0c;總算完成了認證杯數學中國數學建模網絡挑戰賽第二階段B題目謠言在社交網絡上的傳播完整的成品論文。 本論文可以保證原創&#xff0c;保證高質量。絕不是隨便引用一大堆模型和代碼復制粘貼進來完全沒有應用糊弄人的垃圾半…

Qt功能區:Ribbon使用

Ribbon使用 1. Ribbon功能區介紹1.1 樣式 2. 基本功能區設置2.1 安裝動態庫&#xff08;推薦&#xff09;2.2 在MainWindow中使用Ribbon2.3 在QWidget中使用SARibbonBar2.4 創建Category和Pannel2.5 ContextCategory 上下文標簽創建 2.6 ApplicationButton2.7 QuickAccessBar和…

Ubnutu ADB 無法識別設備的解決方法

1. 正確安裝adb 下載地址 2. 檢查 Linux 是否識別設備 lsusb通過上述指令&#xff0c;分別查詢插入、斷開設備的usb設備表&#xff0c;如下所示&#xff1a; # 插入設備 adbc:~$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 011:…

C# 實現雪花算法(Snowflake Algorithm)詳解與應用

在現代分布式系統中&#xff0c;生成全局唯一的標識符&#xff08;ID&#xff09;是一個非常重要的問題。隨著微服務架構和分布式系統的普及&#xff0c;傳統的單機數據庫生成 ID 的方式已無法滿足高并發和高可用的需求。為了解決這個問題&#xff0c;Twitter 提出了 雪花算法&…

STM32+ESP8266連接onenet新平臺

若該文為原創文章&#xff0c;轉載請注明原文出處。 阿里云物聯網平臺無法開通了&#xff0c;所以嘗試使用onenet平臺。 一、硬件 1、STM32F103C8T6最?系統板 2、ESP-01S 3、DHT11 二、軟件 1、KEIL5.29 2、Token生成工具 3、app inventor 三、原理 四、平臺搭建 1、注…

深入解析Spring Boot與Redis集成:高效緩存實踐

深入解析Spring Boot與Redis集成&#xff1a;高效緩存實踐 引言 在現代Web應用開發中&#xff0c;緩存技術是提升系統性能的重要手段之一。Redis作為一種高性能的鍵值存儲數據庫&#xff0c;廣泛應用于緩存、會話管理和消息隊列等場景。本文將詳細介紹如何在Spring Boot項目中…

Python自學筆記3 常見運算符

常用運算符 加減法 python的自動數據類型轉換 整形轉為浮點型 實數轉為復數 數字類型不能和浮點數類型相加減 乘除法 數據轉換基本同加減法&#xff0c; 但字符串可以和整數相加減&#xff0c;作用是字符串的自我復制 反斜杠 成員運算符 判斷一個元素是不是一個序列的成員…

[特殊字符]接口測試用例設計指南:全面覆蓋與精準驗證

一、接口測試的核心價值 接口作為系統間通信的橋梁&#xff0c;其穩定性和準確性直接影響業務功能。通過科學設計的測試用例&#xff0c;可以提前暴露接口潛在缺陷&#xff0c;降低上下游系統的耦合風險。本文將系統講解接口測試的用例設計策略&#xff0c;覆蓋查詢類接口與操…